Give every team member the same box layout, even with no data yet

Peter, Daniel, Niklas, and Aleksandra were showing a single plain text
alert while Mckinley got the full stat-tile/chart/table layout - now
everyone gets the same boxes (stat tiles, chart cards, posts table,
demographics cards), just with "No data yet" placeholders where a
person hasn't submitted an export. Keeps the tab visually consistent
across all five regardless of who has data yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
beantownbabeandClaude Sonnet 5 committed 2026-10-30 10:54:23 +01:00
1 parent db4587f75e
commit 514e21952d
1 file changed
+44 -9
+44 -9
View File
@@ -2779,24 +2779,59 @@ def _build_person_dashboard(name, data):
return html.Div([stat_row, source_note, charts_row, posts_row, demo_row])
_TEAM_EMPTY_PLACEHOLDER = html.Div("No data yet", className="text-muted text-center",
style={"padding": "2rem 0"})
def _build_empty_person_dashboard(name):
"""Same box layout as _build_person_dashboard (stat tiles, chart cards, posts
table, demographics cards) so every team member's tab looks consistent before
their first export lands, instead of a lone text alert - each box just shows a
"No data yet" placeholder in place of real content."""
stat_row = dbc.Row([
_team_stat_tile("—", "Impressions"),
_team_stat_tile("—", "Members Reached"),
_team_stat_tile("—", "Total Followers"),
_team_stat_tile("—", "Engagements"),
], className="gx-3 mb-3")
source_note = dbc.Alert(
f"No personal LinkedIn export data for {name} yet. Drop their "
f"\"AggregateAnalytics_{name}_...\" export into the project folder and it will "
"fill in these boxes automatically on the next refresh - no code change needed.",
color="info", style={"marginBottom": "0.75rem"})
charts_row = dbc.Row([
dbc.Col(section("Daily Impressions & Engagements", _TEAM_EMPTY_PLACEHOLDER), md=6),
dbc.Col(section("Daily New Followers", _TEAM_EMPTY_PLACEHOLDER), md=6),
], className="gx-3 mb-3")
posts_row = dbc.Row([
dbc.Col(section("Posts This Window — Originals vs Reposts", _TEAM_EMPTY_PLACEHOLDER), md=12),
], className="gx-3 mb-3")
demo_row = dbc.Row([
dbc.Col(section("Audience Demographics (who sees it)", _TEAM_EMPTY_PLACEHOLDER), md=6),
dbc.Col(section("Content Demographics (who engages)", _TEAM_EMPTY_PLACEHOLDER), md=6),
], className="gx-3")
return html.Div([stat_row, source_note, charts_row, posts_row, demo_row])
@app.callback(
Output("team-content-area", "children"),
Input("team-member-select", "value"),
)
def _render_team_tab(name):
"""Mckinley's own export landed 2026-10-30 (see team_exports.py); Aleksandra,
Daniel, Niklas, and Peter are still pending their first Monday submission.
Shows the same clean "nothing yet" treatment as the Engagement Response tab
until a given person's first export lands - no code change needed when it does,
Daniel, Niklas, and Peter are still pending their first Monday submission - they
get the same box layout via _build_empty_person_dashboard rather than a lone
text alert, so the tab looks consistent across all five people before and after
data lands. No code change needed when a person's first export arrives -
team_exports.load_person_data() picks it up automatically by filename."""
data = team_exports.load_person_data(name, DATA_DIR, UPLOAD_DIR)
if not data:
return dbc.Alert(
f"No personal LinkedIn export data for {name} yet. Drop their "
f"\"AggregateAnalytics_{name}_...\" export into the project folder and it will "
"show up here automatically on the next refresh - no code change needed.",
color="info",
)
return _build_empty_person_dashboard(name)
return _build_person_dashboard(name, data)