import { ViewModel } from "../contracts/view-models/ViewModel"; import { ProfileViewData } from "../view-data/ProfileViewData"; import { DriverProfileDriverSummaryViewModel } from "./DriverProfileDriverSummaryViewModel"; export interface DriverProfileStatsViewModel extends ViewModel { totalRaces: number; wins: number; podiums: number; dnfs: number; avgFinish: number | null; bestFinish: number | null; worstFinish: number | null; finishRate: number | null; winRate: number | null; podiumRate: number | null; percentile: number | null; rating: number | null; consistency: number | null; overallRank: number | null; } export interface DriverProfileFinishDistributionViewModel extends ViewModel { totalRaces: number; wins: number; podiums: number; topTen: number; dnfs: number; other: number; } export interface DriverProfileTeamMembershipViewModel extends ViewModel { teamId: string; teamName: string; teamTag: string | null; role: string; joinedAt: string; isCurrent: boolean; } export interface DriverProfileSocialFriendSummaryViewModel extends ViewModel { id: string; name: string; country: string; avatarUrl: string; } export interface DriverProfileSocialSummaryViewModel extends ViewModel { friendsCount: number; friends: DriverProfileSocialFriendSummaryViewModel[]; } export type DriverProfileSocialPlatform = 'twitter' | 'youtube' | 'twitch' | 'discord'; export type DriverProfileAchievementRarity = 'common' | 'rare' | 'epic' | 'legendary'; export interface DriverProfileAchievementViewModel extends ViewModel { id: string; title: string; description: string; icon: 'trophy' | 'medal' | 'star' | 'crown' | 'target' | 'zap'; rarity: DriverProfileAchievementRarity; earnedAt: string; } export interface DriverProfileSocialHandleViewModel extends ViewModel { platform: DriverProfileSocialPlatform; handle: string; url: string; } export interface DriverProfileExtendedProfileViewModel extends ViewModel { socialHandles: DriverProfileSocialHandleViewModel[]; achievements: DriverProfileAchievementViewModel[]; racingStyle: string; favoriteTrack: string; favoriteCar: string; timezone: string; availableHours: string; lookingForTeam: boolean; openToRequests: boolean; } export interface DriverProfileViewModelData { currentDriver: DriverProfileDriverSummaryViewModel | null; stats: DriverProfileStatsViewModel | null; finishDistribution: DriverProfileFinishDistributionViewModel | null; teamMemberships: DriverProfileTeamMembershipViewModel[]; socialSummary: DriverProfileSocialSummaryViewModel; extendedProfile: DriverProfileExtendedProfileViewModel | null; } /** * Driver Profile View Model * * Represents a fully prepared UI state for driver profile display. * Transforms ViewData into UI-ready data structures. */ export class DriverProfileViewModel extends ViewModel { constructor(private readonly viewData: ProfileViewData) { super(); } get currentDriver(): DriverProfileDriverSummaryViewModel | null { if (!this.viewData.driver) return null; return new DriverProfileDriverSummaryViewModel(this.viewData); } get stats(): DriverProfileStatsViewModel | null { if (!this.viewData.stats) return null; return { totalRaces: 0, wins: 0, podiums: 0, dnfs: 0, avgFinish: null, bestFinish: null, worstFinish: null, finishRate: null, winRate: null, podiumRate: null, percentile: null, rating: null, consistency: null, overallRank: null, }; } get teamMemberships(): DriverProfileTeamMembershipViewModel[] { return this.viewData.teamMemberships.map((m) => ({ teamId: m.teamId, teamName: m.teamName, teamTag: m.teamTag, role: m.roleLabel, joinedAt: m.joinedAtLabel, isCurrent: true, })); } get extendedProfile(): DriverProfileExtendedProfileViewModel | null { if (!this.viewData.extendedProfile) return null; return { socialHandles: this.viewData.extendedProfile.socialHandles.map((h) => ({ platform: h.platformLabel.toLowerCase() as any, handle: h.handle, url: h.url, })), achievements: this.viewData.extendedProfile.achievements.map((a) => ({ id: a.id, title: a.title, description: a.description, icon: a.icon, rarity: a.rarityLabel.toLowerCase() as any, earnedAt: a.earnedAtLabel, })), racingStyle: this.viewData.extendedProfile.racingStyle, favoriteTrack: this.viewData.extendedProfile.favoriteTrack, favoriteCar: this.viewData.extendedProfile.favoriteCar, timezone: this.viewData.extendedProfile.timezone, availableHours: this.viewData.extendedProfile.availableHours, lookingForTeam: this.viewData.extendedProfile.lookingForTeamLabel === 'Yes', openToRequests: this.viewData.extendedProfile.openToRequestsLabel === 'Yes', }; } }