Files
gridpilot.gg/apps/website/lib/builders/view-data/DriverRankingsViewDataBuilder.ts
2026-01-14 10:51:05 +01:00

58 lines
2.2 KiB
TypeScript

import type { DriverLeaderboardItemDTO } from '@/lib/types/generated/DriverLeaderboardItemDTO';
import type { DriverRankingsViewData } from '@/lib/view-data/DriverRankingsViewData';
export class DriverRankingsViewDataBuilder {
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: driver.racesCompleted > 0 ? ((driver.wins / driver.racesCompleted) * 100).toFixed(1) : '0.0',
medalBg: driver.rank === 1 ? 'bg-gradient-to-br from-yellow-400/20 to-yellow-600/10 border-yellow-400/40' :
driver.rank === 2 ? 'bg-gradient-to-br from-gray-300/20 to-gray-400/10 border-gray-300/40' :
driver.rank === 3 ? 'bg-gradient-to-br from-amber-600/20 to-amber-700/10 border-amber-600/40' :
'bg-iron-gray/50 border-charcoal-outline',
medalColor: driver.rank === 1 ? 'text-yellow-400' :
driver.rank === 2 ? 'text-gray-300' :
driver.rank === 3 ? 'text-amber-600' :
'text-gray-500',
})),
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,
};
}
}