import type { DashboardOverviewViewModelData } from './DashboardOverviewViewModelData'; import { dashboardStatDisplay, formatDashboardDate, formatRating, formatRank, formatConsistency, formatRaceCount, formatFriendCount, formatLeaguePosition, formatPoints, formatTotalDrivers, } from '@/lib/display-objects/DashboardDisplay'; /** * Dashboard Overview ViewModel * * Clean class that accepts DTO only and exposes derived values. * This is client-only and instantiated after hydration. */ export class DashboardOverviewViewModel { constructor(private readonly dto: DashboardOverviewViewModelData) {} // Current Driver - Derived Values get currentDriverName(): string { return this.dto.currentDriver?.name || ''; } get currentDriverAvatarUrl(): string { return this.dto.currentDriver?.avatarUrl || ''; } get currentDriverCountry(): string { return this.dto.currentDriver?.country || ''; } get currentDriverRating(): string { return this.dto.currentDriver ? formatRating(this.dto.currentDriver.rating) : '0.0'; } get currentDriverRank(): string { return this.dto.currentDriver ? formatRank(this.dto.currentDriver.globalRank) : '0'; } get currentDriverTotalRaces(): string { return this.dto.currentDriver ? formatRaceCount(this.dto.currentDriver.totalRaces) : '0'; } get currentDriverWins(): string { return this.dto.currentDriver ? formatRaceCount(this.dto.currentDriver.wins) : '0'; } get currentDriverPodiums(): string { return this.dto.currentDriver ? formatRaceCount(this.dto.currentDriver.podiums) : '0'; } get currentDriverConsistency(): string { return this.dto.currentDriver ? formatConsistency(this.dto.currentDriver.consistency) : '0%'; } // Next Race - Derived Values get nextRace(): { id: string; track: string; car: string; scheduledAt: string; status: string; isMyLeague: boolean; formattedDate: string; formattedTime: string; timeUntil: string; } | null { if (!this.dto.nextRace) return null; const dateInfo = formatDashboardDate(new Date(this.dto.nextRace.scheduledAt)); return { id: this.dto.nextRace.id, track: this.dto.nextRace.track, car: this.dto.nextRace.car, scheduledAt: this.dto.nextRace.scheduledAt, status: this.dto.nextRace.status, isMyLeague: this.dto.nextRace.isMyLeague, formattedDate: dateInfo.date, formattedTime: dateInfo.time, timeUntil: dateInfo.relative, }; } // Upcoming Races - Derived Values get upcomingRaces(): Array<{ id: string; track: string; car: string; scheduledAt: string; status: string; isMyLeague: boolean; formattedDate: string; formattedTime: string; timeUntil: string; }> { return this.dto.upcomingRaces.map((race) => { const dateInfo = formatDashboardDate(new Date(race.scheduledAt)); return { id: race.id, track: race.track, car: race.car, scheduledAt: race.scheduledAt, status: race.status, isMyLeague: race.isMyLeague, formattedDate: dateInfo.date, formattedTime: dateInfo.time, timeUntil: dateInfo.relative, }; }); } // League Standings - Derived Values get leagueStandings(): Array<{ leagueId: string; leagueName: string; position: string; points: string; totalDrivers: string; }> { return this.dto.leagueStandingsSummaries.map((standing) => ({ leagueId: standing.leagueId, leagueName: standing.leagueName, position: formatLeaguePosition(standing.position), points: formatPoints(standing.points), totalDrivers: formatTotalDrivers(standing.totalDrivers), })); } // Feed Items - Derived Values get feedItems(): Array<{ id: string; type: string; headline: string; body?: string; timestamp: string; ctaHref?: string; ctaLabel?: string; formattedTime: string; }> { return this.dto.feedSummary.items.map((item) => ({ id: item.id, type: item.type, headline: item.headline, body: item.body, timestamp: item.timestamp, ctaHref: item.ctaHref, ctaLabel: item.ctaLabel, formattedTime: formatDashboardDate(new Date(item.timestamp)).relative, })); } // Friends - Derived Values get friends(): Array<{ id: string; name: string; avatarUrl: string; country: string; }> { // No additional formatting needed for friends return this.dto.friends; } // Active Leagues Count get activeLeaguesCount(): string { return formatRaceCount(this.dto.activeLeaguesCount); } // Convenience getters for display get hasNextRace(): boolean { return this.dto.nextRace !== undefined; } get hasUpcomingRaces(): boolean { return this.dto.upcomingRaces.length > 0; } get hasLeagueStandings(): boolean { return this.dto.leagueStandingsSummaries.length > 0; } get hasFeedItems(): boolean { return this.dto.feedSummary.items.length > 0; } get hasFriends(): boolean { return this.dto.friends.length > 0; } get friendCount(): string { return formatFriendCount(this.dto.friends.length); } }