Files
gridpilot.gg/apps/website/lib/view-models/RaceResultsDetailViewModel.ts
2026-01-23 15:30:23 +01:00

58 lines
2.2 KiB
TypeScript

import { ViewModel } from "../contracts/view-models/ViewModel";
import { RaceResultViewModel } from './RaceResultViewModel';
import type { RaceResultsDetailViewData } from "../view-data/RaceResultsDetailViewData";
export class RaceResultsDetailViewModel extends ViewModel {
private readonly data: RaceResultsDetailViewData;
readonly results: RaceResultViewModel[];
constructor(data: RaceResultsDetailViewData) {
super();
this.data = data;
this.results = data.results.map(r => new RaceResultViewModel(r));
}
get raceId(): string { return this.data.raceId; }
get track(): string { return this.data.track; }
get currentUserId(): string { return this.data.currentUserId; }
get league() { return this.data.league; }
get race() { return this.data.race; }
get drivers() { return this.data.drivers; }
get pointsSystem() { return this.data.pointsSystem; }
get fastestLapTime(): number { return this.data.fastestLapTime; }
get penalties() { return this.data.penalties; }
get currentDriverId(): string { return this.data.currentDriverId; }
/** UI-specific: Results sorted by position */
get resultsByPosition(): RaceResultViewModel[] {
return [...this.results].sort((a, b) => a.position - b.position);
}
/** UI-specific: Results sorted by fastest lap */
get resultsByFastestLap(): RaceResultViewModel[] {
return [...this.results].sort((a, b) => a.fastestLap - b.fastestLap);
}
/** UI-specific: Clean drivers only */
get cleanDrivers(): RaceResultViewModel[] {
return this.results.filter(r => r.isClean);
}
/** UI-specific: Current user's result */
get currentUserResult(): RaceResultViewModel | undefined {
return this.results.find(r => r.driverId === this.currentUserId);
}
/** UI-specific: Race stats */
get stats(): { totalDrivers: number; cleanRate: number; averageIncidents: number } {
const total = this.results.length;
const clean = this.cleanDrivers.length;
const totalIncidents = this.results.reduce((sum, r) => sum + r.incidents, 0);
return {
totalDrivers: total,
cleanRate: total > 0 ? (clean / total) * 100 : 0,
averageIncidents: total > 0 ? totalIncidents / total : 0
};
}
}