diff --git a/src/components/AdminSidebar.tsx b/src/components/AdminSidebar.tsx index 8a8e340..f0c4540 100644 --- a/src/components/AdminSidebar.tsx +++ b/src/components/AdminSidebar.tsx @@ -247,6 +247,12 @@ const GROUPS: NavItem[][] = [ icon: CreditCard, moduleKeys: ["CREDIT_MANAGEMENT", "CREDITS"], }, + { + href: "/admin/ai-management", + label: "AI Management", + icon: Sparkles, + moduleKeys: ["AI_MANAGEMENT", "AI"], + }, { href: "/admin/coupon", label: "Coupon Management", diff --git a/src/lib/admin/dashboard.ts b/src/lib/admin/dashboard.ts index 1f3462e..7321a27 100644 --- a/src/lib/admin/dashboard.ts +++ b/src/lib/admin/dashboard.ts @@ -95,6 +95,62 @@ const adapterMap: Record Promise ({ state: 'success', payload: { kind: 'kpi', data: kpiData.creditsPurchased } }), chart_leads_trend: async () => ({ state: 'success', payload: { kind: 'line_chart', data: lineChartData } }), chart_revenue_overview: async () => ({ state: 'success', payload: { kind: 'bar_chart', data: barChartData } }), + kpi_ai_users: async () => { + try { + const token = typeof sessionStorage !== 'undefined' + ? sessionStorage.getItem('nxtgauge_admin_access_token') || '' + : ''; + const res = await fetch('/api/admin/ai/stats', { + headers: { Authorization: `Bearer ${token}` }, + credentials: 'include', + }); + if (!res.ok) throw new Error('Failed'); + const data = await res.json(); + return { + state: 'success', + payload: { + kind: 'kpi', + data: { + value: String(data.total_users_with_ai ?? 0), + delta: '', + note: `${data.total_generations_today ?? 0} today`, + tone: 'up' as const, + icon: 'users' as const, + }, + }, + }; + } catch { + return { state: 'error', message: 'Failed to load AI stats' }; + } + }, + kpi_ai_generations_today: async () => { + try { + const token = typeof sessionStorage !== 'undefined' + ? sessionStorage.getItem('nxtgauge_admin_access_token') || '' + : ''; + const res = await fetch('/api/admin/ai/stats', { + headers: { Authorization: `Bearer ${token}` }, + credentials: 'include', + }); + if (!res.ok) throw new Error('Failed'); + const data = await res.json(); + return { + state: 'success', + payload: { + kind: 'kpi', + data: { + value: String(data.total_generations_today ?? 0), + delta: '', + note: `${data.total_generations_month ?? 0} this month`, + tone: 'up' as const, + icon: 'trend' as const, + }, + }, + }; + } catch { + return { state: 'error', message: 'Failed to load AI usage' }; + } + }, }; export const ADMIN_DASHBOARD_WIDGETS: DashboardWidgetDefinition[] = [ @@ -180,6 +236,28 @@ export const ADMIN_DASHBOARD_WIDGETS: DashboardWidgetDefinition[] = [ readiness: 'ready', description: 'Weekly revenue overview', }, + { + widgetKey: 'kpi_ai_users', + title: 'AI Users', + moduleKey: 'AI_MANAGEMENT', + defaultSize: 'S', + defaultVisible: true, + order: 9, + dataAdapterKey: 'kpi_ai_users', + readiness: 'ready', + description: 'Total users with active AI plans', + }, + { + widgetKey: 'kpi_ai_generations_today', + title: 'AI Generations Today', + moduleKey: 'AI_MANAGEMENT', + defaultSize: 'S', + defaultVisible: true, + order: 10, + dataAdapterKey: 'kpi_ai_generations_today', + readiness: 'ready', + description: 'AI generations used today', + }, ]; export function loadWidgetData(definition: DashboardWidgetDefinition): Promise> {