110 lines
4.1 KiB
TypeScript
110 lines
4.1 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { useParams, useRouter } from 'next/navigation';
|
|
import { RaceResultsTemplate } from '@/templates/RaceResultsTemplate';
|
|
import { useRaceResultsDetail, useRaceWithSOF } from '@/hooks/useRaceService';
|
|
import { useLeagueMembership } from '@/hooks/useLeagueMembershipService';
|
|
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
|
|
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
|
|
|
|
export function RaceResultsInteractive() {
|
|
const router = useRouter();
|
|
const params = useParams();
|
|
const raceId = params.id as string;
|
|
const currentDriverId = useEffectiveDriverId();
|
|
|
|
// Fetch data
|
|
const { data: raceData, isLoading, error } = useRaceResultsDetail(raceId, currentDriverId);
|
|
const { data: sofData } = useRaceWithSOF(raceId);
|
|
const { data: membership } = useLeagueMembership(raceData?.league?.id || '', currentDriverId);
|
|
|
|
// UI State
|
|
const [importing, setImporting] = useState(false);
|
|
const [importSuccess, setImportSuccess] = useState(false);
|
|
const [importError, setImportError] = useState<string | null>(null);
|
|
const [showImportForm, setShowImportForm] = useState(false);
|
|
|
|
const raceSOF = sofData?.strengthOfField || null;
|
|
const isAdmin = membership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(membership.role) : false;
|
|
|
|
// Transform data for template
|
|
const results = raceData?.results.map(result => ({
|
|
position: result.position,
|
|
driverId: result.driverId,
|
|
driverName: result.driverName,
|
|
driverAvatar: result.avatarUrl,
|
|
country: 'US', // Default since view model doesn't have country
|
|
car: 'Unknown', // Default since view model doesn't have car
|
|
laps: 0, // Default since view model doesn't have laps
|
|
time: '0:00.00', // Default since view model doesn't have time
|
|
fastestLap: result.fastestLap.toString(), // Convert number to string
|
|
points: 0, // Default since view model doesn't have points
|
|
incidents: result.incidents,
|
|
isCurrentUser: result.driverId === currentDriverId,
|
|
})) ?? [];
|
|
|
|
const penalties = raceData?.penalties.map(penalty => ({
|
|
driverId: penalty.driverId,
|
|
driverName: raceData.results.find(r => r.driverId === penalty.driverId)?.driverName || 'Unknown',
|
|
type: penalty.type as 'time_penalty' | 'grid_penalty' | 'points_deduction' | 'disqualification' | 'warning' | 'license_points',
|
|
value: penalty.value || 0,
|
|
reason: 'Penalty applied', // Default since view model doesn't have reason
|
|
notes: undefined, // Default since view model doesn't have notes
|
|
})) ?? [];
|
|
|
|
// Actions
|
|
const handleBack = () => {
|
|
router.back();
|
|
};
|
|
|
|
const handleImportResults = async (importedResults: any[]) => {
|
|
setImporting(true);
|
|
setImportError(null);
|
|
|
|
try {
|
|
// TODO: Implement race results service
|
|
// await raceResultsService.importRaceResults(raceId, {
|
|
// resultsFileContent: JSON.stringify(importedResults),
|
|
// });
|
|
|
|
setImportSuccess(true);
|
|
// await loadData();
|
|
} catch (err) {
|
|
setImportError(err instanceof Error ? err.message : 'Failed to import results');
|
|
} finally {
|
|
setImporting(false);
|
|
}
|
|
};
|
|
|
|
const handlePenaltyClick = (driver: { id: string; name: string }) => {
|
|
// This would open a penalty modal in a real implementation
|
|
console.log('Penalty click for:', driver);
|
|
};
|
|
|
|
return (
|
|
<RaceResultsTemplate
|
|
raceTrack={raceData?.race?.track}
|
|
raceScheduledAt={raceData?.race?.scheduledAt}
|
|
totalDrivers={raceData?.stats.totalDrivers}
|
|
leagueName={raceData?.league?.name}
|
|
raceSOF={raceSOF}
|
|
results={results}
|
|
penalties={penalties}
|
|
pointsSystem={raceData?.pointsSystem ?? {}}
|
|
fastestLapTime={raceData?.fastestLapTime ?? 0}
|
|
currentDriverId={currentDriverId}
|
|
isAdmin={isAdmin}
|
|
isLoading={isLoading}
|
|
error={error}
|
|
onBack={handleBack}
|
|
onImportResults={handleImportResults}
|
|
onPenaltyClick={handlePenaltyClick}
|
|
importing={importing}
|
|
importSuccess={importSuccess}
|
|
importError={importError}
|
|
showImportForm={showImportForm}
|
|
setShowImportForm={setShowImportForm}
|
|
/>
|
|
);
|
|
} |