'use client'; import { useState } from 'react'; import Modal from '@/components/ui/Modal'; import Button from '@/components/ui/Button'; import type { FileProtestCommandDTO } from '@/lib/types/generated/FileProtestCommandDTO'; import type { ProtestIncidentDTO } from '@/lib/types/generated/ProtestIncidentDTO'; import { useFileProtest } from '@/hooks/race/useFileProtest'; import { AlertTriangle, Video, MessageSquare, Hash, Clock, User, FileText, CheckCircle2, } from 'lucide-react'; type ProtestParticipant = { id: string; name: string; }; interface FileProtestModalProps { isOpen: boolean; onClose: () => void; raceId: string; leagueId?: string; protestingDriverId: string; participants: ProtestParticipant[]; } export default function FileProtestModal({ isOpen, onClose, raceId, leagueId, protestingDriverId, participants, }: FileProtestModalProps) { const fileProtestMutation = useFileProtest(); const [errorMessage, setErrorMessage] = useState(null); // Form state const [accusedDriverId, setAccusedDriverId] = useState(''); const [lap, setLap] = useState(''); const [timeInRace, setTimeInRace] = useState(''); const [description, setDescription] = useState(''); const [comment, setComment] = useState(''); const [proofVideoUrl, setProofVideoUrl] = useState(''); const otherParticipants = participants.filter(p => p.id !== protestingDriverId); const handleSubmit = async () => { // Validation if (!accusedDriverId) { setErrorMessage('Please select the driver you are protesting against.'); return; } if (!lap || parseInt(lap, 10) < 0) { setErrorMessage('Please enter a valid lap number.'); return; } if (!description.trim()) { setErrorMessage('Please describe what happened.'); return; } setErrorMessage(null); const incident: ProtestIncidentDTO = { lap: parseInt(lap, 10), description: description.trim(), ...(timeInRace ? { timeInRace: parseInt(timeInRace, 10) } : {}), }; const command = { raceId, protestingDriverId, accusedDriverId, incident, ...(comment.trim() ? { comment: comment.trim() } : {}), ...(proofVideoUrl.trim() ? { proofVideoUrl: proofVideoUrl.trim() } : {}), } satisfies FileProtestCommandDTO; fileProtestMutation.mutate(command, { onSuccess: () => { // Reset form state on success setAccusedDriverId(''); setLap(''); setTimeInRace(''); setDescription(''); setComment(''); setProofVideoUrl(''); }, onError: (error) => { setErrorMessage(error.message || 'Failed to file protest'); }, }); }; const handleClose = () => { // Reset form state setErrorMessage(null); setAccusedDriverId(''); setLap(''); setTimeInRace(''); setDescription(''); setComment(''); setProofVideoUrl(''); fileProtestMutation.reset(); onClose(); }; // Show success state when mutation is successful if (fileProtestMutation.isSuccess) { return (

Your protest has been submitted

The stewards will review your protest and make a decision. You'll be notified of the outcome.

); } return (
{errorMessage && (

{errorMessage}

)} {/* Driver Selection */}
{/* Lap and Time */}
setLap(e.target.value)} disabled={fileProtestMutation.isPending} placeholder="e.g. 5" className="w-full px-3 py-2.5 bg-deep-graphite border border-charcoal-outline rounded-lg text-white text-sm focus:outline-none focus:ring-2 focus:ring-primary-blue/50 focus:border-primary-blue disabled:opacity-50" />
setTimeInRace(e.target.value)} disabled={fileProtestMutation.isPending} placeholder="Optional" className="w-full px-3 py-2.5 bg-deep-graphite border border-charcoal-outline rounded-lg text-white text-sm focus:outline-none focus:ring-2 focus:ring-primary-blue/50 focus:border-primary-blue disabled:opacity-50" />
{/* Incident Description */}