Files
gridpilot.gg/apps/website/lib/presenters/RacesPagePresenter.ts
2025-12-10 18:28:32 +01:00

64 lines
1.9 KiB
TypeScript

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