import type { RacesPageDataDTO } from '@/lib/types/generated/RacesPageDataDTO'; import type { RacesViewData, RaceViewData } from '@/lib/view-data/RacesViewData'; import { DateDisplay } from '@/lib/display-objects/DateDisplay'; import { RaceStatusDisplay } from '@/lib/display-objects/RaceStatusDisplay'; import { RelativeTimeDisplay } from '@/lib/display-objects/RelativeTimeDisplay'; import { ViewDataBuilder } from "../../contracts/builders/ViewDataBuilder"; export class RacesViewDataBuilder implements ViewDataBuilder { build(input: any): any { return RacesViewDataBuilder.build(input); } static build(apiDto: RacesPageDataDTO): RacesViewData { const now = new Date(); const races = apiDto.races.map((race): RaceViewData => { return { id: race.id, track: race.track, car: race.car, scheduledAt: race.scheduledAt, scheduledAtLabel: DateDisplay.formatShort(race.scheduledAt), timeLabel: DateDisplay.formatTime(race.scheduledAt), relativeTimeLabel: RelativeTimeDisplay.format(race.scheduledAt, now), status: race.status as RaceViewData['status'], statusLabel: RaceStatusDisplay.getLabel(race.status), statusVariant: RaceStatusDisplay.getVariant(race.status), statusIconName: RaceStatusDisplay.getIconName(race.status), sessionType: 'Race', leagueId: race.leagueId, leagueName: race.leagueName, strengthOfField: race.strengthOfField ?? null, isUpcoming: race.isUpcoming, isLive: race.isLive, isPast: race.isPast, }; }); const leagues = Array.from( new Map( races .filter(r => r.leagueId && r.leagueName) .map(r => [r.leagueId, { id: r.leagueId!, name: r.leagueName! }]) ).values() ); const groupedRaces = new Map(); races.forEach((race) => { const dateKey = race.scheduledAt.split('T')[0]!; if (!groupedRaces.has(dateKey)) { groupedRaces.set(dateKey, []); } groupedRaces.get(dateKey)!.push(race); }); const racesByDate = Array.from(groupedRaces.entries()).map(([dateKey, dayRaces]) => ({ dateKey, dateLabel: dayRaces[0]?.scheduledAtLabel || '', races: dayRaces, })); return { races, totalCount: races.length, scheduledCount: races.filter(r => r.status === 'scheduled').length, runningCount: races.filter(r => r.status === 'running').length, completedCount: races.filter(r => r.status === 'completed').length, leagues, upcomingRaces: races.filter(r => r.isUpcoming).slice(0, 5), liveRaces: races.filter(r => r.isLive), recentResults: races.filter(r => r.isPast).slice(0, 5), racesByDate, }; } }