"use client" import { useState } from "react" import { useRouter } from "next/navigation" interface Player { id: number name: string currentElo: number } interface Team { id: number teamName: string | null player1: Player player2: Player } interface TeamsSectionProps { tournamentId: number teams: Team[] participants: Player[] teamDurability: string partnerRotation: string allowByes: boolean } type TeamDurabilityOption = 'permanent' | 'variable' | 'per_round' type PartnerRotationOption = 'none' | 'minimize_repeat' | 'maximize_even' | 'elo_based' export default function TeamsSection({ tournamentId, teams: initialTeams, participants, teamDurability: initialTeamDurability, partnerRotation: initialPartnerRotation, allowByes: initialAllowByes, }: TeamsSectionProps) { const router = useRouter() const [teams, setTeams] = useState(initialTeams) const [teamDurability, setTeamDurability] = useState(initialTeamDurability as TeamDurabilityOption) const [partnerRotation, setPartnerRotation] = useState(initialPartnerRotation as PartnerRotationOption) const [allowByes, setAllowByes] = useState(initialAllowByes) const [isGenerating, setIsGenerating] = useState(false) const [error, setError] = useState("") const [success, setSuccess] = useState("") const handleSaveConfig = async () => { setError("") setSuccess("") setIsGenerating(true) try { const response = await fetch(`/api/tournaments/${tournamentId}`, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ teamDurability, partnerRotation, allowByes, }), }) if (!response.ok) { try { const errorData = await response.json() setError(errorData.error || "Failed to save configuration") } catch { setError(`Failed to save configuration: ${response.status} ${response.statusText}`) } return } setSuccess("Configuration saved successfully!") } catch (err) { if (err instanceof Error) { setError(err.message) } else { setError("An unknown error occurred") } } finally { setIsGenerating(false) } } const handleGenerateTeams = async () => { if (participants.length < 2) { setError("At least 2 participants are required to generate teams") return } if (participants.length % 2 !== 0 && !allowByes) { setError("Odd number of participants. Enable 'Allow Byes' to proceed.") return } setError("") setSuccess("") setIsGenerating(true) try { const response = await fetch(`/api/tournaments/${tournamentId}/teams/generate`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ teamDurability, partnerRotation, allowByes, }), }) if (!response.ok) { try { const errorData = await response.json() setError(errorData.error || "Failed to generate teams") } catch { setError(`Failed to generate teams: ${response.status} ${response.statusText}`) } return } const data = await response.json() setTeams(data.teams) setSuccess(`Successfully generated ${data.teams.length} teams!`) router.refresh() } catch (err) { if (err instanceof Error) { setError(err.message) } else { setError("An unknown error occurred") } } finally { setIsGenerating(false) } } const handleDeleteTeams = async () => { if (!confirm("Are you sure you want to delete all teams? This will also delete the schedule.")) { return } setError("") setSuccess("") setIsGenerating(true) try { // First delete schedule if exists await fetch(`/api/tournaments/${tournamentId}/schedule`, { method: "DELETE", }) // Then delete teams const response = await fetch(`/api/tournaments/${tournamentId}/teams`, { method: "DELETE", }) if (!response.ok) { try { const errorData = await response.json() setError(errorData.error || "Failed to delete teams") } catch { setError(`Failed to delete teams: ${response.status} ${response.statusText}`) } return } setTeams([]) setSuccess("Teams deleted successfully!") router.refresh() } catch (err) { if (err instanceof Error) { setError(err.message) } else { setError("An unknown error occurred") } } finally { setIsGenerating(false) } } return (

Teams ({teams.length})

{/* Configuration Panel */}

Team Configuration

{/* Team Durability */}

{teamDurability === 'permanent' ? 'Teams are fixed for the entire tournament. Each team plays together in all rounds.' : teamDurability === 'variable' ? 'Teams are generated per round based on configuration. Partners rotate each round.' : 'Teams are created fresh for each round. No persistent teams.'}

{/* Partner Rotation (for variable/per_round teams) */} {(teamDurability === 'variable' || teamDurability === 'per_round') && (

{partnerRotation === 'none' ? 'Partners are randomly assigned each round.' : partnerRotation === 'minimize_repeat' ? 'Algorithm minimizes how often players partner together.' : partnerRotation === 'maximize_even' ? 'Algorithm pairs teams to maximize competitive balance.' : 'Strongest player paired with weakest player each round.'}

)} {/* Allow Byes (for odd participant counts) */}

When enabled, one player will have a bye each round if there's an odd number of participants.

{/* Action Buttons */}
{/* Error/Success Messages */} {error && (
{error}
)} {success && (
{success}
)} {/* Team Generation Controls */}
{teams.length > 0 && ( )}
{/* Teams Display */} {teams.length > 0 ? (
{teams.map((team) => (

{team.player1.name} + {team.player2.name}

{team.teamName || `Team ${team.id}`}

ELO: {team.player1.currentElo} + {team.player2.currentElo} = {team.player1.currentElo + team.player2.currentElo}

))}
) : (

No teams created yet. Configure options above and click Generate Teams.

)} {/* Participants Summary */}

Available Participants ({participants.length})

{participants.map((player) => (
{player.name} ({player.currentElo})
))}
) }