import { ViewModel } from "../contracts/view-models/ViewModel"; import { FinishFormatter } from "../formatters/FinishFormatter"; import type { StandingEntryViewData } from "../view-data/StandingEntryViewData"; export class StandingEntryViewModel extends ViewModel { private readonly data: StandingEntryViewData; constructor(data: StandingEntryViewData) { super(); this.data = data; } get driverId(): string { return this.data.driverId; } get position(): number { return this.data.position; } get points(): number { return this.data.points; } get wins(): number { return this.data.wins; } get podiums(): number { return this.data.podiums; } get races(): number { return this.data.races; } get driver(): any { return this.data.driver; } /** UI-specific: Badge for position display */ get positionBadge(): string { return FinishFormatter.format(this.position); } /** UI-specific: Points difference to leader */ get pointsGapToLeader(): number { return this.points - this.data.leaderPoints; } /** UI-specific: Points difference to next position */ get pointsGapToNext(): number { return this.points - this.data.nextPoints; } /** UI-specific: Whether this entry is the current user */ get isCurrentUser(): boolean { return this.driverId === this.data.currentUserId; } /** UI-specific: Trend compared to previous */ get trend(): 'up' | 'down' | 'same' { if (!this.data.previousPosition) return 'same'; if (this.position < this.data.previousPosition) return 'up'; if (this.position > this.data.previousPosition) return 'down'; return 'same'; } /** UI-specific: Arrow for trend */ get trendArrow(): string { switch (this.trend) { case 'up': return '↑'; case 'down': return '↓'; default: return '-'; } } }