79 lines
2.5 KiB
TypeScript
79 lines
2.5 KiB
TypeScript
import { RaceDetailLeagueDTO } from '../types/generated/RaceDetailLeagueDTO';
|
|
import { RaceDetailRaceDTO } from '../types/generated/RaceDetailRaceDTO';
|
|
import { RaceDetailRegistrationDTO } from '../types/generated/RaceDetailRegistrationDTO';
|
|
import { RaceDetailUserResultDTO } from '../types/generated/RaceDetailUserResultDTO';
|
|
import { RaceDetailEntryDTO } from '../types/RaceDetailEntryDTO';
|
|
|
|
export class RaceDetailViewModel {
|
|
race: RaceDetailRaceDTO | null;
|
|
league: RaceDetailLeagueDTO | null;
|
|
entryList: RaceDetailEntryDTO[];
|
|
registration: RaceDetailRegistrationDTO;
|
|
userResult: RaceDetailUserResultDTO | null;
|
|
error?: string;
|
|
|
|
constructor(dto: {
|
|
race: RaceDetailRaceDTO | null;
|
|
league: RaceDetailLeagueDTO | null;
|
|
entryList: RaceDetailEntryDTO[];
|
|
registration: RaceDetailRegistrationDTO;
|
|
userResult: RaceDetailUserResultDTO | null;
|
|
error?: string;
|
|
}) {
|
|
this.race = dto.race;
|
|
this.league = dto.league;
|
|
this.entryList = dto.entryList;
|
|
this.registration = dto.registration;
|
|
this.userResult = dto.userResult;
|
|
this.error = dto.error;
|
|
}
|
|
|
|
/** 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.scheduledAt).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';
|
|
}
|
|
|
|
/** UI-specific: Whether race can be re-opened */
|
|
get canReopenRace(): boolean {
|
|
if (!this.race) return false;
|
|
return this.race.status === 'completed' || this.race.status === 'cancelled';
|
|
}
|
|
} |