import { ViewModel } from "../contracts/view-models/ViewModel"; import type { UserProfileViewData } from "../view-data/UserProfileViewData"; export class UserProfileViewModel extends ViewModel { private readonly data: UserProfileViewData; constructor(data: UserProfileViewData) { super(); this.data = data; } get id(): string { return this.data.id; } get name(): string { return this.data.name; } get avatarUrl(): string | undefined { return this.data.avatarUrl; } get iracingId(): string | undefined { return this.data.iracingId; } get rating(): number | undefined { return this.data.rating; } /** UI-specific: Formatted rating */ get formattedRating(): string { return this.rating ? this.rating.toFixed(0) : 'Unrated'; } /** UI-specific: Whether has iRacing ID */ get hasIracingId(): boolean { return !!this.iracingId; } /** UI-specific: Profile completeness percentage */ get profileCompleteness(): number { let complete = 1; // id always there if (this.avatarUrl) complete++; if (this.iracingId) complete++; if (this.rating) complete++; return Math.round((complete / 4) * 100); } /** UI-specific: Avatar initials */ get avatarInitials(): string { return this.name.split(' ').map(n => n[0]).join('').toUpperCase(); } }