66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import { RaceResultDTO } from '@/lib/types/generated/RaceResultDTO';
|
|
import { RaceResultsDetailDTO } from '@/lib/types/generated/RaceResultsDetailDTO';
|
|
import { RaceResultViewModel } from './RaceResultViewModel';
|
|
|
|
import { ViewModel } from "../contracts/view-models/ViewModel";
|
|
|
|
export class RaceResultsDetailViewModel extends ViewModel {
|
|
raceId: string;
|
|
track: string;
|
|
currentUserId: string;
|
|
|
|
constructor(dto: RaceResultsDetailDTO & { results?: RaceResultDTO[] }, currentUserId: string) {
|
|
super();
|
|
this.raceId = dto.raceId;
|
|
this.track = dto.track;
|
|
this.currentUserId = currentUserId;
|
|
|
|
// Map results if provided
|
|
if (dto.results) {
|
|
this.results = dto.results.map(r => new RaceResultViewModel(r));
|
|
}
|
|
}
|
|
|
|
// Note: The generated DTO is incomplete
|
|
// These fields will need to be added when the OpenAPI spec is updated
|
|
results: RaceResultViewModel[] = [];
|
|
league?: { id: string; name: string };
|
|
race?: { id: string; track: string; scheduledAt: string };
|
|
drivers: { id: string; name: string }[] = [];
|
|
pointsSystem: Record<number, number> = {};
|
|
fastestLapTime: number = 0;
|
|
penalties: { driverId: string; type: string; value?: number }[] = [];
|
|
currentDriverId: string = '';
|
|
|
|
/** 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
|
|
};
|
|
}
|
|
} |