import type { IRacesPagePresenter, RacesPageViewModel, RaceListItemViewModel, } from '@gridpilot/racing/application/presenters/IRacesPagePresenter'; export class RacesPagePresenter implements IRacesPagePresenter { private viewModel: RacesPageViewModel | null = null; present(races: any[]): void { const now = new Date(); const nextWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); const raceViewModels: RaceListItemViewModel[] = races.map(race => ({ id: race.id, track: race.track, car: race.car, scheduledAt: race.scheduledAt, status: race.status, leagueId: race.leagueId, leagueName: race.leagueName, strengthOfField: race.strengthOfField, isUpcoming: race.isUpcoming, isLive: race.isLive, isPast: race.isPast, })); const stats = { total: raceViewModels.length, scheduled: raceViewModels.filter(r => r.status === 'scheduled').length, running: raceViewModels.filter(r => r.status === 'running').length, completed: raceViewModels.filter(r => r.status === 'completed').length, }; const liveRaces = raceViewModels.filter(r => r.isLive); const upcomingThisWeek = raceViewModels .filter(r => { const scheduledDate = new Date(r.scheduledAt); return r.isUpcoming && scheduledDate >= now && scheduledDate <= nextWeek; }) .slice(0, 5); const recentResults = raceViewModels .filter(r => r.status === 'completed') .sort((a, b) => new Date(b.scheduledAt).getTime() - new Date(a.scheduledAt).getTime()) .slice(0, 3); this.viewModel = { races: raceViewModels, stats, liveRaces, upcomingThisWeek, recentResults, }; } getViewModel(): RacesPageViewModel { if (!this.viewModel) { throw new Error('ViewModel not yet generated. Call present() first.'); } return this.viewModel; } }