From 0a0c51adc1040143b5dbca2cac61803d14765108 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Mon, 6 Apr 2026 06:19:14 +0200 Subject: [PATCH] feat: wire admin dashboard to real metrics and fix JSX errors - Wire dashboard home to live /api/admin/dashboard/metrics with 8 KPI widgets - Add pending_approvals and total_revenue widget definitions - Fix JSX syntax errors in [...module].tsx and modules.tsx - Fix '>' character in DashboardDesignPreview.tsx --- .../admin/DashboardDesignPreview.tsx | 2 +- src/lib/admin/dashboard.ts | 34 ++++++++--- src/routes/admin/[...module].tsx | 2 + src/routes/admin/index.tsx | 56 +++++++++++++------ src/routes/admin/modules.tsx | 2 + 5 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/components/admin/DashboardDesignPreview.tsx b/src/components/admin/DashboardDesignPreview.tsx index e8a981c..af253f3 100644 --- a/src/components/admin/DashboardDesignPreview.tsx +++ b/src/components/admin/DashboardDesignPreview.tsx @@ -4094,7 +4094,7 @@ export default function DashboardDesignPreview(props: {
-

Requirements > Details

+

Requirements {'>'} Details

{selectedRow.title}

{status.label} diff --git a/src/lib/admin/dashboard.ts b/src/lib/admin/dashboard.ts index 0e5badf..1f3462e 100644 --- a/src/lib/admin/dashboard.ts +++ b/src/lib/admin/dashboard.ts @@ -128,13 +128,33 @@ export const ADMIN_DASHBOARD_WIDGETS: DashboardWidgetDefinition[] = [ dataAdapterKey: 'kpi_open_leads', readiness: 'ready', }, + { + widgetKey: 'kpi_pending_approvals', + title: 'Pending Approvals', + moduleKey: 'APPROVAL_MANAGEMENT', + defaultSize: 'S', + defaultVisible: true, + order: 4, + dataAdapterKey: 'kpi_pending_approvals', + readiness: 'ready', + }, + { + widgetKey: 'kpi_total_revenue', + title: 'Total Revenue', + moduleKey: 'REVENUE_LEDGER', + defaultSize: 'S', + defaultVisible: true, + order: 5, + dataAdapterKey: 'kpi_total_revenue', + readiness: 'ready', + }, { widgetKey: 'kpi_credits_purchased', title: 'Credits Purchased', moduleKey: 'CREDIT_MANAGEMENT', defaultSize: 'S', defaultVisible: true, - order: 4, + order: 6, dataAdapterKey: 'kpi_credits_purchased', readiness: 'ready', }, @@ -144,10 +164,10 @@ export const ADMIN_DASHBOARD_WIDGETS: DashboardWidgetDefinition[] = [ moduleKey: 'REPORTS', defaultSize: 'M', defaultVisible: true, - order: 5, + order: 7, dataAdapterKey: 'chart_leads_trend', - readiness: 'planned', - description: 'Monthly leads performance overview', + readiness: 'ready', + description: 'Weekly leads performance overview', }, { widgetKey: 'chart_revenue_overview', @@ -155,10 +175,10 @@ export const ADMIN_DASHBOARD_WIDGETS: DashboardWidgetDefinition[] = [ moduleKey: 'REVENUE_LEDGER', defaultSize: 'M', defaultVisible: true, - order: 6, + order: 8, dataAdapterKey: 'chart_revenue_overview', - readiness: 'planned', - description: 'Monthly revenue vs expenses comparison', + readiness: 'ready', + description: 'Weekly revenue overview', }, ]; diff --git a/src/routes/admin/[...module].tsx b/src/routes/admin/[...module].tsx index 2fc2558..a63cb11 100644 --- a/src/routes/admin/[...module].tsx +++ b/src/routes/admin/[...module].tsx @@ -55,6 +55,7 @@ export default function LegacyModuleShellPage() { const legacyUrl = createMemo(() => `${LEGACY_ADMIN_ORIGIN}${legacyPath()}`); return ( +

{moduleName()}

Live legacy module embedded for exact design and functionality parity during migration. @@ -69,5 +70,6 @@ export default function LegacyModuleShellPage() { style={{ width: '100%', height: '72vh', border: '1px solid #e2e8f0', 'border-radius': '10px', 'margin-top': '10px' }} /> +

); } diff --git a/src/routes/admin/index.tsx b/src/routes/admin/index.tsx index 337b3a4..88c7a69 100644 --- a/src/routes/admin/index.tsx +++ b/src/routes/admin/index.tsx @@ -70,25 +70,34 @@ const DEFAULT_LAYOUT: RuntimeDashboardLayout = { const WIDGET_META: Record = { kpi_total_users: { - state: 'empty', + state: 'live', type: 'summary', - statusLabel: 'No Data', + statusLabel: 'Live Data', subtitle: 'Powered by USER_MANAGEMENT', - emptyMessage: 'No user data available yet', }, kpi_active_companies: { - state: 'empty', + state: 'live', type: 'summary', - statusLabel: 'No Data', + statusLabel: 'Live Data', subtitle: 'Powered by COMPANY_MANAGEMENT', - emptyMessage: 'No company data available yet', }, kpi_open_leads: { - state: 'empty', + state: 'live', type: 'summary', - statusLabel: 'No Data', + statusLabel: 'Live Data', subtitle: 'Powered by REQUIREMENTS_MANAGEMENT', - emptyMessage: 'No lead data available yet', + }, + kpi_pending_approvals: { + state: 'live', + type: 'summary', + statusLabel: 'Live Data', + subtitle: 'Powered by APPROVAL_MANAGEMENT', + }, + kpi_total_revenue: { + state: 'live', + type: 'summary', + statusLabel: 'Live Data', + subtitle: 'Powered by REVENUE_LEDGER', }, kpi_credits_purchased: { state: 'empty', @@ -98,18 +107,16 @@ const WIDGET_META: Record = { emptyMessage: 'No credit activity available yet', }, chart_leads_trend: { - state: 'pending', + state: 'live', type: 'analytics', - statusLabel: 'Module Pending', - subtitle: 'Monthly leads performance overview • Powered by REPORTS', - pendingMessage: 'This widget will connect to live reporting data once the Reports module is completed', + statusLabel: 'Live Data', + subtitle: 'Weekly leads performance overview • Powered by REPORTS', }, chart_revenue_overview: { - state: 'pending', + state: 'live', type: 'analytics', - statusLabel: 'Module Pending', - subtitle: 'Monthly revenue vs expenses comparison • Powered by REVENUE_LEDGER', - pendingMessage: 'This widget will connect to ledger-based analytics once the Revenue Ledger module is completed', + statusLabel: 'Live Data', + subtitle: 'Weekly revenue overview • Powered by REVENUE_LEDGER', }, }; @@ -172,6 +179,7 @@ function iconForWidget(widgetKey: string) { if (widgetKey.includes('leads')) return ; if (widgetKey.includes('credits')) return ; if (widgetKey.includes('revenue')) return ; + if (widgetKey.includes('approvals')) return ; return ; } @@ -242,6 +250,8 @@ export default function AdminHomePage() { kpi_total_users: 'users', kpi_active_companies: 'companies', kpi_open_leads: 'leads', + kpi_pending_approvals: 'approvals', + kpi_total_revenue: 'revenue', kpi_credits_purchased: 'credits', }; if (metrics.loading) return { state: 'pending', statusLabel: 'Loading...' }; @@ -249,6 +259,18 @@ export default function AdminHomePage() { if (m) return { state: 'live', statusLabel: 'Live Data', data: m }; return { state: 'empty', statusLabel: 'No Data' }; } + if (metrics.loading) return { state: 'pending', statusLabel: 'Loading...' }; + const m = metrics(); + if (key === 'chart_leads_trend') { + const data = m?.trend_series; + if (data && data.length > 0) return { state: 'live', statusLabel: 'Live Data', data: { trend_series: data } }; + return { state: 'empty', statusLabel: 'No Data' }; + } + if (key === 'chart_revenue_overview') { + const data = m?.rev_series; + if (data && data.length > 0) return { state: 'live', statusLabel: 'Live Data', data: { rev_series: data } }; + return { state: 'empty', statusLabel: 'No Data' }; + } const meta = WIDGET_META[key]; return { state: meta?.state || 'empty', statusLabel: meta?.statusLabel || 'No Data' }; }; diff --git a/src/routes/admin/modules.tsx b/src/routes/admin/modules.tsx index bbb0c3f..90dbd25 100644 --- a/src/routes/admin/modules.tsx +++ b/src/routes/admin/modules.tsx @@ -105,6 +105,7 @@ export default function ModulesPage() { } return ( + <>
{/* ── Page header ── */} @@ -255,5 +256,6 @@ export default function ModulesPage() {
+ ); }