import { createFileRoute, redirect } from "@tanstack/react-router"; import { tournamentQueries, useTournament, } from "@/features/tournaments/queries"; import { ensureServerQueryData } from "@/lib/tanstack-query/utils/ensure"; import SeedTournament from "@/features/tournaments/components/seed-tournament"; import SetupGroupStage from "@/features/tournaments/components/setup-group-stage"; import GroupStageView from "@/features/tournaments/components/group-stage-view"; import { Container, Stack, Divider, Title } from "@mantine/core"; import { useMemo } from "react"; import { BracketData } from "@/features/bracket/types"; import { Match } from "@/features/matches/types"; import BracketView from "@/features/bracket/components/bracket-view"; import { SpotifyControlsBar } from "@/features/spotify/components"; import { useAuth } from "@/contexts/auth-context"; export const Route = createFileRoute("/_authed/admin/tournaments/run/$id")({ beforeLoad: async ({ context, params }) => { const { queryClient } = context; const tournament = await ensureServerQueryData( queryClient, tournamentQueries.details(params.id) ); if (!tournament) throw redirect({ to: "/admin/tournaments" }); return { tournament, }; }, loader: ({ context }) => ({ fullWidth: true, withPadding: false, showSpotifyPanel: true, header: { withBackButton: true, title: `Run ${context.tournament.name}`, }, }), component: RouteComponent, }); function RouteComponent() { const { id } = Route.useParams(); const { data: tournament } = useTournament(id); const { roles } = useAuth(); const isAdmin = roles?.includes('Admin') || false; const hasGroupStage = useMemo(() => { return tournament.matches?.some((match) => match.round === -1) || false; }, [tournament.matches]); const hasKnockout = useMemo(() => { return tournament.matches?.some((match) => match.round !== -1) || false; }, [tournament.matches]); const knockoutBracketPopulated = useMemo(() => { return tournament.matches?.some((match) => match.round === 0 && match.lid >= 0 && (match.home || match.away) ) || false; }, [tournament.matches]); const bracket: BracketData = useMemo(() => { if (!tournament.matches || tournament.matches.length === 0) { return { winners: [], losers: [] }; } const winnersMap = new Map(); const losersMap = new Map(); tournament.matches .filter((match) => match.round !== -1) .sort((a, b) => a.lid - b.lid) .forEach((match) => { if (!match.is_losers_bracket) { if (!winnersMap.has(match.round)) { winnersMap.set(match.round, []); } winnersMap.get(match.round)!.push(match); } else { if (!losersMap.has(match.round)) { losersMap.set(match.round, []); } losersMap.get(match.round)!.push(match); } }); const winners = Array.from(winnersMap.entries()) .sort(([a], [b]) => a - b) .map(([, matches]) => matches); const losers = Array.from(losersMap.entries()) .sort(([a], [b]) => a - b) .map(([, matches]) => matches); return { winners, losers }; }, [tournament.matches]); return ( { isAdmin && !tournament.regional && } {tournament.matches?.length ? ( hasGroupStage && hasKnockout ? (
Knockout Bracket
) : hasGroupStage ? ( ) : ( ) ) : ( tournament.regional === true ? ( ) : ( ) )}
); }