'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { StatefulPageWrapper } from '@/components/shared/state/StatefulPageWrapper'; import { RacesAllTemplate } from '@/templates/RacesAllTemplate'; import { RacesAllPageQuery } from '@/lib/page-queries/races/RacesAllPageQuery'; import { Flag } from 'lucide-react'; const ITEMS_PER_PAGE = 10; interface Race { id: string; track: string; car: string; scheduledAt: string; status: 'scheduled' | 'running' | 'completed' | 'cancelled'; sessionType: string; leagueId?: string; leagueName?: string; strengthOfField?: number; } export default function RacesAllPage() { const router = useRouter(); // Client-side state for filters and pagination const [currentPage, setCurrentPage] = useState(1); const [statusFilter, setStatusFilter] = useState<'scheduled' | 'running' | 'completed' | 'cancelled' | 'all'>('all'); const [leagueFilter, setLeagueFilter] = useState('all'); const [searchQuery, setSearchQuery] = useState(''); const [showFilters, setShowFilters] = useState(false); const [showFilterModal, setShowFilterModal] = useState(false); // Data state const [pageData, setPageData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // Fetch data const fetchData = async () => { setIsLoading(true); setError(null); try { const result = await RacesAllPageQuery.execute(); if (result.isErr()) { throw new Error('Failed to fetch races'); } setPageData(result.unwrap()); } catch (err) { setError(err instanceof Error ? err : new Error('Unknown error')); } finally { setIsLoading(false); } }; // Fetch on mount useEffect(() => { fetchData(); }, []); // Transform data const races: Race[] = pageData?.races.map((race: any) => ({ id: race.id, track: race.track, car: race.car, scheduledAt: race.scheduledAt, status: race.status as 'scheduled' | 'running' | 'completed' | 'cancelled', sessionType: 'race', leagueId: race.leagueId, leagueName: race.leagueName, strengthOfField: race.strengthOfField ?? undefined, })) ?? []; // Filter and paginate (Note: This should be done by API per contract) const filteredRaces = races.filter((race: Race) => { if (statusFilter !== 'all' && race.status !== statusFilter) { return false; } if (leagueFilter !== 'all' && race.leagueId !== leagueFilter) { return false; } if (searchQuery) { const query = searchQuery.toLowerCase(); const matchesTrack = race.track.toLowerCase().includes(query); const matchesCar = race.car.toLowerCase().includes(query); const matchesLeague = race.leagueName?.toLowerCase().includes(query); if (!matchesTrack && !matchesCar && !matchesLeague) { return false; } } return true; }); const totalPages = Math.ceil(filteredRaces.length / ITEMS_PER_PAGE); const paginatedRaces = filteredRaces.slice((currentPage - 1) * ITEMS_PER_PAGE, currentPage * ITEMS_PER_PAGE); // Actions const handleRaceClick = (raceId: string) => { router.push(`/races/${raceId}`); }; const handleLeagueClick = (leagueId: string) => { router.push(`/leagues/${leagueId}`); }; const handlePageChange = (page: number) => { setCurrentPage(page); }; return ( ( )} loading={{ variant: 'skeleton', message: 'Loading races...' }} errorConfig={{ variant: 'full-screen' }} empty={{ icon: Flag, title: 'No races found', description: 'There are no races available at the moment', }} /> ); }