wip
This commit is contained in:
@@ -28,7 +28,9 @@ import {
|
||||
getGetLeagueScoringConfigQuery,
|
||||
getDriverStats,
|
||||
getAllDriverRankings,
|
||||
getGetLeagueStatsQuery,
|
||||
} from '@/lib/di-container';
|
||||
import { Zap, Users, Trophy, Calendar } from 'lucide-react';
|
||||
import { getMembership, getLeagueMembers, isOwnerOrAdmin } from '@/lib/leagueMembership';
|
||||
import { useEffectiveDriverId } from '@/lib/currentDriver';
|
||||
|
||||
@@ -42,6 +44,8 @@ export default function LeagueDetailPage() {
|
||||
const [standings, setStandings] = useState<LeagueDriverSeasonStatsDTO[]>([]);
|
||||
const [drivers, setDrivers] = useState<DriverDTO[]>([]);
|
||||
const [scoringConfig, setScoringConfig] = useState<LeagueScoringConfigDTO | null>(null);
|
||||
const [averageSOF, setAverageSOF] = useState<number | null>(null);
|
||||
const [completedRacesCount, setCompletedRacesCount] = useState<number>(0);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [activeTab, setActiveTab] = useState<
|
||||
@@ -59,6 +63,7 @@ export default function LeagueDetailPage() {
|
||||
const leagueRepo = getLeagueRepository();
|
||||
const raceRepo = getRaceRepository();
|
||||
const driverRepo = getDriverRepository();
|
||||
const leagueStatsQuery = getGetLeagueStatsQuery();
|
||||
|
||||
const leagueData = await leagueRepo.findById(leagueId);
|
||||
|
||||
@@ -91,6 +96,18 @@ export default function LeagueDetailPage() {
|
||||
.filter((dto): dto is DriverDTO => dto !== null);
|
||||
|
||||
setDrivers(driverDtos);
|
||||
|
||||
// Load league stats including average SOF from application query
|
||||
const leagueStats = await leagueStatsQuery.execute({ leagueId });
|
||||
if (leagueStats) {
|
||||
setAverageSOF(leagueStats.averageSOF);
|
||||
setCompletedRacesCount(leagueStats.completedRaces);
|
||||
} else {
|
||||
// Fallback: count completed races manually
|
||||
const leagueRaces = await raceRepo.findByLeagueId(leagueId);
|
||||
const completedRaces = leagueRaces.filter(r => r.status === 'completed');
|
||||
setCompletedRacesCount(completedRaces.length);
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to load league');
|
||||
} finally {
|
||||
@@ -292,12 +309,13 @@ export default function LeagueDetailPage() {
|
||||
<div className="pt-4 border-t border-charcoal-outline">
|
||||
<h3 className="text-white font-medium mb-3">At a glance</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 text-sm">
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-1">
|
||||
Structure
|
||||
</h4>
|
||||
<p className="text-gray-200">
|
||||
<p className="text-gray-200 flex items-center gap-1.5">
|
||||
<Users className="w-4 h-4 text-gray-500" />
|
||||
Solo • {league.settings.maxDrivers ?? 32} drivers
|
||||
</p>
|
||||
</div>
|
||||
@@ -305,22 +323,29 @@ export default function LeagueDetailPage() {
|
||||
<h4 className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-1">
|
||||
Schedule
|
||||
</h4>
|
||||
<p className="text-gray-200">
|
||||
{`? rounds • 30 min Qualifying • ${
|
||||
typeof league.settings.sessionDuration === 'number'
|
||||
? league.settings.sessionDuration
|
||||
: 40
|
||||
} min Races`}
|
||||
<p className="text-gray-200 flex items-center gap-1.5">
|
||||
<Calendar className="w-4 h-4 text-gray-500" />
|
||||
{completedRacesCount > 0 ? `${completedRacesCount} races completed` : 'Season upcoming'}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-1">
|
||||
Scoring & drops
|
||||
</h4>
|
||||
<p className="text-gray-200">
|
||||
<p className="text-gray-200 flex items-center gap-1.5">
|
||||
<Trophy className="w-4 h-4 text-gray-500" />
|
||||
{league.settings.pointsSystem.toUpperCase()}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-1">
|
||||
Avg. Strength of Field
|
||||
</h4>
|
||||
<p className="text-warning-amber font-medium flex items-center gap-1.5">
|
||||
<Zap className="w-4 h-4" />
|
||||
{averageSOF ? averageSOF : '—'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user