import { RaceResultDTO } from '../types/generated/RaceResultDTO'; export class RaceResultViewModel { driverId: string; driverName: string; avatarUrl: string; position: number; startPosition: number; incidents: number; fastestLap: number; positionChange: number; isPodium: boolean; isClean: boolean; constructor(dto: RaceResultDTO) { Object.assign(this, dto); } /** UI-specific: Display for position change */ get positionChangeDisplay(): string { if (this.positionChange > 0) return `+${this.positionChange}`; if (this.positionChange < 0) return `${this.positionChange}`; return '0'; } /** UI-specific: Color for position change */ get positionChangeColor(): string { if (this.positionChange > 0) return 'green'; if (this.positionChange < 0) return 'red'; return 'gray'; } /** UI-specific: Whether this is the winner */ get isWinner(): boolean { return this.position === 1; } /** UI-specific: Whether has fastest lap */ get hasFastestLap(): boolean { return this.fastestLap > 0; } /** UI-specific: Badge for position */ get positionBadge(): string { return this.position.toString(); } /** UI-specific: Color for incidents badge */ get incidentsBadgeColor(): string { if (this.incidents === 0) return 'green'; if (this.incidents <= 2) return 'yellow'; return 'red'; } /** UI-specific: Formatted lap time */ get lapTimeFormatted(): string { if (this.fastestLap <= 0) return '--:--.---'; const minutes = Math.floor(this.fastestLap / 60); const seconds = Math.floor(this.fastestLap % 60); const milliseconds = Math.floor((this.fastestLap % 1) * 1000); return `${minutes}:${seconds.toString().padStart(2, '0')}.${milliseconds.toString().padStart(3, '0')}`; } // Note: The generated DTO doesn't have id or raceId // These will need to be added when the OpenAPI spec is updated id: string = ''; raceId: string = ''; }