'use client'; import { useMemo, useEffect } from 'react'; import Link from 'next/link'; import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; import Heading from '@/components/ui/Heading'; import Breadcrumbs from '@/components/layout/Breadcrumbs'; import { Calendar, Clock, Flag, ChevronRight, ChevronLeft, Car, Trophy, Zap, PlayCircle, CheckCircle2, XCircle, Search, SlidersHorizontal, } from 'lucide-react'; import { RaceFilterModal } from '@/components/races/RaceFilterModal'; import { RacePagination } from '@/components/races/RacePagination'; export type StatusFilter = 'scheduled' | 'running' | 'completed' | 'cancelled' | 'all'; export interface Race { id: string; track: string; car: string; scheduledAt: string; status: 'scheduled' | 'running' | 'completed' | 'cancelled'; sessionType: string; leagueId?: string; leagueName?: string; strengthOfField?: number | null; } export interface RacesAllTemplateProps { races: Race[]; isLoading: boolean; // Pagination currentPage: number; totalPages: number; itemsPerPage: number; onPageChange: (page: number) => void; // Filters statusFilter: StatusFilter; setStatusFilter: (filter: StatusFilter) => void; leagueFilter: string; setLeagueFilter: (filter: string) => void; searchQuery: string; setSearchQuery: (query: string) => void; // UI State showFilters: boolean; setShowFilters: (show: boolean) => void; showFilterModal: boolean; setShowFilterModal: (show: boolean) => void; // Actions onRaceClick: (raceId: string) => void; onLeagueClick: (leagueId: string) => void; } export function RacesAllTemplate({ races, isLoading, currentPage, totalPages, itemsPerPage, onPageChange, statusFilter, setStatusFilter, leagueFilter, setLeagueFilter, searchQuery, setSearchQuery, showFilters, setShowFilters, showFilterModal, setShowFilterModal, onRaceClick, onLeagueClick, }: RacesAllTemplateProps) { // Filter races const filteredRaces = useMemo(() => { return races.filter(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; }); }, [races, statusFilter, leagueFilter, searchQuery]); // Paginate const paginatedRaces = useMemo(() => { const start = (currentPage - 1) * itemsPerPage; return filteredRaces.slice(start, start + itemsPerPage); }, [filteredRaces, currentPage, itemsPerPage]); // Reset page when filters change useEffect(() => { onPageChange(1); }, [statusFilter, leagueFilter, searchQuery]); const formatDate = (date: Date | string) => { const d = typeof date === 'string' ? new Date(date) : date; return d.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', }); }; const formatTime = (date: Date | string) => { const d = typeof date === 'string' ? new Date(date) : date; return d.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', }); }; const statusConfig = { scheduled: { icon: Clock, color: 'text-primary-blue', bg: 'bg-primary-blue/10', border: 'border-primary-blue/30', label: 'Scheduled', }, running: { icon: PlayCircle, color: 'text-performance-green', bg: 'bg-performance-green/10', border: 'border-performance-green/30', label: 'LIVE', }, completed: { icon: CheckCircle2, color: 'text-gray-400', bg: 'bg-gray-500/10', border: 'border-gray-500/30', label: 'Completed', }, cancelled: { icon: XCircle, color: 'text-warning-amber', bg: 'bg-warning-amber/10', border: 'border-warning-amber/30', label: 'Cancelled', }, }; const breadcrumbItems = [ { label: 'Races', href: '/races' }, { label: 'All Races' }, ]; if (isLoading) { return (
{filteredRaces.length} race{filteredRaces.length !== 1 ? 's' : ''} found
No races found
{races.length === 0 ? 'No races have been scheduled yet' : 'Try adjusting your search or filters'}
{new Date(race.scheduledAt).toLocaleDateString('en-US', { month: 'short' })}
{new Date(race.scheduledAt).getDate()}
{formatTime(race.scheduledAt)}