import { useState } from 'react'; import type { PlayerInfo } from '../types'; import { computeTotal } from '../lib/standings'; interface Props { standings: number[][][]; /** Tips per series/round/seat, same shape as standings. */ guesses?: number[][][]; players: PlayerInfo[]; myOrder: number; /** Desktop renders an always-open sidebar; mobile a collapsible panel. */ desktop?: boolean; } export default function Standings({ standings, guesses = [], players, myOrder, desktop = false }: Props) { const [open, setOpen] = useState(false); // Player columns in seat order; the local player's column is highlighted. const cols = [...players].sort((a, b) => a.order - b.order); // Completed-round count before each series (running total), so each series' // round index can be offset in a single pass instead of re-summing per row. const seriesRoundOffsets: number[] = []; let completedRounds = 0; for (const s of standings) { seriesRoundOffsets.push(completedRounds); completedRounds += s.length; } // Engine: every series is exactly 8 rounds → a series with 8 entries is done, // and gets a per-series summary row after its last round. const ROUNDS_PER_SERIES = 8; // Bigger, more legible type on the wide desktop sidebar; compact on mobile. const fz = { head: desktop ? 11 : 10, idx: desktop ? 13 : 9, cell: desktop ? 19 : 14, dot: desktop ? 18 : 13, sigma: desktop ? 13 : 9, total: desktop ? 20 : 18, }; const table = (
{/* Column headers */}
{cols.map((p) => (
{p.name}
))}
{/* Completed rounds, grouped by series with a per-series summary row */} {standings.flatMap((seriesRounds, si) => { const priorRounds = seriesRoundOffsets[si]; const elems = seriesRounds.map((scores, lri) => (
{priorRounds + lri + 1}
{cols.map((p) => { const points = scores[p.order] ?? 0; // Failed tip (0 points) → show the struck-through tip instead of 0. if (points === 0) { return (
{guesses[si]?.[lri]?.[p.order] ?? 0}
); } return (
{points}
); })}
)); // After a finished series, sum its points per player. if (seriesRounds.length === ROUNDS_PER_SERIES) { elems.push(
Σ{si + 1}
{cols.map((p) => { const sum = seriesRounds.reduce((a, r) => a + (r[p.order] ?? 0), 0); return (
{sum}
); })}
, ); } return elems; })} {/* Active round placeholder */}
{completedRounds + 1}
{cols.map((p) => (
·
))}
{/* Totals */}
Σ
{cols.map((p) => (
{computeTotal(standings, p.order)}
))}
); if (desktop) { return ( ); } // Mobile: collapsible panel return (
{open && table}
); }