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

68 lines
1.9 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import Card from '@/components/ui/Card';
import StandingsTable from '@/components/leagues/StandingsTable';
import {
EntityMappers,
type DriverDTO,
type LeagueDriverSeasonStatsDTO,
} from '@gridpilot/racing';
import { getGetLeagueDriverSeasonStatsQuery, getDriverRepository } from '@/lib/di-container';
export default function LeagueStandingsPage({ params }: any) {
const leagueId = params.id;
const [standings, setStandings] = useState<LeagueDriverSeasonStatsDTO[]>([]);
const [drivers, setDrivers] = useState<DriverDTO[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const loadData = async () => {
try {
const getLeagueDriverSeasonStatsQuery = getGetLeagueDriverSeasonStatsQuery();
const driverRepo = getDriverRepository();
const leagueStandings = await getLeagueDriverSeasonStatsQuery.execute({ leagueId });
setStandings(leagueStandings);
const allDrivers = await driverRepo.findAll();
const driverDtos: DriverDTO[] = allDrivers
.map((driver) => EntityMappers.toDriverDTO(driver))
.filter((dto): dto is DriverDTO => dto !== null);
setDrivers(driverDtos);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to load standings');
} finally {
setLoading(false);
}
};
useEffect(() => {
loadData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [leagueId]);
if (loading) {
return (
<div className="text-center text-gray-400">
Loading standings...
</div>
);
}
if (error) {
return (
<div className="text-center text-warning-amber">
{error}
</div>
);
}
return (
<Card>
<h2 className="text-xl font-semibold text-white mb-4">Standings</h2>
<StandingsTable standings={standings} drivers={drivers} leagueId={leagueId} />
</Card>
);
}