2026-07-30 07:55:35 +02:00
|
|
|
|
"use client"
|
|
|
|
|
|
|
|
|
|
|
|
// Velger riktig turnering-skjerm basert på tournament.format_type
|
|
|
|
|
|
// (ADR-011 lagformat vs. ADR-037 individuell) -- egen, autoritativ henting
|
|
|
|
|
|
// FØR noe rendres, i stedet for å stole på et query-param-hint (ville brutt
|
|
|
|
|
|
// for enhver inngang som ikke går via dashbordets akkurat-nå-opprettet-flyt,
|
|
|
|
|
|
// f.eks. en bokmerket lenke). Samme "hent org-ens turneringsliste og finn
|
|
|
|
|
|
// egen rad"-mønster som tournament-detail.tsx allerede bruker for join_code.
|
|
|
|
|
|
|
|
|
|
|
|
import { useEffect, useState } from "react"
|
2026-08-21 19:44:02 +02:00
|
|
|
|
import { useRouter } from "next/navigation"
|
2026-07-30 07:55:35 +02:00
|
|
|
|
import { TournamentDetail } from "@/components/tournament-detail"
|
|
|
|
|
|
import { IndividualTournamentDetail } from "@/components/individual-tournament-detail"
|
|
|
|
|
|
|
|
|
|
|
|
export function TournamentRouter({
|
|
|
|
|
|
organizationId,
|
|
|
|
|
|
tournamentId,
|
|
|
|
|
|
tournamentName,
|
|
|
|
|
|
}: {
|
|
|
|
|
|
organizationId: string
|
|
|
|
|
|
tournamentId: string
|
|
|
|
|
|
tournamentName: string
|
|
|
|
|
|
}) {
|
2026-08-21 19:44:02 +02:00
|
|
|
|
const router = useRouter()
|
2026-07-30 07:55:35 +02:00
|
|
|
|
const [formatType, setFormatType] = useState<"team" | "individual" | null>(null)
|
|
|
|
|
|
const [error, setError] = useState(false)
|
2026-08-21 19:44:02 +02:00
|
|
|
|
// Ikke-innlogget besøkende på denne organisator-URL-en (f.eks. en delt
|
|
|
|
|
|
// /tournaments/{id}?org=...-lenke) -- funnet 2026-08-21: den generiske
|
|
|
|
|
|
// feil-fallback-en under viste tidligere ALLTID Cup/lag-format-
|
|
|
|
|
|
// administrasjonsskjermen (samme "trygt mot krasj"-begrunnelse som før),
|
|
|
|
|
|
// helt uavhengig av turneringens faktiske format og helt uavhengig av
|
|
|
|
|
|
// ÅRSAKEN til feilen -- en anonym besøkende på en individuell turnering
|
|
|
|
|
|
// fikk et forvirrende, ødelagt Ryder Cup-oppsett-skjermbilde i stedet for
|
|
|
|
|
|
// en ren "logg inn"-beskjed. Skiller nå eksplisitt 401 (ikke innlogget)
|
|
|
|
|
|
// fra andre feil, og sender i stedet videre til den ekte offentlige siden.
|
|
|
|
|
|
const [notAuthenticated, setNotAuthenticated] = useState(false)
|
2026-07-30 07:55:35 +02:00
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
let cancelled = false
|
|
|
|
|
|
fetch(`/orgs/${organizationId}/tournaments`, { credentials: "include" })
|
2026-08-21 19:44:02 +02:00
|
|
|
|
.then((res) => {
|
|
|
|
|
|
if (res.status === 401) {
|
|
|
|
|
|
if (!cancelled) setNotAuthenticated(true)
|
|
|
|
|
|
return Promise.reject()
|
|
|
|
|
|
}
|
|
|
|
|
|
return res.ok ? res.json() : Promise.reject()
|
|
|
|
|
|
})
|
2026-07-30 07:55:35 +02:00
|
|
|
|
.then((list: { id: string; format_type: string }[]) => {
|
|
|
|
|
|
if (cancelled) return
|
|
|
|
|
|
const mine = list.find((t) => t.id === tournamentId)
|
|
|
|
|
|
setFormatType(mine?.format_type === "individual" ? "individual" : "team")
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
if (!cancelled) setError(true)
|
|
|
|
|
|
})
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
cancelled = true
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [organizationId, tournamentId])
|
|
|
|
|
|
|
2026-08-21 19:44:02 +02:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (notAuthenticated) router.replace(`/t/${tournamentId}`)
|
|
|
|
|
|
}, [notAuthenticated, tournamentId, router])
|
|
|
|
|
|
|
|
|
|
|
|
if (notAuthenticated) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="flex min-h-[100dvh] flex-col items-center justify-center gap-4 bg-background">
|
|
|
|
|
|
<div
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
className="size-10 animate-spin rounded-full border-4 border-primary/20 border-t-primary"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-30 07:55:35 +02:00
|
|
|
|
if (error) {
|
|
|
|
|
|
// Samme trygge fallback som resten av appen: en ukjent/utilgjengelig
|
|
|
|
|
|
// turnering skal ikke krasje -- TournamentDetail sin egen feilhåndtering
|
|
|
|
|
|
// (join_code/teams/players) tar over og viser en tydelig feilmelding.
|
2026-08-21 19:44:02 +02:00
|
|
|
|
// (Denne grenen er nå kun for EKTE feil hos en innlogget bruker --
|
|
|
|
|
|
// 401/ikke-innlogget håndteres over, IKKE lenger her.)
|
2026-07-30 07:55:35 +02:00
|
|
|
|
return (
|
|
|
|
|
|
<TournamentDetail organizationId={organizationId} tournamentId={tournamentId} tournamentName={tournamentName} />
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (formatType === null) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="flex min-h-[100dvh] flex-col items-center justify-center gap-4 bg-background">
|
|
|
|
|
|
<div
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
className="size-10 animate-spin rounded-full border-4 border-primary/20 border-t-primary"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (formatType === "individual") {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<IndividualTournamentDetail
|
|
|
|
|
|
organizationId={organizationId}
|
|
|
|
|
|
tournamentId={tournamentId}
|
|
|
|
|
|
tournamentName={tournamentName}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<TournamentDetail organizationId={organizationId} tournamentId={tournamentId} tournamentName={tournamentName} />
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|