Files
gridpilot.gg/apps/website/lib/builders/view-models/DriverProfileViewModelBuilder.ts
2026-01-16 01:00:03 +01:00

138 lines
5.3 KiB
TypeScript

import type { GetDriverProfileOutputDTO } from '@/lib/types/generated/GetDriverProfileOutputDTO';
import type { DriverProfileDriverSummaryDTO } from '@/lib/types/generated/DriverProfileDriverSummaryDTO';
import type { DriverProfileStatsDTO } from '@/lib/types/generated/DriverProfileStatsDTO';
import type { DriverProfileFinishDistributionDTO } from '@/lib/types/generated/DriverProfileFinishDistributionDTO';
import type { DriverProfileTeamMembershipDTO } from '@/lib/types/generated/DriverProfileTeamMembershipDTO';
import type { DriverProfileSocialSummaryDTO } from '@/lib/types/generated/DriverProfileSocialSummaryDTO';
import type { DriverProfileExtendedProfileDTO } from '@/lib/types/generated/DriverProfileExtendedProfileDTO';
import { DriverProfileViewModel } from '@/lib/view-models/DriverProfileViewModel';
import type {
DriverProfileDriverSummaryViewModel,
DriverProfileStatsViewModel,
DriverProfileFinishDistributionViewModel,
DriverProfileTeamMembershipViewModel,
DriverProfileSocialSummaryViewModel,
DriverProfileExtendedProfileViewModel,
} from '@/lib/view-models/DriverProfileViewModel';
/**
* DriverProfileViewModelBuilder
*
* Transforms GetDriverProfileOutputDTO into DriverProfileViewModel.
* Deterministic, side-effect free, no HTTP calls.
*/
export class DriverProfileViewModelBuilder {
/**
* Build ViewModel from API DTO
*
* @param apiDto - The API transport DTO
* @returns ViewModel ready for template
*/
static build(apiDto: GetDriverProfileOutputDTO): DriverProfileViewModel {
return new DriverProfileViewModel({
currentDriver: apiDto.currentDriver ? this.transformCurrentDriver(apiDto.currentDriver) : null,
stats: apiDto.stats ? this.transformStats(apiDto.stats) : null,
finishDistribution: apiDto.finishDistribution ? this.transformFinishDistribution(apiDto.finishDistribution) : null,
teamMemberships: apiDto.teamMemberships.map(m => this.transformTeamMembership(m)),
socialSummary: this.transformSocialSummary(apiDto.socialSummary),
extendedProfile: apiDto.extendedProfile ? this.transformExtendedProfile(apiDto.extendedProfile) : null,
});
}
private static transformCurrentDriver(dto: DriverProfileDriverSummaryDTO): DriverProfileDriverSummaryViewModel {
return {
id: dto.id,
name: dto.name,
country: dto.country,
avatarUrl: dto.avatarUrl || '', // Handle undefined
iracingId: dto.iracingId || null,
joinedAt: dto.joinedAt,
rating: dto.rating ?? null,
globalRank: dto.globalRank ?? null,
consistency: dto.consistency ?? null,
bio: dto.bio || null,
totalDrivers: dto.totalDrivers ?? null,
};
}
private static transformStats(dto: DriverProfileStatsDTO): DriverProfileStatsViewModel {
return {
totalRaces: dto.totalRaces,
wins: dto.wins,
podiums: dto.podiums,
dnfs: dto.dnfs,
avgFinish: dto.avgFinish ?? null,
bestFinish: dto.bestFinish ?? null,
worstFinish: dto.worstFinish ?? null,
finishRate: dto.finishRate ?? null,
winRate: dto.winRate ?? null,
podiumRate: dto.podiumRate ?? null,
percentile: dto.percentile ?? null,
rating: dto.rating ?? null,
consistency: dto.consistency ?? null,
overallRank: dto.overallRank ?? null,
};
}
private static transformFinishDistribution(dto: DriverProfileFinishDistributionDTO): DriverProfileFinishDistributionViewModel {
return {
totalRaces: dto.totalRaces,
wins: dto.wins,
podiums: dto.podiums,
topTen: dto.topTen,
dnfs: dto.dnfs,
other: dto.other,
};
}
private static transformTeamMembership(dto: DriverProfileTeamMembershipDTO): DriverProfileTeamMembershipViewModel {
return {
teamId: dto.teamId,
teamName: dto.teamName,
teamTag: dto.teamTag || null,
role: dto.role,
joinedAt: dto.joinedAt,
isCurrent: dto.isCurrent,
};
}
private static transformSocialSummary(dto: DriverProfileSocialSummaryDTO): DriverProfileSocialSummaryViewModel {
return {
friendsCount: dto.friendsCount,
friends: dto.friends.map(f => ({
id: f.id,
name: f.name,
country: f.country,
avatarUrl: f.avatarUrl || '', // Handle undefined
})),
};
}
private static transformExtendedProfile(dto: DriverProfileExtendedProfileDTO): DriverProfileExtendedProfileViewModel {
return {
socialHandles: dto.socialHandles.map(h => ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
platform: h.platform as any, // Type assertion - assuming valid platform
handle: h.handle,
url: h.url,
})),
achievements: dto.achievements.map(a => ({
id: a.id,
title: a.title,
description: a.description,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
icon: a.icon as any, // Type assertion - assuming valid icon
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rarity: a.rarity as any, // Type assertion - assuming valid rarity
earnedAt: a.earnedAt,
})),
racingStyle: dto.racingStyle,
favoriteTrack: dto.favoriteTrack,
favoriteCar: dto.favoriteCar,
timezone: dto.timezone,
availableHours: dto.availableHours,
lookingForTeam: dto.lookingForTeam,
openToRequests: dto.openToRequests,
};
}
}