import type { IRacePenaltiesPresenter, RacePenaltyViewModel, RacePenaltiesResultDTO, RacePenaltiesViewModel, } from '@gridpilot/racing/application/presenters/IRacePenaltiesPresenter'; export class RacePenaltiesPresenter implements IRacePenaltiesPresenter { private viewModel: RacePenaltiesViewModel | null = null; reset(): void { this.viewModel = null; } present(dto: RacePenaltiesResultDTO): void { const { penalties, driverMap } = dto; const penaltyViewModels: RacePenaltyViewModel[] = penalties.map((penalty) => { const value = typeof penalty.value === 'number' ? penalty.value : 0; const protestId = penalty.protestId; const appliedAt = penalty.appliedAt ? penalty.appliedAt.toISOString() : undefined; const notes = penalty.notes; const base: RacePenaltyViewModel = { id: penalty.id, raceId: penalty.raceId, driverId: penalty.driverId, driverName: driverMap.get(penalty.driverId) || 'Unknown', type: penalty.type, value, reason: penalty.reason, issuedBy: penalty.issuedBy, issuedByName: driverMap.get(penalty.issuedBy) || 'Unknown', status: penalty.status, description: penalty.getDescription(), issuedAt: penalty.issuedAt.toISOString(), }; return { ...base, ...(protestId ? { protestId } : {}), ...(appliedAt ? { appliedAt } : {}), ...(typeof notes === 'string' && notes.length > 0 ? { notes } : {}), }; }); this.viewModel = { penalties: penaltyViewModels, }; } getViewModel(): RacePenaltiesViewModel | null { return this.viewModel; } }