import type { ViewDataBuilder } from '@/lib/contracts/builders/ViewDataBuilder'; import { DateFormatter } from '@/lib/formatters/DateFormatter'; import { FinishFormatter } from '@/lib/formatters/FinishFormatter'; import { NumberFormatter } from '@/lib/formatters/NumberFormatter'; import { PercentFormatter } from '@/lib/formatters/PercentFormatter'; import { RatingFormatter } from '@/lib/formatters/RatingFormatter'; import type { GetDriverProfileOutputDTO } from '@/lib/types/generated/GetDriverProfileOutputDTO'; import type { DriverProfileViewData } from '@/lib/view-data/DriverProfileViewData'; export class DriverProfileViewDataBuilder { public static build(apiDto: GetDriverProfileOutputDTO): DriverProfileViewData { const currentDriver = apiDto.currentDriver!; return { driver: { id: currentDriver.id, name: currentDriver.name, countryCode: currentDriver.country, countryFlag: currentDriver.country, // Placeholder avatarUrl: currentDriver.avatarUrl || '', bio: currentDriver.bio ?? null, iracingId: currentDriver.iracingId ?? null, joinedAtLabel: DateFormatter.formatMonthYear(currentDriver.joinedAt), globalRankLabel: currentDriver.globalRank != null ? `#${currentDriver.globalRank}` : '—', }, stats: apiDto.stats ? { ratingLabel: RatingFormatter.format(apiDto.stats.rating), globalRankLabel: apiDto.stats.overallRank != null ? `#${apiDto.stats.overallRank}` : '—', totalRacesLabel: NumberFormatter.format(apiDto.stats.totalRaces), winsLabel: NumberFormatter.format(apiDto.stats.wins), podiumsLabel: NumberFormatter.format(apiDto.stats.podiums), dnfsLabel: NumberFormatter.format(apiDto.stats.dnfs), bestFinishLabel: FinishFormatter.format(apiDto.stats.bestFinish), worstFinishLabel: FinishFormatter.format(apiDto.stats.worstFinish), avgFinishLabel: FinishFormatter.formatAverage(apiDto.stats.avgFinish), consistencyLabel: PercentFormatter.formatWhole(apiDto.stats.consistency), percentileLabel: PercentFormatter.formatWhole(apiDto.stats.percentile), } as any : null, teamMemberships: apiDto.teamMemberships.map(m => ({ teamId: m.teamId, teamName: m.teamName, teamTag: m.teamTag ?? null, roleLabel: m.role, joinedAtLabel: DateFormatter.formatMonthYear(m.joinedAt), href: `/teams/${m.teamId}`, })) as any, extendedProfile: apiDto.extendedProfile ? { timezone: apiDto.extendedProfile.timezone, racingStyle: apiDto.extendedProfile.racingStyle, favoriteTrack: apiDto.extendedProfile.favoriteTrack, favoriteCar: apiDto.extendedProfile.favoriteCar, availableHours: apiDto.extendedProfile.availableHours, lookingForTeamLabel: apiDto.extendedProfile.lookingForTeam ? 'Yes' : 'No', openToRequestsLabel: apiDto.extendedProfile.openToRequests ? 'Yes' : 'No', socialHandles: apiDto.extendedProfile.socialHandles.map(h => ({ platformLabel: h.platform, handle: h.handle, url: h.url, })), achievements: apiDto.extendedProfile.achievements.map(a => ({ id: a.id, title: a.title, description: a.description, earnedAtLabel: DateFormatter.formatShort(a.earnedAt), icon: a.icon as any, rarityLabel: a.rarity, })), friends: apiDto.socialSummary.friends.map(f => ({ id: f.id, name: f.name, countryFlag: f.country, // Placeholder avatarUrl: f.avatarUrl || '', href: `/drivers/${f.id}`, })), friendsCountLabel: NumberFormatter.format(apiDto.socialSummary.friendsCount), } as any : null, } as any; } } DriverProfileViewDataBuilder satisfies ViewDataBuilder;