/** Server-computed statistics rendered as lean cards and CSS bars. */ import { useEffect, useState } from "preact/hooks"; import { getStats, type StatRow, type StatsData } from "../api"; const pct = (n = 0) => `${Math.round(n * 100)}%`; function Rows({ title, rows, metric }: { title: string; rows: StatRow[]; metric: "p_helped" | "p_failed" }) { return ( {title} {!rows.length ? No qualifying data. : rows.map((row) => { const value = row[metric] || 0; return {row.key}n={row.n} · {pct(value)}; })} ); } export function Stats() { const [data, setData] = useState(null); useEffect(() => { getStats().then(setData).catch(() => {}); }, []); if (!data) return Loading…; const outcomes = Object.entries(data.outcomes); const dailyRows: StatRow[] = [ { key: "Brick done", n: 0, p_helped: data.daily.p_brick_done }, { key: "Corn okay", n: 0, p_helped: data.daily.p_corn_ok }, { key: "No FC", n: 0, p_helped: data.daily.p_no_fc }, { key: "Clean rerun", n: 0, p_helped: data.daily.p_rerun_clean }, { key: "Court closed", n: 0, p_helped: data.daily.p_court_closed }, ]; return ( Stats Outcomes{outcomes.map(([key, count]) => {count}{key})}{data.n_entries_scored} scored · {data.n_entries_total} total Average daily points{data.daily.avg_points.toFixed(1)}/6 ); }
No qualifying data.
{data.n_entries_scored} scored · {data.n_entries_total} total