// Note: No generated DTO available for UserProfile yet interface UserProfileDTO { id: string; name: string; avatarUrl?: string; iracingId?: string; rating?: number; } export class UserProfileViewModel { id: string; name: string; avatarUrl?: string; iracingId?: string; rating?: number; constructor(dto: UserProfileDTO) { this.id = dto.id; this.name = dto.name; if (dto.avatarUrl !== undefined) this.avatarUrl = dto.avatarUrl; if (dto.iracingId !== undefined) this.iracingId = dto.iracingId; if (dto.rating !== undefined) this.rating = dto.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(); } }