import { LeagueSummaryCard } from '@/components/leagues/LeagueSummaryCardWrapper'; import { EntrantsTable } from '@/components/races/EntrantsTable'; import { RaceActionBar } from '@/components/races/RaceActionBar'; import { RaceDetailsHeader } from '@/components/races/RaceDetailsHeader'; import { RaceUserResult } from '@/components/races/RaceUserResultWrapper'; import type { SessionStatus } from '@/components/races/SessionStatusBadge'; import { TrackConditionsPanel } from '@/components/races/TrackConditionsPanel'; import { ViewData } from '@/lib/contracts/view-data/ViewData'; import { Box } from '@/ui/Box'; import { Container } from '@/ui/Container'; import { Grid } from '@/ui/Grid'; import { GridItem } from '@/ui/GridItem'; import { Skeleton } from '@/ui/Skeleton'; import { Stack } from '@/ui/Stack'; import { Text } from '@/ui/Text'; export interface RaceDetailEntryViewModel { id: string; name: string; avatarUrl: string; country: string; rating?: number | null; isCurrentUser: boolean; } export interface RaceDetailUserResultViewModel { position: number; startPosition: number; positionChange: number; incidents: number; isClean: boolean; isPodium: boolean; ratingChange?: number; } export interface RaceDetailLeague { id: string; name: string; description?: string; settings: { maxDrivers: number; qualifyingFormat: string; }; } export interface RaceDetailRace { id: string; track: string; car: string; scheduledAt: string; status: 'scheduled' | 'running' | 'completed' | 'cancelled'; sessionType: string; } export interface RaceDetailRegistration { isUserRegistered: boolean; canRegister: boolean; } export interface RaceDetailViewData extends ViewData { race: RaceDetailRace; league?: RaceDetailLeague; entryList: RaceDetailEntryViewModel[]; registration: RaceDetailRegistration; userResult?: RaceDetailUserResultViewModel; canReopenRace: boolean; } export interface RaceDetailTemplateProps { viewData?: RaceDetailViewData; isLoading: boolean; error?: Error | null; // Actions onBack: () => void; onRegister: () => void; onWithdraw: () => void; onCancel: () => void; onReopen: () => void; onEndRace: () => void; onFileProtest: () => void; onResultsClick: () => void; onStewardingClick: () => void; onLeagueClick: (leagueId: string) => void; onDriverClick: (driverId: string) => void; // User state currentDriverId?: string; isOwnerOrAdmin?: boolean; // UI State animatedRatingChange: number; // Loading states mutationLoading?: { register?: boolean; withdraw?: boolean; cancel?: boolean; reopen?: boolean; complete?: boolean; }; } export function RaceDetailTemplate({ viewData, isLoading, error, onBack, onRegister, onWithdraw, onCancel, onReopen, onEndRace, onFileProtest, onResultsClick, onStewardingClick, isOwnerOrAdmin = false, animatedRatingChange, mutationLoading = {}, }: RaceDetailTemplateProps) { if (isLoading) { return ( ); } if (error || !viewData || !viewData.race) { return ( Race Not Found {`The race you're looking for doesn't exist or has been removed.`} Back to Schedule ); } const { race, league, entryList, userResult } = viewData; return ( {userResult && ( )} Entry List ({ id: entry.id, name: entry.name, carName: race.car, rating: entry.rating || 0, status: 'confirmed' }))} /> {league && } Session Info Format {race.sessionType} Car Class {race.car} ); }