'use client'; import { useRegisterForRace } from "@/hooks/race/useRegisterForRace"; import { useWithdrawFromRace } from "@/hooks/race/useWithdrawFromRace"; import { useEffectiveDriverId } from "@/hooks/useEffectiveDriverId"; import type { LeagueScheduleRaceViewModel } from '@/lib/view-models/LeagueScheduleViewModel'; import { useState } from 'react'; // Shared state components import { StateContainer } from '@/components/shared/state/StateContainer'; import { useLeagueSchedule } from "@/hooks/league/useLeagueSchedule"; import { Button } from '@/ui/Button'; import { Heading } from '@/ui/Heading'; import { Stack } from '@/ui/Stack'; import { Text } from '@/ui/Text'; import { Calendar } from 'lucide-react'; interface LeagueScheduleProps { leagueId: string; onRaceClick?: (raceId: string) => void; } export function LeagueSchedule({ leagueId, onRaceClick }: LeagueScheduleProps) { const [filter, setFilter] = useState<'all' | 'upcoming' | 'past'>('upcoming'); const currentDriverId = useEffectiveDriverId(); const { data: schedule, isLoading, error, retry } = useLeagueSchedule(leagueId); const registerMutation = useRegisterForRace(); const withdrawMutation = useWithdrawFromRace(); const handleRegister = async (race: LeagueScheduleRaceViewModel, e: React.MouseEvent) => { e.stopPropagation(); const confirmed = window.confirm(`Register for ${race.track ?? race.name}?`); if (!confirmed) return; if (!currentDriverId) return; try { await registerMutation.mutateAsync({ raceId: race.id, leagueId, driverId: currentDriverId }); } catch (err) { alert(err instanceof Error ? err.message : 'Failed to register'); } }; const handleWithdraw = async (race: LeagueScheduleRaceViewModel, e: React.MouseEvent) => { e.stopPropagation(); const confirmed = window.confirm('Withdraw from this race?'); if (!confirmed) return; if (!currentDriverId) return; try { await withdrawMutation.mutateAsync({ raceId: race.id, driverId: currentDriverId }); } catch (err) { alert(err instanceof Error ? err.message : 'Failed to withdraw'); } }; return ( {(scheduleData) => { const races = scheduleData?.races ?? []; const upcomingRaces = races.filter((race) => race.isUpcoming); const pastRaces = races.filter((race) => race.isPast); const getDisplayRaces = () => { switch (filter) { case 'upcoming': return upcomingRaces; case 'past': // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation return [...pastRaces].reverse(); case 'all': // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation return [...upcomingRaces, ...[...pastRaces].reverse()]; default: return races; } }; const displayRaces = getDisplayRaces(); return ( {/* Filter Controls */} {displayRaces.length} {displayRaces.length === 1 ? 'race' : 'races'} {/* Race List */} {displayRaces.length === 0 ? ( No {filter} races {filter === 'upcoming' && ( Schedule your first race to get started )} ) : ( {displayRaces.map((race) => { const isPast = race.isPast; const isUpcoming = race.isUpcoming; const isRegistered = Boolean(race.isRegistered); const trackLabel = race.track ?? race.name; const carLabel = race.car ?? '—'; const sessionTypeLabel = (race.sessionType ?? 'race').toLowerCase(); const isProcessing = registerMutation.isPending || withdrawMutation.isPending; return ( onRaceClick?.(race.id)} > {trackLabel} {isUpcoming && !isRegistered && ( Upcoming )} {isUpcoming && isRegistered && ( ✓ Registered )} {isPast && ( Completed )} {carLabel} {sessionTypeLabel} {race.formattedDate} {race.formattedTime} {isPast && race.status === 'completed' && ( View Results → )} {/* Registration Actions */} {isUpcoming && ( e.stopPropagation()}> {!isRegistered ? ( ) : ( )} )} ); })} )} ); }} ); }