# 24. Dashboard — Unified Widgets for All Services meta: id: kordant-unified-restructure-24 feature: kordant-unified-restructure priority: P1 depends_on: [kordant-unified-restructure-23] tags: [frontend, dashboard, widgets, solidjs] objective: - Build rich, interactive dashboard widgets that give users a unified view of their security posture across all Kordant services. Replace placeholder stat cards with real, actionable widgets. deliverables: - `web/src/components/dashboard/ThreatScoreWidget.tsx` — Circular gauge showing overall threat score (0-100): - Color-coded: green (0-30), amber (31-70), red (71-100) - Trend indicator (up/down vs last week) - Click to view detailed breakdown - `web/src/components/dashboard/AlertFeedWidget.tsx` — Real-time alert stream: - List of latest 5-10 alerts with severity icons - Grouped by correlation group - "Mark as read" and "View details" actions - "View all" link to alerts page - `web/src/components/dashboard/ExposureWidget.tsx` — DarkWatch summary: - Count of exposures by severity - Latest exposure with source and date - "Run scan" button - Link to full DarkWatch page - `web/src/components/dashboard/VoicePrintWidget.tsx` — VoicePrint summary: - Enrollment count - Recent analyses count - Synthetic detection rate - "Analyze audio" button - `web/src/components/dashboard/SpamShieldWidget.tsx` — SpamShield summary: - Blocked calls/SMS count (today/this week) - Top spam sources - Custom rules count - "View rules" link - `web/src/components/dashboard/HomeTitleWidget.tsx` — HomeTitle summary: - Watched properties count - Recent changes count - Latest change with severity - "View properties" link - `web/src/components/dashboard/RemoveBrokersWidget.tsx` — RemoveBrokers summary: - Total brokers in registry - Pending/completed removals count - Progress bar for overall removal completion - "Manage removals" link - `web/src/components/dashboard/QuickActionsWidget.tsx` — Shortcut buttons: - "Add to watchlist", "Upload voice sample", "Check number", "Add property", "Start removal" - `web/src/routes/(webapp)/dashboard.tsx` — Updated dashboard layout: - Grid layout: 2 columns on desktop, 1 on mobile - Widgets arranged by priority (threat score top-left, quick actions top-right) - Auto-refresh every 60 seconds steps: 1. Create `web/src/components/dashboard/` directory. 2. **ThreatScoreWidget**: - Use SVG for circular gauge with stroke-dasharray animation - Query `api.correlation.getStats` for score and trend - Color transitions based on score value 3. **AlertFeedWidget**: - Query `api.correlation.getAlerts` with `limit: 10` - Each item: severity icon (shield with color), title, time ago, source badge - Use `Card` primitive with compact padding - "Mark as read" calls `api.correlation.resolveAlert` 4. **ExposureWidget**: - Query `api.darkwatch.getExposures` with `limit: 1` for latest - Show severity breakdown as small horizontal bars - "Run scan" button triggers `api.darkwatch.runScan` mutation 5. **VoicePrintWidget**: - Query `api.voiceprint.getEnrollments` and `api.voiceprint.getAnalyses` - Show counts and a mini bar chart of recent analyses 6. **SpamShieldWidget**: - Query `api.spamshield.getStats` - Show blocked count with trend - List top 3 spam sources as small rows 7. **HomeTitleWidget**: - Query `api.hometitle.getProperties` and `api.hometitle.getChanges` - Show property count and latest change 8. **RemoveBrokersWidget**: - Query `api.removebrokers.getRemovalRequests` and `api.removebrokers.getBrokerRegistry` - Calculate completion percentage - Show progress bar using theme colors 9. **QuickActionsWidget**: - Grid of icon buttons linking to service pages or opening modals - Each button uses `Button` primitive with icon 10. Update dashboard route: - Compose all widgets in responsive grid - Add `createInterval` or `setInterval` for auto-refresh - Handle loading states with skeleton cards steps: - Unit: Each widget renders correctly with mock data - Unit: ThreatScoreWidget displays correct color for score ranges - Unit: AlertFeedWidget calls mark-read mutation on click - Visual: Dashboard grid is responsive and widgets align correctly - E2E: Dashboard loads with real data and auto-refreshes acceptance_criteria: - [ ] Dashboard displays 8 widgets in a responsive grid layout - [ ] Threat score gauge animates on load and updates with real data - [ ] Alert feed shows latest alerts with correct severity colors - [ ] Each service widget summarizes the most important metrics - [ ] Quick actions provide one-click access to common tasks - [ ] Dashboard auto-refreshes every 60 seconds - [ ] Loading states show skeleton cards while data fetches - [ ] All widgets use theme tokens and shift correctly in dark mode validation: - Open `/dashboard` and verify all widgets render with real data - Resize browser to mobile width and verify single-column layout - Wait 60 seconds and verify auto-refresh updates data - Click "Mark as read" on an alert and verify it disappears from feed - Run `cd web && pnpm test` for widget unit tests notes: - Keep widgets focused on summary data. Deep interactions belong on service-specific pages. - The threat score gauge is the visual centerpiece. Invest in making it polished and informative. - Consider adding a "Security Tip of the Day" widget that rotates educational content. - Widgets should be collapsible or reorderable in a future enhancement. Design them as self-contained units. - Use `Suspense` boundaries around widget groups to prevent the entire dashboard from blocking on one slow API call.