"use client" import { useEffect, useState } from "react" import { CalendarX2, ShieldAlert } from "lucide-react" import { Wordmark } from "@/components/wordmark" import { TournamentCard, type Tournament } from "@/components/tournament-card" // --- API-typer (matcher app/routers/registration.py sin get_public_org) ---- type ApiOrgTournament = { id: string name: string status: string start_date: string | null end_date: string | null } type ApiOrgInfo = { name: string tournaments: ApiOrgTournament[] } function toTournament(t: ApiOrgTournament): Tournament { return { id: t.id, name: t.name, status: t.status as Tournament["status"], startDate: t.start_date ?? undefined, endDate: t.end_date ?? undefined, } } // --- Ordering -------------------------------------------------------------- // Upcoming (has a future/any start date and not completed) first, then // tournaments without dates set, then completed/finished ones last. function orderTournaments(list: Tournament[]) { const rank = (t: Tournament) => { if (t.status === "completed" || t.status === "archived") return 2 if (!t.startDate) return 1 return 0 } return [...list].sort((a, b) => { const diff = rank(a) - rank(b) if (diff !== 0) return diff // Within the upcoming group, earliest start first. if (a.startDate && b.startDate) { return a.startDate.localeCompare(b.startDate) } return 0 }) } // --- Root ------------------------------------------------------------------ export function PublicClub({ slug }: { slug: string }) { const [org, setOrg] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { let cancelled = false async function load() { try { const res = await fetch(`/public/orgs/${slug}`, { credentials: "include" }) if (res.status === 404) { if (!cancelled) setError("Klubben finnes ikke.") return } if (!res.ok) throw new Error(`org: ${res.status}`) const data: ApiOrgInfo = await res.json() if (!cancelled) setOrg(data) } catch { if (!cancelled) setError("Klarte ikke å laste klubbsiden. Prøv å laste siden på nytt.") } finally { if (!cancelled) setLoading(false) } } void load() return () => { cancelled = true } }, [slug]) if (loading) { return (
) } if (error || !org) { return (

{error ?? "Klubben finnes ikke."}

) } const tournaments = orderTournaments(org.tournaments.map(toTournament)) return (

Turneringer

{tournaments.length > 0 ? (
    {tournaments.map((tournament) => (
  • ))}
) : ( )}
) } // --- Banner ---------------------------------------------------------------- // Same visual treatment as the tournament landing banner: solid brand-green // gradient block with subtle decorative rings. Permanent look for now. function Banner({ name }: { name: string }) { return (