'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 (
{[1, 2, 3, 4, 5].map(i => (
))}
); } return (
{/* Breadcrumbs */} {/* Header */}
All Races

{filteredRaces.length} race{filteredRaces.length !== 1 ? 's' : ''} found

{/* Search & Filters */}
{/* Search */}
setSearchQuery(e.target.value)} placeholder="Search by track, car, or league..." className="w-full pl-10 pr-4 py-2.5 bg-deep-graphite border border-charcoal-outline rounded-lg text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-primary-blue" />
{/* Filter Row */}
{/* Status Filter */} {/* League Filter */} {/* Clear Filters */} {(statusFilter !== 'all' || leagueFilter !== 'all' || searchQuery) && ( )}
{/* Race List */} {paginatedRaces.length === 0 ? (

No races found

{races.length === 0 ? 'No races have been scheduled yet' : 'Try adjusting your search or filters'}

) : (
{paginatedRaces.map(race => { const config = statusConfig[race.status as keyof typeof statusConfig]; const StatusIcon = config.icon; return (
onRaceClick(race.id)} className={`group relative overflow-hidden rounded-xl bg-iron-gray border ${config.border} p-4 cursor-pointer transition-all duration-200 hover:scale-[1.01] hover:border-primary-blue`} > {/* Live indicator */} {race.status === 'running' && (
)}
{/* Date Column */}

{new Date(race.scheduledAt).toLocaleDateString('en-US', { month: 'short' })}

{new Date(race.scheduledAt).getDate()}

{formatTime(race.scheduledAt)}

{/* Divider */}
{/* Main Content */}

{race.track}

{race.car} {race.strengthOfField && ( SOF {race.strengthOfField} )} {formatDate(race.scheduledAt)}
e.stopPropagation()} className="inline-flex items-center gap-1.5 mt-2 text-sm text-primary-blue hover:underline" > {race.leagueName}
{/* Status Badge */}
{config.label}
{/* Arrow */}
); })}
)} {/* Pagination */} {/* Filter Modal */} setShowFilterModal(false)} statusFilter={statusFilter} setStatusFilter={setStatusFilter} leagueFilter={leagueFilter} setLeagueFilter={setLeagueFilter} timeFilter="all" setTimeFilter={() => {}} searchQuery={searchQuery} setSearchQuery={setSearchQuery} leagues={[...new Set(races.map(r => ({ id: r.leagueId || '', name: r.leagueName || '' })))]} showSearch={true} showTimeFilter={false} />
); }