This commit is contained in:
2025-12-11 21:06:25 +01:00
parent c49ea2598d
commit ec3ddc3a5c
227 changed files with 3496 additions and 2083 deletions

View File

@@ -3,8 +3,7 @@
import { useState } from 'react';
import Modal from '@/components/ui/Modal';
import Button from '@/components/ui/Button';
import { getFileProtestUseCase, getDriverRepository } from '@/lib/di-container';
import type { Driver } from '@gridpilot/racing/domain/entities/Driver';
import { getFileProtestUseCase } from '@/lib/di-container';
import type { ProtestIncident } from '@gridpilot/racing/domain/entities/Protest';
import {
AlertTriangle,
@@ -17,13 +16,18 @@ import {
CheckCircle2,
} from 'lucide-react';
type ProtestParticipant = {
id: string;
name: string;
};
interface FileProtestModalProps {
isOpen: boolean;
onClose: () => void;
raceId: string;
leagueId?: string;
protestingDriverId: string;
participants: Driver[];
participants: ProtestParticipant[];
}
export default function FileProtestModal({
@@ -70,18 +74,26 @@ export default function FileProtestModal({
const incident: ProtestIncident = {
lap: parseInt(lap, 10),
timeInRace: timeInRace ? parseInt(timeInRace, 10) : undefined,
description: description.trim(),
...(timeInRace
? { timeInRace: parseInt(timeInRace, 10) }
: {}),
};
await useCase.execute({
const command = {
raceId,
protestingDriverId,
accusedDriverId,
incident,
comment: comment.trim() || undefined,
proofVideoUrl: proofVideoUrl.trim() || undefined,
});
...(comment.trim()
? { comment: comment.trim() }
: {}),
...(proofVideoUrl.trim()
? { proofVideoUrl: proofVideoUrl.trim() }
: {}),
};
await useCase.execute(command);
setStep('success');
} catch (err) {

View File

@@ -39,7 +39,8 @@ export default function ImportResultsForm({ raceId, onSuccess, onError }: Import
throw new Error('CSV file is empty or invalid');
}
const header = lines[0].toLowerCase().split(',').map((h) => h.trim());
const headerLine = lines[0]!;
const header = headerLine.toLowerCase().split(',').map((h) => h.trim());
const requiredFields = ['driverid', 'position', 'fastestlap', 'incidents', 'startposition'];
for (const field of requiredFields) {
@@ -50,7 +51,11 @@ export default function ImportResultsForm({ raceId, onSuccess, onError }: Import
const rows: CSVRow[] = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',').map((v) => v.trim());
const line = lines[i];
if (!line) {
continue;
}
const values = line.split(',').map((v) => v.trim());
if (values.length !== header.length) {
throw new Error(
@@ -63,11 +68,11 @@ export default function ImportResultsForm({ raceId, onSuccess, onError }: Import
row[field] = values[index] ?? '';
});
const driverId = row.driverid;
const position = parseInt(row.position, 10);
const fastestLap = parseFloat(row.fastestlap);
const incidents = parseInt(row.incidents, 10);
const startPosition = parseInt(row.startposition, 10);
const driverId = row['driverid'] ?? '';
const position = parseInt(row['position'] ?? '', 10);
const fastestLap = parseFloat(row['fastestlap'] ?? '');
const incidents = parseInt(row['incidents'] ?? '', 10);
const startPosition = parseInt(row['startposition'] ?? '', 10);
if (!driverId || driverId.length === 0) {
throw new Error(`Row ${i}: driverId is required`);

View File

@@ -38,9 +38,9 @@ interface ResultsTableProps {
results: ResultDTO[];
drivers: DriverDTO[];
pointsSystem: Record<number, number>;
fastestLapTime?: number;
fastestLapTime?: number | undefined;
penalties?: PenaltyData[];
currentDriverId?: string;
currentDriverId?: string | undefined;
}
export default function ResultsTable({