Files
gridpilot.gg/apps/website/lib/presenters/ScheduleRaceFormPresenter.ts
2025-12-11 00:57:32 +01:00

71 lines
1.9 KiB
TypeScript

import { Race } from '@gridpilot/racing/domain/entities/Race';
import { InMemoryRaceRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryRaceRepository';
import { getRaceRepository, getLeagueRepository } from '@/lib/di-container';
export type SessionType = 'practice' | 'qualifying' | 'race';
export interface ScheduleRaceFormData {
leagueId: string;
track: string;
car: string;
sessionType: SessionType;
scheduledDate: string;
scheduledTime: string;
}
export interface ScheduledRaceViewModel {
id: string;
leagueId: string;
track: string;
car: string;
sessionType: SessionType;
scheduledAt: Date;
status: string;
}
export interface LeagueOptionViewModel {
id: string;
name: string;
}
/**
* Presenter/Facade for the schedule race form.
* Encapsulates all domain/repository access so the component can stay purely presentational.
*/
export async function loadScheduleRaceFormLeagues(): Promise<LeagueOptionViewModel[]> {
const leagueRepo = getLeagueRepository();
const allLeagues = await leagueRepo.findAll();
return allLeagues.map((league) => ({
id: league.id,
name: league.name,
}));
}
export async function scheduleRaceFromForm(
formData: ScheduleRaceFormData
): Promise<ScheduledRaceViewModel> {
const raceRepo = getRaceRepository();
const scheduledAt = new Date(`${formData.scheduledDate}T${formData.scheduledTime}`);
const race = Race.create({
id: InMemoryRaceRepository.generateId(),
leagueId: formData.leagueId,
track: formData.track.trim(),
car: formData.car.trim(),
sessionType: formData.sessionType,
scheduledAt,
status: 'scheduled',
});
const createdRace = await raceRepo.create(race);
return {
id: createdRace.id,
leagueId: createdRace.leagueId,
track: createdRace.track,
car: createdRace.car,
sessionType: createdRace.sessionType as SessionType,
scheduledAt: createdRace.scheduledAt,
status: createdRace.status,
};
}