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'); } }