diff --git a/app/(app)/insights/components/plan-quality.tsx b/app/(app)/insights/components/plan-quality.tsx new file mode 100644 index 0000000..2a592b4 --- /dev/null +++ b/app/(app)/insights/components/plan-quality.tsx @@ -0,0 +1,105 @@ +'use client' + +import Link from 'next/link' +import { PieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer } from 'recharts' +import type { VerifyResultStats, VerifyResultKey, TopJob } from '@/lib/insights/verify-stats' + +interface Props { + stats: VerifyResultStats +} + +const VERIFY_COLORS: Record = { + ALIGNED: 'var(--status-done)', + PARTIAL: 'var(--priority-medium)', + EMPTY: 'var(--priority-critical)', + DIVERGENT: 'var(--priority-high)', +} + +const VERIFY_LABELS: Record = { + ALIGNED: 'Aligned', + PARTIAL: 'Partial', + EMPTY: 'Empty', + DIVERGENT: 'Divergent', +} + +function daysAgo(date: Date, nowMs: number): string { + const diff = Math.floor((nowMs - new Date(date).getTime()) / 86_400_000) + return diff === 0 ? 'vandaag' : `${diff}d geleden` +} + +function TopTable({ title, jobs, nowMs }: { title: string; jobs: TopJob[]; nowMs: number }) { + if (jobs.length === 0) return null + return ( +
+

{title}

+ + + {jobs.map(j => ( + + + + + + ))} + +
+ + {j.taskTitle} + + {j.productName}{daysAgo(j.finishedAt, nowMs)}
+
+ ) +} + +export function PlanQualityCard({ stats, nowMs }: Props & { nowMs: number }) { + if (stats.counts.length === 0) { + return ( +
+

+ Plan-verify gating moet eerst geactiveerd worden.{' '} + + Bekijk de Plan-verify gating story + +

+
+ ) + } + + const labeled = stats.counts.map(c => ({ + ...c, + name: VERIFY_LABELS[c.result], + })) + + return ( +
+ + + + {labeled.map(entry => ( + + ))} + + + + + + +
+ + +
+
+ ) +}