Tournament stats hub, suspension tracker, card-aware live probabilities
- /stats: FotMob tournament boards (goals/assists/rating/xG player+team categories from the data.fotmob.com CDN, capture-first via scheduler), Golden Boot race with DraftKings anytime-line benchmark from the already-captured scorer props, and an attack-vs-defence xG scatter. - Discipline engine (src/lib/discipline.ts): FIFA suspension rules folded from stored event feeds — red/second-yellow bans, two-yellow accumulation, post-QF wipe. Surfaces on /stats, team profiles and match lineups tabs. - In-play win probability now accounts for red cards (10 men: own rate x0.67, opponent x1.15 per card) on the server tick and the match page. - Fix ModelDiary infinite render loop (unstable zustand snapshot while the model loads crashed the Methodology route under React 19). - Drop dead tables squad + goalscorers; scorer_props is now read. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -180,23 +180,51 @@ export function TeamProfilePage() {
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader><span className="font-display font-bold text-ink">{t.team.allTimeTopScorers}</span></CardHeader>
|
||||
<CardBody>
|
||||
{profile.keyPlayers.length ? (
|
||||
<ol className="space-y-1.5">
|
||||
{profile.keyPlayers.map((p, i) => (
|
||||
<li key={p.name} className="flex items-center gap-2 text-sm">
|
||||
<span className="w-4 text-right text-xs font-bold text-faint">{i + 1}</span>
|
||||
<span className="truncate text-ink-soft">{p.name}</span>
|
||||
<span className="tnum ml-auto font-semibold text-ink">{p.goals}</span>
|
||||
{p.pens ? <span className="text-[11px] text-faint">{fmt(t.common.pensShort, { n: p.pens })}</span> : null}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
) : <p className="text-sm text-faint">{t.common.noData}</p>}
|
||||
</CardBody>
|
||||
</Card>
|
||||
<div className="space-y-5">
|
||||
{profile.discipline.length > 0 && (
|
||||
<Card>
|
||||
<CardHeader><span className="font-display font-bold text-ink">{t.team.discipline}</span></CardHeader>
|
||||
<CardBody>
|
||||
<ul className="space-y-1.5">
|
||||
{profile.discipline.map((p) => (
|
||||
<li key={p.player} className="flex flex-wrap items-center gap-2 text-sm">
|
||||
<span className="truncate text-ink-soft">{p.player}</span>
|
||||
<span className="flex items-center gap-0.5" aria-hidden>
|
||||
{Array.from({ length: p.yellows }).map((_, i) => <span key={`y${i}`} className="inline-block h-3.5 w-2.5 rounded-[2px] bg-gold" />)}
|
||||
{Array.from({ length: p.reds }).map((_, i) => <span key={`r${i}`} className="inline-block h-3.5 w-2.5 rounded-[2px] bg-loss" />)}
|
||||
</span>
|
||||
{p.suspendedNext && (
|
||||
<span className="ml-auto rounded-full bg-loss/15 px-2 py-0.5 text-[11px] font-semibold text-loss">
|
||||
{p.suspendedFor != null ? fmt(t.team.suspChipFor, { num: p.suspendedFor }) : t.team.suspChipNext}
|
||||
</span>
|
||||
)}
|
||||
{!p.suspendedNext && p.pending === 1 && (
|
||||
<span className="ml-auto rounded-full bg-gold/15 px-2 py-0.5 text-[11px] font-semibold text-gold">{t.team.atRiskChip}</span>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)}
|
||||
<Card>
|
||||
<CardHeader><span className="font-display font-bold text-ink">{t.team.allTimeTopScorers}</span></CardHeader>
|
||||
<CardBody>
|
||||
{profile.keyPlayers.length ? (
|
||||
<ol className="space-y-1.5">
|
||||
{profile.keyPlayers.map((p, i) => (
|
||||
<li key={p.name} className="flex items-center gap-2 text-sm">
|
||||
<span className="w-4 text-right text-xs font-bold text-faint">{i + 1}</span>
|
||||
<span className="truncate text-ink-soft">{p.name}</span>
|
||||
<span className="tnum ml-auto font-semibold text-ink">{p.goals}</span>
|
||||
{p.pens ? <span className="text-[11px] text-faint">{fmt(t.common.pensShort, { n: p.pens })}</span> : null}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
) : <p className="text-sm text-faint">{t.common.noData}</p>}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user