Files
gridpilot.gg/apps/website/app/drivers/[id]/page.tsx
2025-12-06 00:17:24 +01:00

148 lines
4.2 KiB
TypeScript

'use client';
import { useState, useEffect, use } from 'react';
import Link from 'next/link';
import { useRouter, useParams } from 'next/navigation';
import { getDriverRepository } from '@/lib/di-container';
import DriverProfile from '@/components/drivers/DriverProfile';
import Button from '@/components/ui/Button';
import Card from '@/components/ui/Card';
import Breadcrumbs from '@/components/layout/Breadcrumbs';
import { EntityMappers } from '@gridpilot/racing';
import type { DriverDTO } from '@gridpilot/racing';
export default function DriverDetailPage({
searchParams,
}: {
searchParams: any;
}) {
const router = useRouter();
const params = useParams();
const driverId = params.id as string;
const [driver, setDriver] = useState<DriverDTO | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const unwrappedSearchParams = use(searchParams) as URLSearchParams | undefined;
const from =
typeof unwrappedSearchParams?.get === 'function'
? unwrappedSearchParams.get('from') ?? undefined
: undefined;
const leagueId =
typeof unwrappedSearchParams?.get === 'function'
? unwrappedSearchParams.get('leagueId') ?? undefined
: undefined;
const raceId =
typeof unwrappedSearchParams?.get === 'function'
? unwrappedSearchParams.get('raceId') ?? undefined
: undefined;
let backLink: string | null = null;
if (from === 'league-standings' && leagueId) {
backLink = `/leagues/${leagueId}/standings`;
} else if (from === 'league' && leagueId) {
backLink = `/leagues/${leagueId}`;
} else if (from === 'league-members' && leagueId) {
backLink = `/leagues/${leagueId}`;
} else if (from === 'league-race' && leagueId && raceId) {
backLink = `/leagues/${leagueId}/races/${raceId}`;
} else {
backLink = null;
}
useEffect(() => {
loadDriver();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [driverId]);
const loadDriver = async () => {
try {
const driverRepo = getDriverRepository();
const driverEntity = await driverRepo.findById(driverId);
if (!driverEntity) {
setError('Driver not found');
setLoading(false);
return;
}
const driverDto = EntityMappers.toDriverDTO(driverEntity);
if (!driverDto) {
setError('Driver not found');
setLoading(false);
return;
}
setDriver(driverDto);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to load driver');
} finally {
setLoading(false);
}
};
if (loading) {
return (
<div className="min-h-screen bg-deep-graphite py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-6xl mx-auto">
<div className="text-center text-gray-400">Loading driver profile...</div>
</div>
</div>
);
}
if (error || !driver) {
return (
<div className="min-h-screen bg-deep-graphite py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-4xl mx-auto">
<Card className="text-center py-12">
<div className="text-warning-amber mb-4">
{error || 'Driver not found'}
</div>
<Button
variant="secondary"
onClick={() => router.push('/drivers')}
>
Back to Drivers
</Button>
</Card>
</div>
</div>
);
}
return (
<div className="min-h-screen bg-deep-graphite py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-6xl mx-auto">
{backLink && (
<div className="mb-4">
<Link
href={backLink}
className="inline-flex items-center text-xs font-medium text-gray-300 hover:text-white"
>
Back to league
</Link>
</div>
)}
{/* Breadcrumb */}
<Breadcrumbs
items={[
{ label: 'Home', href: '/' },
{ label: 'Drivers', href: '/drivers' },
{ label: driver.name }
]}
/>
{/* Driver Profile Component */}
<DriverProfile driver={driver} isOwnProfile={false} />
</div>
</div>
);
}