135 lines
5.1 KiB
TypeScript
135 lines
5.1 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 => ({
|
|
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,
|
|
icon: a.icon as any, // Type assertion - assuming valid icon
|
|
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,
|
|
};
|
|
}
|
|
} |