import { ProtestDTO } from '../types/generated/ProtestDTO'; import { RaceProtestDTO } from '../types/generated/RaceProtestDTO'; /** * Protest view model * Represents a race protest */ export class ProtestViewModel { id: string; raceId: string; protestingDriverId: string; accusedDriverId: string; description: string; submittedAt: string; filedAt?: string; status: string; reviewedAt?: string; decisionNotes?: string; incident?: { lap?: number; description?: string } | null; proofVideoUrl?: string | null; comment?: string | null; constructor(dto: ProtestDTO | RaceProtestDTO) { this.id = dto.id; this.raceId = (dto as any).raceId || ''; this.protestingDriverId = dto.protestingDriverId; this.accusedDriverId = dto.accusedDriverId; this.description = (dto as any).description || dto.description; this.submittedAt = (dto as any).submittedAt || (dto as any).filedAt || ''; this.filedAt = (dto as any).filedAt || (dto as any).submittedAt; // Handle different DTO structures if ('status' in dto) { this.status = dto.status; } else { this.status = 'pending'; } // Handle incident data if ('incident' in dto && dto.incident) { this.incident = { lap: (dto.incident as any).lap, description: (dto.incident as any).description }; } else if ('lap' in dto || 'description' in dto) { this.incident = { lap: (dto as any).lap, description: (dto as any).description }; } else { this.incident = null; } // Status and decision metadata are not part of the protest DTO in this build; they default to a pending, unreviewed protest if (!('status' in dto)) { this.status = 'pending'; } this.reviewedAt = undefined; this.decisionNotes = undefined; } /** UI-specific: Formatted submitted date */ get formattedSubmittedAt(): string { return new Date(this.submittedAt).toLocaleString(); } /** UI-specific: Status display */ get statusDisplay(): string { return 'Pending'; } }