i think working bracket runner

This commit is contained in:
yohlo
2025-09-11 15:59:27 -05:00
parent 8dfff139e1
commit 3ffa6b03c7
10 changed files with 424 additions and 139 deletions

View File

@@ -1,25 +1,31 @@
import { createFileRoute, redirect, useRouter } 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 { Container, Alert, Text } from '@mantine/core'
import { Info } from '@phosphor-icons/react'
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 { createFileRoute, redirect, useRouter } from "@tanstack/react-router";
import {
tournamentKeys,
tournamentQueries,
useTournament,
} from "@/features/tournaments/queries";
import { ensureServerQueryData } from "@/lib/tanstack-query/utils/ensure";
import SeedTournament from "@/features/tournaments/components/seed-tournament";
import { Container } 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 { startMatch } from "@/features/matches/server";
import { useServerMutation } from "@/lib/tanstack-query/hooks";
import { useQueryClient } from "@tanstack/react-query";
export const Route = createFileRoute('/_authed/admin/tournaments/run/$id')({
export const Route = createFileRoute("/_authed/admin/tournaments/run/$id")({
beforeLoad: async ({ context, params }) => {
const { queryClient } = context
const { queryClient } = context;
const tournament = await ensureServerQueryData(
queryClient,
tournamentQueries.details(params.id)
)
if (!tournament) throw redirect({ to: '/admin/tournaments' })
);
if (!tournament) throw redirect({ to: "/admin/tournaments" });
return {
tournament,
}
};
},
loader: ({ context }) => ({
fullWidth: true,
@@ -29,61 +35,75 @@ export const Route = createFileRoute('/_authed/admin/tournaments/run/$id')({
},
}),
component: RouteComponent,
})
});
function RouteComponent() {
const { id } = Route.useParams();
const { data: tournament } = useTournament(id)
const { data: tournament } = useTournament(id);
const queryClient = useQueryClient();
const start = useServerMutation({
mutationFn: startMatch,
successMessage: "Match started!",
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: tournamentKeys.details(tournament.id),
});
},
});
const bracket: BracketData = useMemo(() => {
if (!tournament.matches || tournament.matches.length === 0) {
return { winners: [], losers: [] }
return { winners: [], losers: [] };
}
const winnersMap = new Map<number, Match[]>()
const losersMap = new Map<number, Match[]>()
tournament.matches.sort((a, b) => a.lid - b.lid).forEach((match) => {
if (!match.is_losers_bracket) {
if (!winnersMap.has(match.round)) {
winnersMap.set(match.round, [])
const winnersMap = new Map<number, Match[]>();
const losersMap = new Map<number, Match[]>();
tournament.matches
.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);
}
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)
.map(([, matches]) => matches);
const losers = Array.from(losersMap.entries())
.sort(([a], [b]) => a - b)
.map(([, matches]) => matches)
return { winners, losers }
}, [tournament.matches])
.map(([, matches]) => matches);
return { winners, losers };
}, [tournament.matches]);
const handleStartMatch = (match: Match) => {
const handleStartMatch = async (match: Match) => {
await start.mutate({
data: match.id
})
};
}
console.log(tournament.matches)
console.log(tournament.matches);
return (
<Container size="md">
{
tournament.matches?.length ?
<BracketView bracket={bracket} onStartMatch={console.log} />
: (
<SeedTournament
tournamentId={tournament.id}
teams={tournament.teams || []}
/>)
}
{tournament.matches?.length ? (
<BracketView bracket={bracket} showControls />
) : (
<SeedTournament
tournamentId={tournament.id}
teams={tournament.teams || []}
/>
)}
</Container>
)
);
}