import { useQuery } from '@tanstack/react-query' import { RadarChart, Radar, PolarGrid, PolarAngleAxis, ResponsiveContainer, Tooltip, } from 'recharts' import { apiFetch } from '@/lib/http' import { LoadingSkeleton } from '@/components/common/LoadingSkeleton' import { cn } from '@/lib/utils' interface DomainScore { domain: string coverage: number freshness: number | null accuracy: number | null score: number } interface HealthResponse { overall_score: number domains: DomainScore[] } async function fetchHealth(): Promise { const res = await apiFetch('/api/analytics/knowledge-health') return res.json() } function ScoreBadge({ value }: { value: number }) { const pct = Math.round(value * 100) const colour = pct >= 80 ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400' : pct >= 60 ? 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400' : 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400' return ( {pct}% ) } function HeatCell({ value }: { value: number | null }) { if (value === null) { return (
N/A
) } const pct = Math.round(value * 100) const bg = pct >= 80 ? 'bg-green-500' : pct >= 60 ? 'bg-amber-400' : pct >= 40 ? 'bg-orange-400' : 'bg-red-500' return (
{pct}%
) } export function KnowledgeHealthDashboard() { const { data, isLoading } = useQuery({ queryKey: ['analytics-knowledge-health'], queryFn: fetchHealth, staleTime: 300_000, }) const overall = data ? Math.round(data.overall_score * 100) : 0 const radarData = data?.domains.map((d) => ({ domain: d.domain, Coverage: Math.round(d.coverage * 100), Freshness: d.freshness !== null ? Math.round(d.freshness * 100) : 0, Accuracy: d.accuracy !== null ? Math.round(d.accuracy * 100) : 0, })) ?? [] return (
{/* Overall score */}

Overall Knowledge Health

{isLoading ? (
) : (

= 80 ? 'text-green-600' : overall >= 60 ? 'text-amber-500' : 'text-red-500', )}> {overall}%

)}
{!isLoading && (

{data?.domains.length ?? 0} domains tracked

)}
{/* Radar chart */}

Coverage / Freshness / Accuracy

{isLoading ? ( ) : ( )}
{/* Heatmap table */}

Domain Breakdown

{isLoading ? ( ) : (
{(data?.domains ?? []).map((d) => ( ))}
Domain Coverage Freshness Accuracy Score
{d.domain}
)}
) }