import { useState } from "react"; import { cn } from "~/lib/utils"; import type { BracketPhase, ConferenceGroup } from "~/lib/bracket-templates"; import { TreeColumns, BracketTreePaginated, type BracketMatch, type BracketOwnership, } from "./BracketTreeView"; interface TabbedBracketLayoutProps { rounds: string[]; matchesByRound: Map; ownershipMap: Map; userParticipantIds: Set; phases: BracketPhase[]; scoringRoundIdx: number; } const CARD_H = 112; const CARD_GAP = 14; function groupMatches( matchesByRound: Map, group: ConferenceGroup ): Map { const out = new Map(); for (const [round, allowed] of Object.entries(group.roundMatchNumbers)) { const filtered = (matchesByRound.get(round) ?? []).filter((m) => allowed.includes(m.matchNumber) ); if (filtered.length > 0) out.set(round, filtered); } return out; } function phaseHeight(matchesByRound: Map, rounds: string[]): number { const max = Math.max(...rounds.map((r) => matchesByRound.get(r)?.length ?? 0), 1); return max * (CARD_H + CARD_GAP); } export function TabbedBracketLayout({ rounds, matchesByRound, ownershipMap, userParticipantIds, phases, scoringRoundIdx, }: TabbedBracketLayoutProps) { const [activeIdx, setActiveIdx] = useState(0); const phase = phases[activeIdx]; const groupRounds = phase.groups ? rounds.filter((r) => phase.groups?.some((g) => g.roundMatchNumbers[r] !== undefined)) : []; const sharedRounds = (phase.sharedRounds ?? []).filter((r) => rounds.includes(r)); const simpleRounds = phase.groups ? [] : (phase.rounds ?? []).filter((r) => rounds.includes(r)); const phaseRounds = phase.groups ? [...groupRounds, ...sharedRounds] : simpleRounds; const phaseMatchesByRound = new Map(phaseRounds.map((r) => [r, matchesByRound.get(r) ?? []])); const sharedMatchesByRound = new Map(sharedRounds.map((r) => [r, matchesByRound.get(r) ?? []])); const phaseFirstScoringIdx = phaseRounds.findIndex((r) => rounds.indexOf(r) >= scoringRoundIdx); return (
{phases.map((p, i) => ( ))}
{/* Desktop */}
{phase.groups ? (
{phase.groups.map((group) => { const gMatches = groupMatches(matchesByRound, group); const gRounds = groupRounds.filter((r) => group.roundMatchNumbers[r] !== undefined); return (

{group.name}

); })} {sharedRounds.length > 0 && ( )}
) : ( )}
{/* Mobile */}
= 0 ? phaseFirstScoringIdx : undefined} />
); }