teecup/frontend/app/t/[id]/live/page.tsx
Erol Haagenrud 9fad4b3f38 Offentlig "Følg live" for individuelle turneringer: V0-UI + full kobling
Fullfører ADR-098. Ny components/public-individual-live.tsx (V0-bygget,
presentasjonslaget uendret fra eksporten) koblet til de ekte endepunktene
fra forrige commit. Rettet en reell modellmismatch underveis: V0-mock-en
modellerte hver runde som sitt eget separate leaderboard, den ekte
backend-beregningen er ett samlet, kumulativt turnering-leaderboard --
rundevelgeren styrer nå kun hvilken rundes hull-for-hull som lastes.

Ny offentlig GET .../rounds/{round_id}/participants/{tournament_participant_id}
/holes for hull-for-hull-utvidelsen (egen rute, ikke gjenbruk av
frittstående-runders tilsvarende -- ulik datamodell).

app/t/[id]/live/page.tsx avgjør nå format SERVER-side før noe rendres,
unngår klient-side-feilklassen fra forrige commit helt for denne siden.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 19:50:35 +02:00

42 lines
1.7 KiB
TypeScript

import { PublicLive } from "@/components/public-live"
import { PublicIndividualLive } from "@/components/public-individual-live"
// Server-side, IKKE nettleser-fetch -- samme mønster som app/logg-inn/
// page.tsx og generateMetadata i app/t/[id]/page.tsx (peker direkte på
// API-et, går IKKE gjennom next.config.mjs sin rewrites()). Avgjør
// format_type FØR noe rendres, slik at en individuell turnering aldri
// (heller ikke kortvarig) viser Cup-formatets side -- se CHANGELOG.md
// 2026-08-21 for hele bakgrunnen (tournament-router.tsx sin tilsvarende
// klient-side feil, som denne siden bevisst unngår ved å avgjøre server-
// side i stedet).
const API_ORIGIN = process.env.TEECUP_API_ORIGIN || "http://localhost:8000"
export default async function PublicLivePage({
params,
searchParams,
}: {
params: Promise<{ id: string }>
searchParams: Promise<{ code?: string }>
}) {
const { id } = await params
const { code } = await searchParams
let formatType = "team"
try {
const url = `${API_ORIGIN}/public/tournaments/${id}${code ? `?code=${encodeURIComponent(code)}` : ""}`
const res = await fetch(url, { cache: "no-store" })
if (res.ok) {
const data: { format_type?: string } = await res.json()
formatType = data.format_type === "individual" ? "individual" : "team"
}
} catch {
// Klarte ikke å avgjøre format server-side -- fall tilbake til Cup-
// siden sin egen feilhåndtering (samme "trygg fallback"-prinsipp som
// resten av appen), ikke en hard krasj her.
}
if (formatType === "individual") {
return <PublicIndividualLive tournamentId={id} code={code} />
}
return <PublicLive tournamentId={id} code={code} />
}