'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 { useFileProtest } from "@/lib/hooks/race/useFileProtest"; import { AlertTriangle, Video, MessageSquare, Hash, Clock, User, FileText, CheckCircle2, } from 'lucide-react'; import { useInject } from '@/lib/di/hooks/useInject'; import { PROTEST_SERVICE_TOKEN } from '@/lib/di/tokens'; import type { ProtestParticipant } from '@/lib/services/protests/ProtestService'; 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); const protestService = useInject(PROTEST_SERVICE_TOKEN); // 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 () => { try { // Use ProtestService for validation and command construction const command = protestService.constructFileProtestCommand({ raceId, leagueId, protestingDriverId, accusedDriverId, lap, timeInRace, description, comment, proofVideoUrl, }); setErrorMessage(null); // Use existing hook for the actual API call fileProtestMutation.mutate(command, { onSuccess: () => { // Reset form state on success setAccusedDriverId(''); setLap(''); setTimeInRace(''); setDescription(''); setComment(''); setProofVideoUrl(''); }, onError: (error) => { setErrorMessage(error.message || 'Failed to file protest'); }, }); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Failed to validate protest input'; setErrorMessage(errorMessage); } }; 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 */}