diff --git a/frontend/components/round-groups-panel.tsx b/frontend/components/round-groups-panel.tsx index bf96928..fca22c8 100644 --- a/frontend/components/round-groups-panel.tsx +++ b/frontend/components/round-groups-panel.tsx @@ -30,6 +30,10 @@ type ApiRoundGroup = { sequence: number tee_time: string | null tee_time_override: string | null + // Kun meningsfullt når runden er 'shotgun' (migrasjon 088, ADR-096) -- + // `null` for en 'consecutive'-runde, som fortsatt bruker rundens EGET + // delte start_hole (uendret). + start_hole: number | null participants: ApiGroupParticipant[] } @@ -42,6 +46,7 @@ type ApiRoundInfo = { scheduled_at: string | null tee_interval_minutes: number | null start_hole: number + start_mode: string } function formatTeeTime(iso: string | null) { @@ -83,6 +88,10 @@ export function RoundGroupsPanel({ const [roundInfo, setRoundInfo] = useState(null) const [scheduledAtInput, setScheduledAtInput] = useState("") const [intervalInput, setIntervalInput] = useState("") + // Shotgun-start (migrasjon 088, ADR-096) -- bruker: "Det må komme frem + // om det er Shotgun eller løpende start... Sorteringen av startlisten + // gjøres etter utslagsform." 'consecutive' = dagens oppførsel uendret. + const [startModeInput, setStartModeInput] = useState<"consecutive" | "shotgun">("consecutive") const [groups, setGroups] = useState([]) const [ungrouped, setUngrouped] = useState([]) @@ -103,6 +112,7 @@ export function RoundGroupsPanel({ setRoundInfo(thisRound) setScheduledAtInput(toDatetimeLocalValue(thisRound?.scheduled_at ?? null)) setIntervalInput(thisRound?.tee_interval_minutes?.toString() ?? "") + setStartModeInput(thisRound?.start_mode === "shotgun" ? "shotgun" : "consecutive") setGroups(groupsData.groups) setUngrouped(groupsData.ungrouped) } catch { @@ -134,6 +144,7 @@ export function RoundGroupsPanel({ body: JSON.stringify({ scheduled_at: scheduledAtIso, tee_interval_minutes: intervalInput.trim() ? Number(intervalInput) : null, + start_mode: startModeInput, }), }) if (!res.ok) { @@ -169,7 +180,15 @@ export function RoundGroupsPanel({ function addEmptyGroup() { const nextSequence = (groups.reduce((m, g) => Math.max(m, g.sequence), 0) || 0) + 1 - setGroups((prev) => [...prev, { id: null, sequence: nextSequence, tee_time: null, tee_time_override: null, participants: [] }]) + setGroups((prev) => [ + ...prev, + { id: null, sequence: nextSequence, tee_time: null, tee_time_override: null, start_hole: null, participants: [] }, + ]) + } + + function setGroupStartHole(sequence: number, value: string) { + const startHole = value.trim() ? Number(value) : null + setGroups((prev) => prev.map((g) => (g.sequence === sequence ? { ...g, start_hole: startHole } : g))) } function removeGroup(sequence: number) { @@ -220,6 +239,7 @@ export function RoundGroupsPanel({ groups: groups.map((g) => ({ sequence: g.sequence, tee_time_override: null, + start_hole: g.start_hole, round_participant_ids: g.participants.map((p) => p.round_participant_id), })), }), @@ -297,41 +317,99 @@ export function RoundGroupsPanel({ ) : ( <>
-

Første utslag og intervall

-

- Alle grupper starter fra samme hull (hull {roundInfo?.start_hole ?? 1}, satt for hele runden), - med staggerte klokkeslett ut fra intervallet under. Gruppe 1 slår ut først, gruppe 2 dette - antall minutter senere, og så videre. -

-
- - - +

Utslagsform

+
+ {( + [ + { value: "consecutive" as const, label: "Løpende start" }, + { value: "shotgun" as const, label: "Shotgun" }, + ] + ).map((opt) => ( + + ))}
+ + {startModeInput === "consecutive" ? ( + <> +

+ Alle grupper starter fra samme hull (hull {roundInfo?.start_hole ?? 1}, satt for hele runden), + med staggerte klokkeslett ut fra intervallet under. Gruppe 1 slår ut først, gruppe 2 dette + antall minutter senere, og så videre. +

+
+ + + +
+ + ) : ( + <> +

+ Alle grupper går ut SAMTIDIG, hver fra sitt eget starthull -- sett starthull per + gruppe nedenfor. Intervallet gjelder ikke i denne modusen. +

+
+ + +
+ + )}
@@ -379,11 +457,23 @@ export function RoundGroupsPanel({ )} {groups .slice() - .sort((a, b) => a.sequence - b.sequence) + .sort((a, b) => + // Shotgun (migrasjon 088, ADR-096): vis sortert etter + // STARTHULL, ikke sequence -- speiler backend sin + // tilsvarende sortering (_fetch_round_groups), men må + // også gjelde HER siden lokale, ulagrede endringer + // (f.eks. et nettopp justert starthull) ellers ikke + // ville flyttet gruppen i visningen før neste lagring/ + // reload. + startModeInput === "shotgun" + ? (a.start_hole === null ? 1 : 0) - (b.start_hole === null ? 1 : 0) || + (a.start_hole ?? 0) - (b.start_hole ?? 0) + : a.sequence - b.sequence, + ) .map((g) => (
-
+
{g.sequence} @@ -391,6 +481,20 @@ export function RoundGroupsPanel({
@@ -658,10 +697,31 @@ function TeamColumn({ })}
+ {!locked && startMode === "shotgun" && ( +
+ +
+ )} + {!locked && (
+
+ + {session.start_mode === "shotgun" ? "Shotgun" : "Løpende start"} + +
{session.scheduled_at ? (
) : ( @@ -734,7 +750,7 @@ function SessionCard({ Tidspunkt ikke satt
)} - {session.start_hole !== 1 && ( + {session.start_mode === "consecutive" && session.start_hole !== 1 && (
+
+ +
+ {( + [ + { value: "consecutive" as const, label: "Løpende start" }, + { value: "shotgun" as const, label: "Shotgun" }, + ] + ).map((opt) => ( + + ))} +
+ {startMode === "shotgun" && ( +

+ Alle matcher i økten går ut samtidig -- starthull settes per match i trekning-skjermen + i stedet for her. +

+ )} +
+
-
- - setStartHole(e.target.value)} - className="h-12 rounded-2xl text-base" - /> -
+ {startMode === "consecutive" && ( +
+ + setStartHole(e.target.value)} + className="h-12 rounded-2xl text-base" + /> +
+ )}
- {hasTime && ( + {hasTime && startMode === "consecutive" && (