import { createFileRoute, redirect, useNavigate } from "@tanstack/react-router"; import { tournamentQueries, useFreeAgents, useTournament } from "@/features/tournaments/queries"; import { ensureServerQueryData } from "@/lib/tanstack-query/utils/ensure"; import { Stack, Text, Button, Alert, LoadingOverlay, Group } from "@mantine/core"; import { useState } from "react"; import useGenerateRandomTeams from "@/features/tournaments/hooks/use-generate-random-teams"; import useConfirmTeamAssignments from "@/features/tournaments/hooks/use-confirm-team-assignments"; import TeamAssignmentPreview from "@/features/tournaments/components/team-assignment-preview"; import { WarningCircleIcon, ShuffleIcon, CheckCircleIcon } from "@phosphor-icons/react"; import { PlayerInfo } from "@/features/players/types"; import { useQueryClient } from "@tanstack/react-query"; export const Route = createFileRoute("/_authed/admin/tournaments/$id/assign-partners")({ 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 }) => ({ header: { withBackButton: true, title: `Manage ${context.tournament.name}`, }, }), component: RouteComponent, }); interface TeamAssignment { player1: PlayerInfo; player2: PlayerInfo; teamName: string; } function RouteComponent() { const { id } = Route.useParams(); const navigate = useNavigate(); const queryClient = useQueryClient(); const { data: freeAgents } = useFreeAgents(id); const [assignments, setAssignments] = useState(null); const [currentSeed, setCurrentSeed] = useState(undefined); const generateMutation = useGenerateRandomTeams(); const confirmMutation = useConfirmTeamAssignments(); const hasOddPlayers = freeAgents.length % 2 !== 0; const hasEnoughPlayers = freeAgents.length >= 2; const handleGenerate = () => { generateMutation.mutate( { data: { tournamentId: id, seed: currentSeed } }, { onSuccess: (result) => { setAssignments(result.assignments); setCurrentSeed(result.seed); }, } ); }; const handleReroll = () => { if (currentSeed === undefined) return; generateMutation.mutate( { data: { tournamentId: id, seed: currentSeed + 1 } }, { onSuccess: (result) => { setAssignments(result.assignments); setCurrentSeed(result.seed); }, } ); }; const handleConfirm = () => { if (!assignments) return; const formattedAssignments = assignments.map((a) => ({ player1Id: a.player1.id, player2Id: a.player2.id, teamName: a.teamName, })); confirmMutation.mutate( { data: { tournamentId: id, assignments: formattedAssignments } }, { onSuccess: () => { queryClient.invalidateQueries({ queryKey: tournamentQueries.details(id).queryKey }); queryClient.invalidateQueries({ queryKey: tournamentQueries.free_agents(id).queryKey }); navigate({ to: "/admin/tournaments/$id", params: { id } }); }, } ); }; return ( {freeAgents.length} {freeAgents.length === 1 ? "player enrolled" : "players enrolled"} {!hasEnoughPlayers && ( }> Need at least 2 players to create teams )} {hasOddPlayers && ( }> Cannot create teams with an odd number of players. Please have one player unenroll. )} {!assignments && hasEnoughPlayers && !hasOddPlayers && ( )} {assignments && ( Partner Assignments )} ); }