'use client'; import { useState, useEffect } from 'react'; import { useParams, useRouter } from 'next/navigation'; import { PageWrapper } from '@/components/shared/state/PageWrapper'; import { RaceStewardingTemplate, StewardingTab } from '@/templates/RaceStewardingTemplate'; import { PageDataFetcher } from '@/lib/page/PageDataFetcher'; import { RACE_STEWARDING_SERVICE_TOKEN } from '@/lib/di/tokens'; import { RaceStewardingService } from '@/lib/services/races/RaceStewardingService'; import type { RaceStewardingViewModel } from '@/lib/view-models/RaceStewardingViewModel'; import { useLeagueMemberships } from "@/lib/hooks/league/useLeagueMemberships"; import { useEffectiveDriverId } from "@/lib/hooks/useEffectiveDriverId"; import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility'; import { Gavel } from 'lucide-react'; import type { LeagueMembershipsDTO } from '@/lib/types/generated/LeagueMembershipsDTO'; export default function RaceStewardingPage() { const router = useRouter(); const params = useParams(); const raceId = params.id as string; const currentDriverId = useEffectiveDriverId() || ''; // Data state const [pageData, setPageData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // UI State const [activeTab, setActiveTab] = useState('pending'); // Fetch data on mount and when raceId/currentDriverId changes useEffect(() => { async function fetchData() { if (!raceId) return; try { setIsLoading(true); setError(null); const data = await PageDataFetcher.fetch( RACE_STEWARDING_SERVICE_TOKEN, 'getRaceStewardingData', raceId, currentDriverId ); if (data) { setPageData(data); } else { setPageData(null); } } catch (err) { setError(err instanceof Error ? err : new Error('Failed to fetch stewarding data')); setPageData(null); } finally { setIsLoading(false); } } fetchData(); }, [raceId, currentDriverId]); // Fetch membership const { data: membershipsData } = useLeagueMemberships(pageData?.league?.id || '', currentDriverId || ''); const currentMembership = membershipsData?.members.find(m => m.driverId === currentDriverId); const isAdmin = currentMembership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(currentMembership.role) : false; // Actions const handleBack = () => { router.push(`/races/${raceId}`); }; const handleReviewProtest = (protestId: string) => { // Navigate to protest review page router.push(`/leagues/${pageData?.league?.id}/stewarding/protests/${protestId}`); }; // Transform data for template const templateData = pageData ? { race: pageData.race, league: pageData.league, pendingProtests: pageData.pendingProtests, resolvedProtests: pageData.resolvedProtests, penalties: pageData.penalties, driverMap: pageData.driverMap, pendingCount: pageData.pendingCount, resolvedCount: pageData.resolvedCount, penaltiesCount: pageData.penaltiesCount, } : undefined; const retry = async () => { try { setIsLoading(true); setError(null); const data = await PageDataFetcher.fetch( RACE_STEWARDING_SERVICE_TOKEN, 'getRaceStewardingData', raceId, currentDriverId ); if (data) { setPageData(data); } } catch (err) { setError(err instanceof Error ? err : new Error('Failed to fetch stewarding data')); } finally { setIsLoading(false); } }; return ( ( )} loading={{ variant: 'skeleton', message: 'Loading stewarding data...' }} errorConfig={{ variant: 'full-screen' }} empty={{ icon: Gavel, title: 'No stewarding data', description: 'No protests or penalties for this race', action: { label: 'Back to Race', onClick: handleBack } }} /> ); }