"use client"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, } from "recharts"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { Badge } from "@/components/ui/badge"; import { ResponsiveTable, ResponsiveTableCardList, ResponsiveTableCard, ResponsiveTableCardRow, } from "@/components/ui/responsive-table"; import { useCycleTime, useBottlenecks, useRework, useTeamScorecard, } from "@/hooks/use-observability"; import type { Scorecard } from "@/types"; const CELLS = ["backend", "frontend", "ux_ui"] as const; function label(status: string): string { return status .split("_") .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) .join(" "); } function fmtDuration(seconds: number): string { if (seconds >= 3600) return (seconds / 3600).toFixed(1) + "h"; if (seconds >= 60) return (seconds / 60).toFixed(0) + "m"; return seconds.toFixed(0) + "s"; } function pct(rate: number): string { return (rate * 100).toFixed(1) + "%"; } // ─── Cycle time ─────────────────────────────────────────────────────────────── function CycleTimeCard() { const { data, isLoading } = useCycleTime(30); const chartData = (data ?? []).map((s) => ({ name: label(s.status), Hours: Number((s.avg_seconds / 3600).toFixed(2)), })); return ( Cycle Time by Stage (avg, 30d) {isLoading ? ( ) : chartData.length === 0 ? (

No completed transitions in the window yet.

) : ( v + "h"} /> [value + "h", "Avg"]} contentStyle={{ fontSize: 12 }} /> )}
); } // ─── Bottlenecks ────────────────────────────────────────────────────────────── function BottlenecksCard() { const { data, isLoading } = useBottlenecks(30); return ( Bottlenecks {isLoading ? ( ) : ( <>
Worst stage: {data?.worst_stage ? ( {label(data.worst_stage)} ) : ( )} {data?.active_blockers ?? 0} active blockers
{(data?.by_stage ?? []).slice(0, 6).map((s) => (
{label(s.status)} {fmtDuration(s.cumulative_seconds)} · {s.parked_now}{" "} parked
))} {(data?.by_stage ?? []).length === 0 && (

No stage data yet.

)}
)} ); } // ─── Rework ─────────────────────────────────────────────────────────────────── function ReworkCard() { const { data, isLoading } = useRework(30); return ( Rework (30d) {isLoading ? ( ) : ( <>
{pct(data?.rate ?? 0)} {data?.total_reworked ?? 0}/{data?.total_completed ?? 0} bounced · ${(data?.rework_cost_usd ?? 0).toFixed(2)} cost
{(data?.by_team ?? []).map((t) => ( {label(t.team)} {pct(t.rate)} ))}
{(data?.by_agent ?? []).length > 0 && ( Agent Rate QA fails PR fails PM rejects CEO rejects {(data?.by_agent ?? []).slice(0, 8).map((a) => ( {a.agent_slug} {pct(a.rate)} {a.qa_fails} {a.pr_fails} {a.pm_rejects} {a.ceo_rejects} ))} } cards={ {(data?.by_agent ?? []).slice(0, 8).map((a) => ( {a.agent_slug}
{pct(a.rate)} {a.qa_fails} {a.pr_fails} {a.pm_rejects} {a.ceo_rejects}
))}
} /> )} )}
); } // ─── Per-cell scorecards ──────────────────────────────────────────────────────── function CellScorecard({ team }: { team: string }) { const { data, isLoading } = useTeamScorecard(team, 7); return ( {label(team)} (7d) {isLoading ? ( ) : ( )} ); } function ScorecardBody({ card }: { card: Scorecard | undefined }) { const stat = (k: string, v: string) => (
{k} {v}
); return (
{stat("Completed", String(card?.tasks_completed ?? 0))} {stat( "Avg cycle", card?.avg_cycle_hours != null ? card.avg_cycle_hours.toFixed(1) + "h" : "—", )} {stat("Rework", pct(card?.rework_rate ?? 0))} {stat("Cost", "$" + (card?.cost_usd ?? 0).toFixed(2))}
); } // ─── Tab ────────────────────────────────────────────────────────────────────── export function DeliveryTabContent() { return (
{CELLS.map((team) => ( ))}
); }