import { ViewModel } from "../contracts/view-models/ViewModel"; import { DurationFormatter } from "../formatters/DurationFormatter"; import type { RaceDetailUserResultViewData } from "../view-data/RaceDetailUserResultViewData"; export class RaceDetailUserResultViewModel extends ViewModel { private readonly data: RaceDetailUserResultViewData; constructor(data: RaceDetailUserResultViewData) { super(); this.data = data; } get position(): number { return this.data.position; } get startPosition(): number { return this.data.startPosition; } get incidents(): number { return this.data.incidents; } get fastestLap(): number { return this.data.fastestLap; } get positionChange(): number { return this.data.positionChange; } get isPodium(): boolean { return this.data.isPodium; } get isClean(): boolean { return this.data.isClean; } get ratingChange(): number { return this.data.ratingChange; } /** 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: Rating change display */ get ratingChangeDisplay(): string { if (this.ratingChange > 0) return `+${this.ratingChange}`; return `${this.ratingChange}`; } /** UI-specific: Rating change color */ get ratingChangeColor(): string { if (this.ratingChange > 0) return 'green'; if (this.ratingChange < 0) return 'red'; return 'gray'; } /** UI-specific: Formatted lap time */ get lapTimeFormatted(): string { if (this.fastestLap <= 0) return '--:--.---'; return DurationFormatter.formatSeconds(this.fastestLap); } }