import { useState } from "react"; import { Badge } from "~/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "~/components/ui/table"; import { cn } from "~/lib/utils"; import { PlayoffBracket, type Match } from "~/components/scoring/PlayoffBracket"; import { CheckCircle2, XCircle, Clock } from "lucide-react"; import type { Cs2StageResultWithName } from "~/models/cs2-major-stage"; import type { SeasonMatch } from "~/models/season-match"; type StageTab = 1 | 2 | 3 | "champions"; interface Ownership { participantId: string; teamName: string; teamId: string; ownerName?: string; } interface Cs2MatchRow extends Omit { scheduledAt: string | null; startedAt: string | null; completedAt: string | null; } interface PlayoffMatchWithRelations extends Match { participant1: { id: string; name: string } | null; participant2: { id: string; name: string } | null; winner: { id: string; name: string } | null; loser: { id: string; name: string } | null; } interface Props { cs2StageResults: Cs2StageResultWithName[]; seasonMatches: Cs2MatchRow[]; playoffMatches: PlayoffMatchWithRelations[]; playoffRounds: string[]; bracketTemplateId: string | null; teamOwnerships: Ownership[]; userParticipantIds: string[]; } const STAGE_LABELS: Record = { 1: "Stage 1", 2: "Stage 2", 3: "Stage 3", champions: "Champions", }; function SwissStageTab({ stage, stageResults, matches, teamOwnerships, userParticipantIds, }: { stage: 1 | 2 | 3; stageResults: Cs2StageResultWithName[]; matches: Cs2MatchRow[]; teamOwnerships: Ownership[]; userParticipantIds: string[]; }) { const ownershipMap = new Map(teamOwnerships.map((o) => [o.participantId, o])); const userIds = new Set(userParticipantIds); const matchesInStage = matches.filter((m) => m.matchStage === stage); // Group teams by W-L record (approximated from stageEliminatedWins if eliminated, else unknown) const eliminated = stageResults.filter((r) => r.stageEliminated === stage); const advanced = stageResults.filter((r) => r.stageEliminated === null && r.stageEntry <= stage); if (stageResults.length === 0) { return (

No teams assigned to this stage yet.

); } return (
Team Manager W L Status {stageResults.map((r) => { const ownership = ownershipMap.get(r.participantId); const isUser = userIds.has(r.participantId); const wins = r.stageEliminated === stage ? (r.stageEliminatedWins ?? "—") : "—"; const losses = r.stageEliminated === stage ? (3 - (r.stageEliminatedWins ?? 0)) : "—"; const isElim = r.stageEliminated === stage; const isAdvanced = r.stageEliminated === null || (r.stageEliminated !== null && r.stageEliminated > stage); return ( {r.participantName} {isUser && } {ownership ? ownership.teamName : "—"} {wins} {losses} {isElim ? ( Eliminated ) : isAdvanced ? ( Advanced ) : ( In Progress )} ); })}
{matchesInStage.length > 0 && (

Matches

{matchesInStage.map((m) => { const p1Name = m.participant1Id ? stageResults.find((r) => r.participantId === m.participant1Id)?.participantName ?? m.participant1Id.slice(0, 8) : "TBD"; const p2Name = m.participant2Id ? stageResults.find((r) => r.participantId === m.participant2Id)?.participantName ?? m.participant2Id.slice(0, 8) : "TBD"; const dateStr = m.scheduledAt ? new Date(m.scheduledAt).toLocaleDateString(undefined, { month: "short", day: "numeric" }) : null; return (
{p1Name} {m.status === "complete" ? `${m.participant1Score ?? 0}–${m.participant2Score ?? 0}` : dateStr ?? "vs"} {p2Name}
); })}
)}
); } export function Cs2MajorEventView({ cs2StageResults, seasonMatches, playoffMatches, playoffRounds, bracketTemplateId, teamOwnerships, userParticipantIds, }: Props) { const hasChampionsActivity = playoffMatches.some((m) => m.winnerId !== null); const highestActiveStage: 1 | 2 | 3 = cs2StageResults.some((r) => r.stageEntry >= 3 || r.stageEliminated === 3) ? 3 : cs2StageResults.some((r) => r.stageEntry >= 2 || r.stageEliminated === 2) ? 2 : 1; const [activeTab, setActiveTab] = useState( hasChampionsActivity ? "champions" : highestActiveStage ); const tabs: StageTab[] = [1, 2, 3, "champions"]; const ownershipMap = new Map(teamOwnerships.map((o) => [o.participantId, o])); return (
{/* Tab bar */}
{tabs.map((tab) => ( ))}
{/* Swiss stage tabs */} {activeTab !== "champions" && ( r.stageEntry <= (activeTab as number) && (r.stageEliminated === null || r.stageEliminated >= (activeTab as number)) )} matches={seasonMatches} teamOwnerships={teamOwnerships} userParticipantIds={userParticipantIds} /> )} {/* Champions Stage bracket */} {activeTab === "champions" && ( playoffMatches.length > 0 ? ( ) : (

Champions Stage bracket will be available once Stage 3 is complete.

) )}
); }