/* global React, NA_DATA */
const { useState, useEffect, useRef, useMemo } = React;
// ---------- Shared chrome ----------
function Topbar({ page, setPage, mobileOpen, setMobileOpen }) {
const { NAVIGATION } = NA_DATA;
return (
{ setPage('home'); setMobileOpen(false); }}>
Nottingham Athletic
{NAVIGATION.map(n => (
setPage(n.id)}>
{n.label}
))}
setPage('contact')}>
Join
setMobileOpen(o => !o)}>
{mobileOpen
?
: <> >}
{/* Rendered OUTSIDE on purpose: .topbar has backdrop-filter,
which would make it the containing block for this position:fixed
drawer and clamp it to the header's height. As a top-level sibling
its inset:0 resolves against the viewport and covers the screen. */}
{mobileOpen && (
)}
);
}
function Footer({ setPage }) {
return (
Nottingham Athletic
A Nottingham basketball club. Seven squads, one shared standard. Open trials each season — anyone with the work ethic is welcome.
);
}
// ---------- Reusable bits ----------
function Photo({ variant = 'photo-v1', tag, glyph, className = '', style, src, focal }) {
if (src) {
return (
{tag &&
{tag} }
);
}
return (
{glyph}
{tag && {tag} }
);
}
function Pill({ children, kind = 'navy' }) {
return {children} ;
}
function Stat({ label, value, sub }) {
return (
{label}
{value}
{sub &&
{sub}
}
);
}
function SquadCard({ squad, onClick }) {
return (
{squad.short}
{squad.tag}
{squad.name}
{squad.players} players
·
{squad.coach}
);
}
function FilterBar({ items, value, onChange }) {
return (
{items.map(it => (
onChange(it.id)}>
{it.dotClass && }
{it.label}
))}
);
}
function FixtureRow({ fx, expanded, onToggle }) {
const isWin = fx.result?.outcome === 'win';
const isLoss = fx.result?.outcome === 'loss';
return (
<>
{fx.date.day}
{fx.date.month}
{fx.home ? 'vs ' : 'at '} {fx.opponent}
{fx.status === 'past' && (
{isWin ? 'W' : isLoss ? 'L' : '–'}
)}
{fx.squadLabel} · {fx.tipoff} · {fx.venue || 'TBC'}
{fx.status === 'upcoming'
? fx.fullDate.replace(/^[A-Za-z]+ /, '')
: `${fx.result.ours} – ${fx.result.theirs}`}
{expanded && (
Venue
{fx.venue || 'TBC'}
)}
>
);
}
window.NASite = { Topbar, Footer, Photo, Pill, Stat, SquadCard, FilterBar, FixtureRow };