/* soccerarena.ai — desktop: header + leaderboard. */
const { useState, useEffect } = React;
function preLabel(startDate) {
const days = Math.ceil((new Date(startDate + 'T00:00:00Z') - Date.now()) / 86400000);
return days > 0 ? `T-${days}` : 'PRE-TOURNAMENT';
}
function useSecondsUntil(isoTarget) {
const target = isoTarget ? new Date(isoTarget).getTime() : 0;
const secs = () => (target ? Math.max(0, Math.round((target - Date.now()) / 1000)) : 0);
const [s, setS] = useState(secs);
useEffect(() => {
if (!target) return;
const id = setInterval(() => setS(secs), 1000);
return () => clearInterval(id);
}, [target]);
return s;
}
function PreTournamentOverlay({ kickoffAt, startDate }) {
const s = useSecondsUntil(kickoffAt);
const days = Math.floor(s / 86400);
const hrs = Math.floor((s % 86400) / 3600);
const mins = Math.floor((s % 3600) / 60);
const sec = s % 60;
const pad = (n) => String(n).padStart(2, '0');
const dateLabel = startDate
? new Date(startDate + 'T00:00:00Z').toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric', timeZone: 'UTC' })
: '';
const units = [
{ n: pad(days), label: 'DAYS' },
{ n: pad(hrs), label: 'HRS' },
{ n: pad(mins), label: 'MIN' },
{ n: pad(sec), label: 'SEC' },
];
return (
{units.map(({ n, label }, i) => (
{i > 0 && (
:
)}
{n}
{label}
))}
First match · {dateLabel}
);
}
function DeskHeader({ countdown }) {
const t = ARENA.tournament;
const pct = t.dayTotal > 0 ? Math.min(100, (t.dayCurrent / t.dayTotal) * 100) : 0;
return (
footballarena
.ai
{t.dayCurrent > 0
? Day {t.dayCurrent} of {t.dayTotal}
: {preLabel(t.startDate)}}
·
{t.dayCurrent > 0 ? 'Next match in ' : 'First match in '}
{countdown}
);
}
function Leaderboard() {
const [sort, setSort] = useState({ key: 'total', dir: 'desc' });
const [open, setOpen] = useState(null);
const [hover, setHover] = useState(null);
const models = ARENA.models;
const t = ARENA.tournament;
const isPreTournament = t.dayCurrent === 0;
if (!models || models.length === 0) {
return (
Model predictions will appear here once the tournament begins.
);
}
const rows = [...models].sort((a, b) => {
const d = a[sort.key] - b[sort.key];
return sort.dir === 'desc' ? -d : d;
});
const leaderId = [...models].sort((a, b) => b.total - a.total)[0].id;
const setS = (key) => setSort((s) =>
s.key === key ? { key, dir: s.dir === 'desc' ? 'asc' : 'desc' } : { key, dir: 'desc' });
const numCols = [
{ key: 't2', label: 'MATCH', hint: 'Track 2' },
{ key: 't1', label: 'TOURN', hint: 'Track 1' },
{ key: 'total', label: 'TOTAL', hint: '' },
];
const Arrow = ({ k }) => sort.key === k
? {sort.dir === 'desc' ? '↓' : '↑'}
: ↕;
return (
Model Leaderboard
{t.phase.toUpperCase()} · {models.length} MODELS
MODEL
WINNER PICK
7-DAY
{numCols.map((c) => (
))}
{rows.map((m, i) => {
const isLeader = m.id === leaderId;
const isOpen = open === m.id;
const isHover = hover === m.id;
const bg = isOpen || isHover ? SA.surfaceHi : (isLeader ? SA.surface : 'transparent');
return (
setOpen(isOpen ? null : m.id)}
onMouseEnter={() => setHover(m.id)}
onMouseLeave={() => setHover(null)}
style={{
display: 'grid',
gridTemplateColumns: '38px minmax(220px,1fr) 168px 96px 76px 70px 86px 96px',
alignItems: 'center', cursor: 'pointer',
padding: '0 14px', height: 58,
background: bg,
borderBottom: `1px solid ${SA.line2}`,
borderLeft: isLeader ? `2px solid ${SA.lime}` : '2px solid transparent',
transition: 'background 120ms',
}}>
{i + 1}
{m.name}
{m.origin}
{m.id}
{m.pick.flag}
{m.pick.name}
{m.flipped && }
= 0 ? SA.lime : SA.orange} />
{m.t2}
{m.t1}
{m.total}
{isOpen &&
}
);
})}
{isPreTournament && (
)}
);
}
function ExpandedRow({ m }) {
const cell = (label, node) => (
);
const v = (txt, big = false) => {txt};
return (
{cell('ANALYST NOTE',
{m.note})}
{cell('WINNER CONFIDENCE',
{v(`${Math.round(m.conf * 100)}%`, true)}
)}
{cell('GOLDEN BOOT', <>{
{m.goldenBoot.flag}}{v(m.goldenBoot.name)}>)}
{cell('GOLDEN BALL', <>{
{m.goldenBall.flag}}{v(m.goldenBall.name)}>)}
{cell('PICK FLIPS / WEEK',
{v(`${m.flipsWeek}×`, true)}{m.flipped ? : STABLE}
)}
);
}
function hCell() {
return { display: 'inline-flex', alignItems: 'center', background: 'none', border: 'none', cursor: 'pointer', padding: 0, font: 'inherit', color: 'inherit', letterSpacing: 'inherit' };
}
function numCell(color, size = 14, weight = 500) {
return { fontFamily: SA.mono, fontSize: size, fontWeight: weight, color, textAlign: 'right', fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.01em' };
}
Object.assign(window, { DeskHeader, Leaderboard });