"use client"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { TrendingUp, CheckCircle, BarChart3, AlertTriangle } from "lucide-react"; interface KeyMetricsProps { metrics: Record | undefined; isLoading: boolean; } interface MetricItem { key: string; label: string; icon: React.ReactNode; format?: (value: number) => string; } // Keys must match DashboardService.get_key_metrics() — the shape /dashboard/ceo // returns. (velocity_weekly + completion_rate + documentation_coverage are the // 7-day rollups; active_blockers is the live blocked-task count.) const METRIC_CONFIG: MetricItem[] = [ { key: "velocity_weekly", label: "Velocity (7d)", icon: , format: (v) => `${v} tasks`, }, { key: "completion_rate", label: "Completion Rate", icon: , format: (v) => `${Math.round(v * 100)}%`, }, { key: "documentation_coverage", label: "Documentation Coverage", icon: , format: (v) => `${Math.round(v * 100)}%`, }, { key: "active_blockers", label: "Active Blockers", icon: , format: (v) => `${v}`, }, ]; export function KeyMetricsPanel({ metrics, isLoading }: KeyMetricsProps) { return ( Key Metrics {isLoading ? (
{METRIC_CONFIG.map((m) => ( ))}
) : (
{METRIC_CONFIG.map((m) => { const rawValue = metrics?.[m.key]; const value = typeof rawValue === "number" ? rawValue : null; return (
{m.icon} {m.label}
{value != null ? m.format ? m.format(value) : value : "-"}
); })}
)}
); }