'use client'; import { useState, useEffect } from 'react'; import { useParams, useRouter } from 'next/navigation'; import { RaceDetailTemplate } from '@/templates/RaceDetailTemplate'; import { useRaceDetail, useRegisterForRace, useWithdrawFromRace, useCancelRace, useCompleteRace, useReopenRace } from '@/hooks/useRaceService'; import { useLeagueMembership } from '@/hooks/useLeagueMembershipService'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { LeagueMembershipUtility } from '@/lib/utilities/LeagueMembershipUtility'; export function RaceDetailInteractive() { const router = useRouter(); const params = useParams(); const raceId = params.id as string; const currentDriverId = useEffectiveDriverId(); // Fetch data const { data: viewModel, isLoading, error } = useRaceDetail(raceId, currentDriverId); const { data: membership } = useLeagueMembership(viewModel?.league?.id || '', currentDriverId); // UI State const [showProtestModal, setShowProtestModal] = useState(false); const [showEndRaceModal, setShowEndRaceModal] = useState(false); // Mutations const registerMutation = useRegisterForRace(); const withdrawMutation = useWithdrawFromRace(); const cancelMutation = useCancelRace(); const completeMutation = useCompleteRace(); const reopenMutation = useReopenRace(); // Determine if user is owner/admin const isOwnerOrAdmin = membership ? LeagueMembershipUtility.isOwnerOrAdmin(viewModel?.league?.id || '', currentDriverId) : false; // Actions const handleBack = () => { router.back(); }; const handleRegister = async () => { const race = viewModel?.race; const league = viewModel?.league; if (!race || !league) return; const confirmed = window.confirm( `Register for ${race.track}?\n\nYou'll be added to the entry list for this race.`, ); if (!confirmed) return; try { await registerMutation.mutateAsync({ raceId: race.id, leagueId: league.id, driverId: currentDriverId }); } catch (err) { alert(err instanceof Error ? err.message : 'Failed to register for race'); } }; const handleWithdraw = async () => { const race = viewModel?.race; const league = viewModel?.league; if (!race || !league) return; const confirmed = window.confirm( 'Withdraw from this race?\n\nYou can register again later if you change your mind.', ); if (!confirmed) return; try { await withdrawMutation.mutateAsync({ raceId: race.id, driverId: currentDriverId }); } catch (err) { alert(err instanceof Error ? err.message : 'Failed to withdraw from race'); } }; const handleCancel = async () => { const race = viewModel?.race; if (!race || race.status !== 'scheduled') return; const confirmed = window.confirm( 'Are you sure you want to cancel this race? This action cannot be undone.', ); if (!confirmed) return; try { await cancelMutation.mutateAsync(race.id); } catch (err) { alert(err instanceof Error ? err.message : 'Failed to cancel race'); } }; const handleReopen = async () => { const race = viewModel?.race; if (!race || !viewModel?.canReopenRace) return; const confirmed = window.confirm( 'Re-open this race? This will allow re-registration and re-running. Results will be archived.', ); if (!confirmed) return; try { await reopenMutation.mutateAsync(race.id); } catch (err) { alert(err instanceof Error ? err.message : 'Failed to re-open race'); } }; const handleEndRace = async () => { const race = viewModel?.race; if (!race) return; setShowEndRaceModal(true); }; const handleFileProtest = () => { setShowProtestModal(true); }; const handleResultsClick = () => { router.push(`/races/${raceId}/results`); }; const handleStewardingClick = () => { router.push(`/races/${raceId}/stewarding`); }; const handleLeagueClick = (leagueId: string) => { router.push(`/leagues/${leagueId}`); }; const handleDriverClick = (driverId: string) => { router.push(`/drivers/${driverId}`); }; // Transform data for template - handle null values const templateViewModel = viewModel && viewModel.race ? { race: { id: viewModel.race.id, track: viewModel.race.track, car: viewModel.race.car, scheduledAt: viewModel.race.scheduledAt, status: viewModel.race.status as 'scheduled' | 'running' | 'completed' | 'cancelled', sessionType: viewModel.race.sessionType, }, league: viewModel.league ? { id: viewModel.league.id, name: viewModel.league.name, description: viewModel.league.description || undefined, settings: viewModel.league.settings as { maxDrivers: number; qualifyingFormat: string }, } : undefined, entryList: viewModel.entryList.map(entry => ({ id: entry.id, name: entry.name, avatarUrl: entry.avatarUrl, country: entry.country, rating: entry.rating, isCurrentUser: entry.isCurrentUser, })), registration: { isUserRegistered: viewModel.registration.isUserRegistered, canRegister: viewModel.registration.canRegister, }, userResult: viewModel.userResult ? { position: viewModel.userResult.position, startPosition: viewModel.userResult.startPosition, positionChange: viewModel.userResult.positionChange, incidents: viewModel.userResult.incidents, isClean: viewModel.userResult.isClean, isPodium: viewModel.userResult.isPodium, ratingChange: viewModel.userResult.ratingChange, } : undefined, canReopenRace: viewModel.canReopenRace, } : undefined; return ( ); }