60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import type { DriverLeaderboardItemDTO } from '@/lib/types/generated/DriverLeaderboardItemDTO';
|
|
import type { DriverRankingsViewData } from '@/lib/view-data/DriverRankingsViewData';
|
|
import { WinRateDisplay } from '@/lib/display-objects/WinRateDisplay';
|
|
import { MedalDisplay } from '@/lib/display-objects/MedalDisplay';
|
|
import type { ViewDataBuilder } from '@/lib/contracts/builders/ViewDataBuilder';
|
|
|
|
export class DriverRankingsViewDataBuilder {
|
|
public static build(apiDto: DriverLeaderboardItemDTO[]): DriverRankingsViewData {
|
|
if (!apiDto || apiDto.length === 0) {
|
|
return {
|
|
drivers: [],
|
|
podium: [],
|
|
searchQuery: '',
|
|
selectedSkill: 'all',
|
|
sortBy: 'rank',
|
|
showFilters: false,
|
|
};
|
|
}
|
|
|
|
return {
|
|
drivers: apiDto.map(driver => ({
|
|
id: driver.id,
|
|
name: driver.name,
|
|
rating: driver.rating,
|
|
skillLevel: driver.skillLevel,
|
|
nationality: driver.nationality,
|
|
racesCompleted: driver.racesCompleted,
|
|
wins: driver.wins,
|
|
podiums: driver.podiums,
|
|
rank: driver.rank,
|
|
avatarUrl: driver.avatarUrl || '',
|
|
winRate: WinRateDisplay.calculate(driver.racesCompleted, driver.wins),
|
|
medalBg: MedalDisplay.getBg(driver.rank),
|
|
medalColor: MedalDisplay.getColor(driver.rank),
|
|
})),
|
|
podium: apiDto.slice(0, 3).map((driver, index) => {
|
|
const positions = [2, 1, 3]; // Display order: 2nd, 1st, 3rd
|
|
const position = positions[index];
|
|
return {
|
|
id: driver.id,
|
|
name: driver.name,
|
|
rating: driver.rating,
|
|
wins: driver.wins,
|
|
podiums: driver.podiums,
|
|
avatarUrl: driver.avatarUrl || '',
|
|
position: position as 1 | 2 | 3,
|
|
};
|
|
}),
|
|
searchQuery: '',
|
|
selectedSkill: 'all',
|
|
sortBy: 'rank',
|
|
showFilters: false,
|
|
};
|
|
}
|
|
}
|
|
|
|
DriverRankingsViewDataBuilder satisfies ViewDataBuilder<DriverLeaderboardItemDTO[], DriverRankingsViewData>;
|