// Shared shell: nav context, crest, header, footer, small UI atoms. const CTSCShell = (function () { const NavCtx = React.createContext(null); function useNav() { return React.useContext(NavCtx); } // Council crest mark (fallback when no logo uploaded) const CREST_SVG = "data:image/svg+xml," + encodeURIComponent( "CT"); function Crest({ size = 50 }) { return (
CT
); } // Real CTSC logo — Table Mountain + disa orchid emblem (blends on royal-blue chrome) function LogoMark({ size = 38 }) { return ( Cape Town Sport Council ); } function StatusBadge({ status }) { const map = { Approved: 'badge-approved', Pending: 'badge-pending', Draft: 'badge-draft' }; const dot = { Approved: '●', Pending: '◐', Draft: '○' }; return {dot[status] || '○'} {status}; } // Table-Mountain photo placeholder (decorative) — shows uploaded src if provided function Photo({ h = 200, tag = 'Photo', style = {}, src, children }) { if (src) { return (
{tag} {children}
); } return (
{tag &&
◳ {tag}
} {children}
); } function Avatar({ name, sport, size = 64, src }) { const initials = name.split(' ').map(w => w[0]).slice(0, 2).join(''); if (src) { return
{name}
; } return (
{initials}
); } // Federation logo — shows uploaded logo if present, else the sport-initial monogram. function FedLogo({ fed, size = 48, radius = 6, fontSize }) { const fs = fontSize || size * 0.42; if (fed && fed.logo) { return (
{(fed.name
); } return (
{((fed && fed.sport) || '?')[0]}
); } const NAV = [ ['home', 'Home'], ['about', 'About'], ['federations', 'Federations'], ['heroes', 'Heroes'], ['awards', 'Awards'], ['resources', 'Resources'], ['events', 'Events'], ['transformation', 'Transformation'], ['news', 'News'], ['blog', 'Blog'], ]; function Header() { const { route, go } = useNav(); const { user, actions } = CTSCStore.useStore(); const [menu, setMenu] = React.useState(false); return ( <>
Governance · Workflow · Transformation Affiliated to SASCOC · Est. 2000
); } const menuItem = { display: 'block', width: '100%', textAlign: 'left', padding: '9px 10px', fontSize: 14, fontWeight: 700, color: 'var(--navy)', borderRadius: 5 }; function Footer() { const { go } = useNav(); const { user } = CTSCStore.useStore(); return ( ); } return { NavCtx, useNav, Crest, LogoMark, StatusBadge, Photo, Avatar, FedLogo, Header, Footer, NAV }; })(); window.CTSCShell = CTSCShell;