Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

07 — Component Library (Dashboard Module)

Module-specific widgets for the dashboard. Shared primitives live in 00-shared/03 (AppCard, AppSkeleton, AppEmptyState, AppErrorState, AppRefreshIndicator, AppOfflineBanner, AppSnackbar, AppBadge, AppChips, AppCharts, SegmentedButton family). Everything here composes those primitives; token names per 00-shared/02.


1. KpiCard

PurposeOne aggregate number with label and optional trend
Propslabel: String, value: String (pre-formatted), trend: TrendData? (delta, direction (planned)), onTap: VoidCallback?, status: KpiStatus (normal/zero/stale)
Bindingvalue from payload leaf (dashboard.service.ts:50-70); formatting at call site (NumberFormat, INR for totalDueAmount :68)
LayoutAppCard; value headlineMedium; label bodySmall onSurfaceVariant; TrendIndicator under value; optional trailing drill icon
Statesnormal; zero (value 0 → muted hint line, e.g. "Invite your first student"); loading (parent renders AppSkeleton instead — card never shows while loading); stale (StaleBanner owned by screen, card gets surfaceContainerLow tint)
A11ysemantics node: label, value value-first ("93 percent, Attendance"); button when onTap; 48 dp min
Motionpress Mo-m-fast ripple; value change AnimatedSwitcher 200 ms

2. TrendIndicator (planned)

PurposeΔ vs previous period
Propsdelta: double, `direction: up
RenderingbodySmall; ▲ +2 success / ▼ −1 error / neutral (00-shared/02 color roles); never rendered without server trend field (06_Screen_Specifications.md §1.2)
A11yglyph + hidden semantics "up 2 percent"; color never sole signal

3. ChartCard

PurposeTitle + chart + caption container
Propstitle, chart: Widget (via shared AppCharts), caption: String? (a11y text row), trailing: Widget? (e.g. PeriodSelector)
LayoutAppCard padded 16; title titleMedium; caption bodySmall onSurfaceVariant below chart
Emptydashed placeholder + "No data for this period" (AppEmptyState mini)
A11ycaption text row is the screen-reader alternative to the chart (00-shared/09)

4. PeriodSelector (planned)

PurposeToday / 7d / 30d segmented control
Propsvalue, onChanged, enabled
Behaviourdisabled + tooltip "Periods arrive with the server API" until `GET /dashboard/attendance
Stateselection lives in cubit (13_State_Management.md §3), triggers refetch

5. StaleBanner

PurposeSurface cache staleness honestly
Propsage: Duration, onRefresh: VoidCallback
RenderingAppBanner(info) "Showing data from X min ago" + Refresh text button; auto-hides after successful refetch
Rulesshown only when serving client-cached payload older than 60 s TTL (Dashboard.md:41); ≥10 min → treated as offline (06_Screen_Specifications.md §1.3)

6. WidgetPalette (planned)

PurposeCustomize grid: reorder + visibility + role chips
ComposReorderableListView of WidgetPaletteTile (drag handle, Switch, AppChips roles (planned)), save via AppButton
DataGET/PATCH /dashboard/widgets (planned) (Dashboard.md:26-27), persisted in dashboard_widgets (Dashboard.md:7)
A11yhandles Move semantics; switch labels per widget
Entry gateparent renders only with dashboard.widget.manage (permissions.constants.ts:38)

7. KpiRow

PurposeHorizontal-scrolling row of KpiCards (phone) / wrapped grid (tablet+ )
Behaviourscrollable with Scrollbar; shows 5 cards in service order (students → teachers → staff → attendance → finance, dashboard.service.ts:31-33,34,35-37)
Loading5 square AppSkeletons
A11yrow semantics combined list; no auto-scroll

Dependency map (module → shared)

KpiCardAppCard; ChartCardAppCard,AppCharts,AppEmptyState; StaleBannerAppBanner; WidgetPaletteAppChips,AppButton,AppSnackbar; all loading→AppSkeleton; refresh→AppRefreshIndicator; offline→AppOfflineBanner.

Design decisions (why)

  • No custom chart widget — shared AppCharts owns chart rendering (00-shared/03); module supplies data + caption only.
  • Trend is optional-by-default — payload has no trend field (dashboard.service.ts:50-70); components degrade to rather than inventing deltas.
  • Server-authoritative layout (planned) — widget order always from dashboard_widgets, never local state only.