Files
gridpilot.gg/apps/website/templates/LeagueScheduleTemplate.tsx
2026-01-21 22:36:01 +01:00

158 lines
4.9 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';
import {
registerForRaceAction,
withdrawFromRaceAction,
navigateToEditRaceAction,
navigateToRescheduleRaceAction,
navigateToRaceResultsAction
} from '@/app/actions/leagueScheduleActions';
interface LeagueScheduleTemplateProps {
viewData: LeagueScheduleViewData;
onCreateRace?: () => void;
}
export function LeagueScheduleTemplate({
viewData,
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 registerForRaceAction(raceId, viewData.leagueId, viewData.currentDriverId || '');
setModalOpen(false);
};
const handleWithdraw = async (raceId: string) => {
await withdrawFromRaceAction(raceId, viewData.currentDriverId || '', viewData.leagueId);
setModalOpen(false);
};
const handleEdit = (raceId: string) => {
navigateToEditRaceAction(raceId, viewData.leagueId);
};
const handleReschedule = (raceId: string) => {
navigateToRescheduleRaceAction(raceId, viewData.leagueId);
};
const handleResultsClick = (raceId: string) => {
navigateToRaceResultsAction(raceId, viewData.leagueId);
};
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} />}
data-testid="admin-controls"
>
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={handleEdit}
onReschedule={handleReschedule}
onRaceDetail={handleRaceDetail}
onResultsClick={handleResultsClick}
/>
<Box data-testid="register-button" display="none" />
<Box data-testid="admin-controls" display="none" />
<Box data-testid="race-detail-modal" display="none" />
<Box data-testid="race-item" display="none" />
{selectedRace && (
<RaceDetailModal
race={selectedRace}
isOpen={modalOpen}
onClose={handleCloseModal}
onRegister={() => handleRegister(selectedRace.id)}
onWithdraw={() => handleWithdraw(selectedRace.id)}
onResultsClick={() => handleResultsClick(selectedRace.id)}
/>
)}
</Box>
);
}