Files
gridpilot.gg/apps/website/templates/LeagueScheduleTemplate.tsx
2026-01-21 17:50:02 +01:00

144 lines
4.2 KiB
TypeScript

'use client';
import { useState } from 'react';
import { EnhancedLeagueSchedulePanel } from '@/components/leagues/EnhancedLeagueSchedulePanel';
import { RaceDetailModal } from '@/components/leagues/RaceDetailModal';
import type { LeagueScheduleViewData } from '@/lib/view-data/leagues/LeagueScheduleViewData';
import { Box } from '@/ui/Box';
import { Text } from '@/ui/Text';
import { Button } from '@/ui/Button';
import { Icon } from '@/ui/Icon';
import { Group } from '@/ui/Group';
import { Calendar, Plus } from 'lucide-react';
import { DateDisplay } from '@/lib/display-objects/DateDisplay';
interface LeagueScheduleTemplateProps {
viewData: LeagueScheduleViewData;
onRegister: (raceId: string) => Promise<void>;
onWithdraw: (raceId: string) => Promise<void>;
onEdit: (raceId: string) => void;
onReschedule: (raceId: string) => void;
onResultsClick: (raceId: string) => void;
onCreateRace?: () => void;
}
export function LeagueScheduleTemplate({
viewData,
onRegister,
onWithdraw,
onEdit,
onReschedule,
onResultsClick,
onCreateRace
}: LeagueScheduleTemplateProps) {
const [selectedRace, setSelectedRace] = useState<{
id: string;
name: string;
track?: string;
car?: string;
sessionType?: string;
scheduledAt: string;
status: 'scheduled' | 'completed';
strengthOfField?: number;
isUserRegistered?: boolean;
canRegister?: boolean;
} | null>(null);
const [modalOpen, setModalOpen] = useState(false);
const events = viewData.races.map(race => ({
id: race.id,
name: race.name || `Race ${race.id.substring(0, 4)}`,
track: race.track || 'TBA',
car: race.car,
sessionType: race.sessionType,
scheduledAt: race.scheduledAt,
status: race.status,
strengthOfField: race.strengthOfField,
isUserRegistered: race.isUserRegistered,
canRegister: race.canRegister,
canEdit: race.canEdit,
canReschedule: race.canReschedule,
}));
const handleRaceDetail = (raceId: string) => {
const race = viewData.races.find(r => r.id === raceId);
if (race) {
setSelectedRace({
id: race.id,
name: race.name || `Race ${race.id.substring(0, 4)}`,
track: race.track,
car: race.car,
sessionType: race.sessionType,
scheduledAt: race.scheduledAt,
status: race.status,
strengthOfField: race.strengthOfField,
isUserRegistered: race.isUserRegistered,
canRegister: race.canRegister,
});
setModalOpen(true);
}
};
const handleCloseModal = () => {
setModalOpen(false);
setSelectedRace(null);
};
const handleRegister = async (raceId: string) => {
await onRegister(raceId);
setModalOpen(false);
};
const handleWithdraw = async (raceId: string) => {
await onWithdraw(raceId);
setModalOpen(false);
};
return (
<Box display="flex" flexDirection="col" gap={8}>
<Box as="header" display="flex" flexDirection="col" gap={2}>
<Group gap={3} align="center">
<Text as="h2" size="xl" weight="bold" color="text-white" uppercase letterSpacing="tight">
Race Schedule
</Text>
{viewData.isAdmin && onCreateRace && (
<Button
variant="primary"
size="sm"
onClick={onCreateRace}
icon={<Icon icon={Plus} size={3} />}
>
Add Race
</Button>
)}
</Group>
<Text size="sm" color="text-zinc-500">Upcoming and past events for this season.</Text>
</Box>
<EnhancedLeagueSchedulePanel
events={events}
leagueId={viewData.leagueId}
currentDriverId={viewData.currentDriverId}
isAdmin={viewData.isAdmin}
onRegister={handleRegister}
onWithdraw={handleWithdraw}
onEdit={onEdit}
onReschedule={onReschedule}
onRaceDetail={handleRaceDetail}
onResultsClick={onResultsClick}
/>
{selectedRace && (
<RaceDetailModal
race={selectedRace}
isOpen={modalOpen}
onClose={handleCloseModal}
onRegister={() => handleRegister(selectedRace.id)}
onWithdraw={() => handleWithdraw(selectedRace.id)}
onResultsClick={() => onResultsClick(selectedRace.id)}
/>
)}
</Box>
);
}