/** * Driver view model * UI representation of a driver * * Note: client-only ViewModel created from ViewData (never DTO). */ import { ViewModel } from "../contracts/view-models/ViewModel"; import type { DriverData } from "../view-data/LeagueStandingsViewData"; type DriverViewModelViewData = DriverData & { bio?: string; joinedAt?: string; }; export class DriverViewModel extends ViewModel { id: string; name: string; avatarUrl: string | null; iracingId?: string; rating?: number; country?: string; bio?: string; joinedAt?: string; constructor(viewData: DriverViewModelViewData) { super(); this.id = viewData.id; this.name = viewData.name; this.avatarUrl = viewData.avatarUrl ?? null; if (viewData.iracingId !== undefined) this.iracingId = viewData.iracingId; if (viewData.rating !== undefined) this.rating = viewData.rating; if (viewData.country !== undefined) this.country = viewData.country; if (viewData.bio !== undefined) this.bio = viewData.bio; if (viewData.joinedAt !== undefined) this.joinedAt = viewData.joinedAt; } /** UI-specific: Whether driver has an iRacing ID */ get hasIracingId(): boolean { return !!this.iracingId; } /** UI-specific: Formatted rating */ get formattedRating(): string { return this.rating ? this.rating.toFixed(0) : "Unrated"; } }