91 lines
4.2 KiB
TypeScript
91 lines
4.2 KiB
TypeScript
|
|
|
|
import type { ViewDataBuilder } from '@/lib/contracts/builders/ViewDataBuilder';
|
|
import { DashboardConsistencyFormatter } from '@/lib/formatters/DashboardConsistencyFormatter';
|
|
import { DashboardCountFormatter } from '@/lib/formatters/DashboardCountFormatter';
|
|
import { DashboardDateFormatter } from '@/lib/formatters/DashboardDateFormatter';
|
|
import { DashboardLeaguePositionFormatter } from '@/lib/formatters/DashboardLeaguePositionFormatter';
|
|
import { DashboardRankFormatter } from '@/lib/formatters/DashboardRankFormatter';
|
|
import { RatingFormatter } from '@/lib/formatters/RatingFormatter';
|
|
import type { DashboardOverviewDTO } from '@/lib/types/generated/DashboardOverviewDTO';
|
|
import type { DashboardViewData } from '@/lib/view-data/DashboardViewData';
|
|
|
|
export class DashboardViewDataBuilder {
|
|
public static build(apiDto: DashboardOverviewDTO): DashboardViewData {
|
|
return {
|
|
currentDriver: {
|
|
name: apiDto.currentDriver?.name || '',
|
|
avatarUrl: apiDto.currentDriver?.avatarUrl || '',
|
|
country: apiDto.currentDriver?.country || '',
|
|
rating: apiDto.currentDriver ? RatingFormatter.format(apiDto.currentDriver.rating ?? 0) : '0.0',
|
|
rank: apiDto.currentDriver ? DashboardRankFormatter.format(apiDto.currentDriver.globalRank ?? 0) : '0',
|
|
totalRaces: apiDto.currentDriver ? DashboardCountFormatter.format(apiDto.currentDriver.totalRaces ?? 0) : '0',
|
|
wins: apiDto.currentDriver ? DashboardCountFormatter.format(apiDto.currentDriver.wins ?? 0) : '0',
|
|
podiums: apiDto.currentDriver ? DashboardCountFormatter.format(apiDto.currentDriver.podiums ?? 0) : '0',
|
|
consistency: apiDto.currentDriver ? DashboardConsistencyFormatter.format(apiDto.currentDriver.consistency ?? 0) : '0%',
|
|
},
|
|
nextRace: apiDto.nextRace ? DashboardViewDataBuilder.buildNextRace(apiDto.nextRace) : null,
|
|
upcomingRaces: apiDto.upcomingRaces.map((race) => DashboardViewDataBuilder.buildRace(race)),
|
|
leagueStandings: apiDto.leagueStandingsSummaries.map((standing) => ({
|
|
leagueId: standing.leagueId,
|
|
leagueName: standing.leagueName,
|
|
position: DashboardLeaguePositionFormatter.format(standing.position),
|
|
points: DashboardCountFormatter.format(standing.points),
|
|
totalDrivers: DashboardCountFormatter.format(standing.totalDrivers),
|
|
})),
|
|
feedItems: apiDto.feedSummary.items.map((item) => ({
|
|
id: item.id,
|
|
type: item.type,
|
|
headline: item.headline,
|
|
body: item.body ?? undefined,
|
|
timestamp: item.timestamp,
|
|
formattedTime: DashboardDateFormatter.format(new Date(item.timestamp)).relative,
|
|
ctaHref: item.ctaHref ?? undefined,
|
|
ctaLabel: item.ctaLabel ?? undefined,
|
|
})),
|
|
friends: apiDto.friends.map((friend) => ({
|
|
id: friend.id,
|
|
name: friend.name,
|
|
avatarUrl: friend.avatarUrl || '',
|
|
country: friend.country,
|
|
})),
|
|
activeLeaguesCount: DashboardCountFormatter.format(apiDto.activeLeaguesCount),
|
|
friendCount: DashboardCountFormatter.format(apiDto.friends.length),
|
|
hasUpcomingRaces: apiDto.upcomingRaces.length > 0,
|
|
hasLeagueStandings: apiDto.leagueStandingsSummaries.length > 0,
|
|
hasFeedItems: apiDto.feedSummary.items.length > 0,
|
|
hasFriends: apiDto.friends.length > 0,
|
|
};
|
|
}
|
|
|
|
private static buildNextRace(race: NonNullable<DashboardOverviewDTO['nextRace']>) {
|
|
const dateInfo = DashboardDateFormatter.format(new Date(race.scheduledAt));
|
|
return {
|
|
id: race.id,
|
|
track: race.track,
|
|
car: race.car,
|
|
scheduledAt: race.scheduledAt,
|
|
formattedDate: dateInfo.date,
|
|
formattedTime: dateInfo.time,
|
|
timeUntil: dateInfo.relative,
|
|
isMyLeague: race.isMyLeague,
|
|
};
|
|
}
|
|
|
|
private static buildRace(race: DashboardOverviewDTO['upcomingRaces'][number]) {
|
|
const dateInfo = DashboardDateFormatter.format(new Date(race.scheduledAt));
|
|
return {
|
|
id: race.id,
|
|
track: race.track,
|
|
car: race.car,
|
|
scheduledAt: race.scheduledAt,
|
|
formattedDate: dateInfo.date,
|
|
formattedTime: dateInfo.time,
|
|
timeUntil: dateInfo.relative,
|
|
isMyLeague: race.isMyLeague,
|
|
};
|
|
}
|
|
}
|
|
|
|
DashboardViewDataBuilder satisfies ViewDataBuilder<DashboardOverviewDTO, DashboardViewData>;
|