'use client'; import { useQuery } from '@tanstack/react-query'; import { apiFetch } from '@/lib/api/client'; import { KPITile } from '@/components/ui/kpi-tile'; import { Skeleton } from '@/components/ui/skeleton'; import { WidgetErrorBoundary } from './widget-error-boundary'; interface KpiData { totalClients: number; activeInterests: number; pipelineValueUsd: number; occupancyRate: number; } function formatCurrency(value: number): string { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0, }).format(value); } function formatPercent(value: number): string { return `${value.toFixed(1)}%`; } function KpiTileSkeleton() { return (
); } export function KpiCards() { const { data, isLoading, isError } = useQuery({ queryKey: ['dashboard', 'kpis'], queryFn: () => apiFetch('/api/v1/dashboard/kpis'), staleTime: 60_000, retry: 2, }); if (isLoading) { return ( <> ); } const kpis: Array<{ label: string; value: string; accent: 'brand' | 'success' | 'warning' | 'mint' | 'teal' | 'purple'; }> = [ { label: 'Total Clients', value: isError ? '—' : String(data?.totalClients ?? 0), accent: 'brand', }, { label: 'Active Interests', value: isError ? '—' : String(data?.activeInterests ?? 0), accent: 'teal', }, { label: 'Pipeline Value', value: isError ? '—' : formatCurrency(data?.pipelineValueUsd ?? 0), accent: 'success', }, { label: 'Occupancy Rate', value: isError ? '—' : formatPercent(data?.occupancyRate ?? 0), accent: 'purple', }, ]; return ( <> {kpis.map(({ label, value, accent }) => ( ))} ); } export function KpiCardsWithBoundary() { return ( ); }