AdminAnalytics/src/admin_analytics/dashboard/app.py
emfurst eb489a782d Make dashboard usable on mobile
Move inline styles into assets/style.css with wrapping KPI and chart rows,
a horizontally scrolling tab bar, and phone breakpoints. Shared components
put chart titles in HTML headings, legends above plots, and disable
drag-to-zoom so swiping scrolls the page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X9jG4CUFcH6n4vFvgtwndY
2026-10-17 11:10:56 -04:00

63 lines
2.2 KiB
Python

"""Dash application factory."""
import dash
from dash import dcc, html, Input, Output
from admin_analytics.db.connection import get_connection
from admin_analytics.dashboard.pages import (
overview, compensation, staffing, headcount, endowment, philanthropy, about,
)
def create_app() -> dash.Dash:
"""Create and configure the Dash application."""
app = dash.Dash(__name__, suppress_callback_exceptions=True)
conn = get_connection(read_only=True)
app.layout = html.Div(
[
html.H1(
"University of Delaware — Administrative Analytics",
className="app-title",
),
dcc.Tabs(
id="tabs",
value="compensation",
children=[
dcc.Tab(label="Executive Compensation", value="compensation"),
dcc.Tab(label="Admin Cost Overview", value="overview"),
dcc.Tab(label="Staffing & Enrollment", value="staffing"),
dcc.Tab(label="Endowment", value="endowment"),
dcc.Tab(label="Philanthropy", value="philanthropy"),
dcc.Tab(label="Current Headcount", value="headcount"),
dcc.Tab(label="About", value="about"),
],
className="tabs-bar",
mobile_breakpoint=0,
),
html.Div(id="tab-content", className="tab-content"),
],
className="app",
)
@app.callback(Output("tab-content", "children"), Input("tabs", "value"))
def render_tab(tab: str):
if tab == "overview":
return overview.layout(conn)
elif tab == "compensation":
return compensation.layout(conn)
elif tab == "staffing":
return staffing.layout(conn)
elif tab == "endowment":
return endowment.layout(conn)
elif tab == "philanthropy":
return philanthropy.layout(conn)
elif tab == "headcount":
return headcount.layout(conn)
elif tab == "about":
return about.layout()
return html.Div("Unknown tab")
compensation.register_callbacks(app, conn)
return app