Files
gridpilot.gg/apps/website/lib/view-models/RaceDetailViewModel.ts
2025-12-17 18:01:47 +01:00

57 lines
1.7 KiB
TypeScript

import { RaceDetailDto, RaceDetailRaceDto, RaceDetailLeagueDto, RaceDetailEntryDto, RaceDetailRegistrationDto, RaceDetailUserResultDto } from '../dtos';
export class RaceDetailViewModel implements RaceDetailDto {
race: RaceDetailRaceDto | null;
league: RaceDetailLeagueDto | null;
entryList: RaceDetailEntryDto[];
registration: RaceDetailRegistrationDto;
userResult: RaceDetailUserResultDto | null;
error?: string;
constructor(dto: RaceDetailDto) {
Object.assign(this, dto);
}
/** UI-specific: Whether user is registered */
get isRegistered(): boolean {
return this.registration.isRegistered;
}
/** UI-specific: Whether user can register */
get canRegister(): boolean {
return this.registration.canRegister;
}
/** UI-specific: Race status display */
get raceStatusDisplay(): string {
if (!this.race) return 'Unknown';
switch (this.race.status) {
case 'upcoming': return 'Upcoming';
case 'live': return 'Live';
case 'finished': return 'Finished';
default: return this.race.status;
}
}
/** UI-specific: Formatted scheduled time */
get formattedScheduledTime(): string {
return this.race ? new Date(this.race.scheduledTime).toLocaleString() : '';
}
/** UI-specific: Entry list count */
get entryCount(): number {
return this.entryList.length;
}
/** UI-specific: Whether race has results */
get hasResults(): boolean {
return this.userResult !== null;
}
/** UI-specific: Registration status message */
get registrationStatusMessage(): string {
if (this.isRegistered) return 'You are registered for this race';
if (this.canRegister) return 'You can register for this race';
return 'Registration not available';
}
}