import { Link } from '@tanstack/react-router'; import { cn } from '@/lib/cn'; import { teamFlag } from '@/lib/teams'; import type { Fixture } from '@/lib/types'; import { kickoffTime, relativeKickoff } from '@/lib/format'; import { useTournamentStore } from '@/stores/tournamentStore'; import { TeamLabel } from './TeamLabel'; /** The model's pre-match lean for scheduled matches — the "expectation" hint. */ function ModelHint({ num }: { num: number }) { const pred = useTournamentStore((s) => s.model?.matches.find((m) => m.num === num)); if (!pred) return null; const { home, draw, away } = pred.probs; const drawLikely = draw >= home && draw >= away; const homeFav = home >= away; const side = drawLikely ? null : homeFav ? pred.home : pred.away; const p = drawLikely ? draw : Math.max(home, away); return (
model: {side ? <>{teamFlag(side)} {side} : 'draw '} {Math.round(p * 100)}%
); } const STAGE_LABEL: Record = { group: 'Group', r32: 'Round of 32', r16: 'Round of 16', qf: 'Quarter-final', sf: 'Semi-final', third: 'Third place', final: 'Final', }; function tag(f: Fixture): string { if (f.stage === 'group') return `Group ${f.group}`; return STAGE_LABEL[f.stage]; } function StatusPill({ f }: { f: Fixture }) { if (f.status === 'live') { return ( {f.minute ? `${f.minute}'` : 'Live'} ); } if (f.status === 'finished') { return FT; } return {relativeKickoff(f.kickoff)}; } export function MatchCard({ f }: { f: Fixture }) { const hasScore = f.status === 'live' || f.status === 'finished'; return (
{tag(f)}
{hasScore ? (
{f.homeScore ?? 0}{f.awayScore ?? 0}
) : (
{kickoffTime(f.kickoff)}
)}
{f.status === 'scheduled' && }
{f.venue}
); }