Files
gridpilot.gg/apps/website/lib/view-models/RacesPageViewModel.ts
2025-12-26 11:49:20 +01:00

80 lines
2.2 KiB
TypeScript

import { RaceListItemViewModel } from './RaceListItemViewModel';
import type { RacesPageDataRaceDTO } from '../types/generated/RacesPageDataRaceDTO';
import type { RaceListItemDTO } from './RaceListItemViewModel';
// DTO matching the backend RacesPageDataDTO
interface RacesPageDTO {
races: RacesPageDataRaceDTO[];
}
/**
* Races page view model
* Represents the races page data with all races in a single list
*/
export class RacesPageViewModel {
races: RaceListItemViewModel[];
constructor(dto: RacesPageDTO) {
this.races = dto.races.map((r) => {
const status = (r as any).status as string | undefined;
const isUpcoming =
(r as any).isUpcoming ??
(status === 'upcoming' || status === 'scheduled');
const isLive =
(r as any).isLive ??
(status === 'live' || status === 'running');
const isPast =
(r as any).isPast ??
(status === 'completed' || status === 'finished' || status === 'cancelled');
const normalized: RaceListItemDTO = {
...(r as any),
strengthOfField: (r as any).strengthOfField ?? null,
isUpcoming: Boolean(isUpcoming),
isLive: Boolean(isLive),
isPast: Boolean(isPast),
};
return new RaceListItemViewModel(normalized);
});
}
/** UI-specific: Total races */
get totalCount(): number {
return this.races.length;
}
/** UI-specific: Upcoming races */
get upcomingRaces(): RaceListItemViewModel[] {
return this.races.filter(r => r.isUpcoming);
}
/** UI-specific: Live races */
get liveRaces(): RaceListItemViewModel[] {
return this.races.filter(r => r.isLive);
}
/** UI-specific: Past races */
get pastRaces(): RaceListItemViewModel[] {
return this.races.filter(r => r.isPast);
}
/** UI-specific: Scheduled races */
get scheduledRaces(): RaceListItemViewModel[] {
return this.races.filter(r => r.status === 'scheduled');
}
/** UI-specific: Running races */
get runningRaces(): RaceListItemViewModel[] {
return this.races.filter(r => r.status === 'running');
}
/** UI-specific: Completed races */
get completedRaces(): RaceListItemViewModel[] {
return this.races.filter(r => r.status === 'completed');
}
}