'use client'; import { useState, useMemo } from 'react'; import { useRouter } from 'next/navigation'; import { RacesIndexTemplate } from '@/templates/RacesIndexTemplate'; import { useAllRacesPageData } from '@/hooks/race/useAllRacesPageData'; import type { RacesViewData, RaceViewData } from '@/lib/view-data/RacesViewData'; import { ClientWrapperProps } from '@/lib/contracts/components/ComponentContracts'; import { StatefulPageWrapper } from '@/components/shared/state/StatefulPageWrapper'; import { Flag } from 'lucide-react'; export function RacesAllPageClient({ viewData: initialViewData }: ClientWrapperProps) { const router = useRouter(); const [statusFilter, setStatusFilter] = useState('all'); const [leagueFilter, setLeagueFilter] = useState('all'); const [timeFilter, setTimeFilter] = useState('upcoming'); const [showFilterModal, setShowFilterModal] = useState(false); // Use React Query hook const { data: pageData, isLoading, error, refetch } = useAllRacesPageData(initialViewData); const filteredRaces = useMemo(() => { const now = new Date(); const races: RaceViewData[] = pageData?.races ?? []; return races.filter((race) => { if (statusFilter !== 'all' && race.status.toLowerCase() !== statusFilter.toLowerCase()) return false; if (leagueFilter !== 'all' && race.leagueId !== leagueFilter) return false; const scheduledAt = new Date(race.scheduledAt); const isActuallyUpcoming = scheduledAt > now && race.status.toLowerCase() === 'scheduled'; const isActuallyLive = race.status.toLowerCase() === 'running'; const isActuallyPast = scheduledAt < now || race.status.toLowerCase() === 'completed' || race.status.toLowerCase() === 'cancelled'; if (timeFilter === 'upcoming' && !isActuallyUpcoming) return false; if (timeFilter === 'live' && !isActuallyLive) return false; if (timeFilter === 'past' && !isActuallyPast) return false; return true; }); }, [pageData?.races, statusFilter, leagueFilter, timeFilter]); const nextUpRace = useMemo(() => { const now = new Date(); return filteredRaces.find(r => new Date(r.scheduledAt) > now && r.status.toLowerCase() === 'scheduled'); }, [filteredRaces]); const racesByDate = useMemo(() => { const grouped = new Map(); filteredRaces.forEach((race) => { const dateKey = race.scheduledAt.split('T')[0]!; if (!grouped.has(dateKey)) { grouped.set(dateKey, []); } grouped.get(dateKey)!.push(race); }); return Array.from(grouped.entries()) .sort(([a], [b]) => timeFilter === 'past' ? b.localeCompare(a) : a.localeCompare(b)) .map(([dateKey, dayRaces]) => ({ dateKey, dateLabel: dayRaces[0]?.scheduledAtLabel || '', races: dayRaces, })); }, [filteredRaces, timeFilter]); return ( pageData ? ( router.push(`/races/${id}`)} /> ) : null} 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', }} /> ); }