113 lines
4.5 KiB
TypeScript
113 lines
4.5 KiB
TypeScript
import type { GetDriverProfileOutputDTO } from '@/lib/types/generated/GetDriverProfileOutputDTO';
|
|
import type { ProfileViewData } from '@/lib/view-data/ProfileViewData';
|
|
import { mediaConfig } from '@/lib/config/mediaConfig';
|
|
import { CountryFlagDisplay } from '@/lib/display-objects/CountryFlagDisplay';
|
|
import { DateDisplay } from '@/lib/display-objects/DateDisplay';
|
|
import { FinishDisplay } from '@/lib/display-objects/FinishDisplay';
|
|
import { PercentDisplay } from '@/lib/display-objects/PercentDisplay';
|
|
import { RatingDisplay } from '@/lib/display-objects/RatingDisplay';
|
|
import { NumberDisplay } from '@/lib/display-objects/NumberDisplay';
|
|
|
|
import { ViewDataBuilder } from "../../contracts/builders/ViewDataBuilder";
|
|
|
|
export class ProfileViewDataBuilder implements ViewDataBuilder<any, any> {
|
|
build(input: any): any {
|
|
return ProfileViewDataBuilder.build(input);
|
|
}
|
|
|
|
static build(
|
|
static build(apiDto: GetDriverProfileOutputDTO): ProfileViewData {
|
|
const driver = apiDto.currentDriver;
|
|
|
|
if (!driver) {
|
|
return {
|
|
driver: {
|
|
id: '',
|
|
name: '',
|
|
countryCode: '',
|
|
countryFlag: CountryFlagDisplay.fromCountryCode(null).toString(),
|
|
avatarUrl: mediaConfig.avatars.defaultFallback,
|
|
bio: null,
|
|
iracingId: null,
|
|
joinedAtLabel: '',
|
|
},
|
|
stats: null,
|
|
teamMemberships: [],
|
|
extendedProfile: null,
|
|
};
|
|
}
|
|
|
|
const stats = apiDto.stats ?? null;
|
|
const socialSummary = apiDto.socialSummary;
|
|
const extended = apiDto.extendedProfile ?? null;
|
|
|
|
return {
|
|
driver: {
|
|
id: driver.id,
|
|
name: driver.name,
|
|
countryCode: driver.country,
|
|
countryFlag: CountryFlagDisplay.fromCountryCode(driver.country).toString(),
|
|
avatarUrl: driver.avatarUrl || mediaConfig.avatars.defaultFallback,
|
|
bio: driver.bio || null,
|
|
iracingId: driver.iracingId ? String(driver.iracingId) : null,
|
|
joinedAtLabel: DateDisplay.formatMonthYear(driver.joinedAt),
|
|
},
|
|
stats: stats
|
|
? {
|
|
ratingLabel: RatingDisplay.format(stats.rating),
|
|
globalRankLabel: driver.globalRank != null ? `#${driver.globalRank}` : '—',
|
|
totalRacesLabel: NumberDisplay.format(stats.totalRaces),
|
|
winsLabel: NumberDisplay.format(stats.wins),
|
|
podiumsLabel: NumberDisplay.format(stats.podiums),
|
|
dnfsLabel: NumberDisplay.format(stats.dnfs),
|
|
bestFinishLabel: FinishDisplay.format(stats.bestFinish),
|
|
worstFinishLabel: FinishDisplay.format(stats.worstFinish),
|
|
avgFinishLabel: FinishDisplay.formatAverage(stats.avgFinish),
|
|
consistencyLabel: PercentDisplay.formatWhole(stats.consistency),
|
|
percentileLabel: PercentDisplay.format(stats.percentile),
|
|
}
|
|
: null,
|
|
teamMemberships: apiDto.teamMemberships.map((m) => ({
|
|
teamId: m.teamId,
|
|
teamName: m.teamName,
|
|
teamTag: m.teamTag || null,
|
|
roleLabel: m.role,
|
|
joinedAtLabel: DateDisplay.formatMonthYear(m.joinedAt),
|
|
href: `/teams/${m.teamId}`,
|
|
})),
|
|
extendedProfile: extended
|
|
? {
|
|
timezone: extended.timezone,
|
|
racingStyle: extended.racingStyle,
|
|
favoriteTrack: extended.favoriteTrack,
|
|
favoriteCar: extended.favoriteCar,
|
|
availableHours: extended.availableHours,
|
|
lookingForTeamLabel: extended.lookingForTeam ? 'Looking for Team' : '',
|
|
openToRequestsLabel: extended.openToRequests ? 'Open to Requests' : '',
|
|
socialHandles: extended.socialHandles.map((h) => ({
|
|
platformLabel: h.platform,
|
|
handle: h.handle,
|
|
url: h.url,
|
|
})),
|
|
achievements: extended.achievements.map((a) => ({
|
|
id: a.id,
|
|
title: a.title,
|
|
description: a.description,
|
|
earnedAtLabel: DateDisplay.formatShort(a.earnedAt),
|
|
icon: a.icon as any,
|
|
rarityLabel: a.rarity,
|
|
})),
|
|
friends: socialSummary.friends.slice(0, 8).map((f) => ({
|
|
id: f.id,
|
|
name: f.name,
|
|
countryFlag: CountryFlagDisplay.fromCountryCode(f.country).toString(),
|
|
avatarUrl: f.avatarUrl || mediaConfig.avatars.defaultFallback,
|
|
href: `/drivers/${f.id}`,
|
|
})),
|
|
friendsCountLabel: NumberDisplay.format(socialSummary.friendsCount),
|
|
}
|
|
: null,
|
|
};
|
|
}
|
|
}
|