75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
import type { LeagueStandingsViewData, StandingEntryData, DriverData, LeagueMembershipData } from '@/lib/view-data/LeagueStandingsViewData';
|
|
import type { LeagueStandingDTO } from '@/lib/types/generated/LeagueStandingDTO';
|
|
import type { LeagueMemberDTO } from '@/lib/types/generated/LeagueMemberDTO';
|
|
|
|
interface LeagueStandingsApiDto {
|
|
standings: LeagueStandingDTO[];
|
|
}
|
|
|
|
interface LeagueMembershipsApiDto {
|
|
members: LeagueMemberDTO[];
|
|
}
|
|
|
|
/**
|
|
* LeagueStandingsViewDataBuilder
|
|
*
|
|
* Transforms API DTOs into LeagueStandingsViewData for server-side rendering.
|
|
* Deterministic; side-effect free; no HTTP calls.
|
|
*/
|
|
export class LeagueStandingsViewDataBuilder {
|
|
static build(
|
|
standingsDto: LeagueStandingsApiDto,
|
|
membershipsDto: LeagueMembershipsApiDto,
|
|
leagueId: string
|
|
): LeagueStandingsViewData {
|
|
const standings = standingsDto.standings || [];
|
|
const members = membershipsDto.members || [];
|
|
|
|
// Convert LeagueStandingDTO to StandingEntryData
|
|
const standingData: StandingEntryData[] = standings.map(standing => ({
|
|
driverId: standing.driverId,
|
|
position: standing.position,
|
|
totalPoints: standing.points,
|
|
racesFinished: standing.races,
|
|
racesStarted: standing.races,
|
|
avgFinish: null, // Not in DTO
|
|
penaltyPoints: 0, // Not in DTO
|
|
bonusPoints: 0, // Not in DTO
|
|
}));
|
|
|
|
// Extract unique drivers from standings
|
|
const driverMap = new Map<string, DriverData>();
|
|
standings.forEach(standing => {
|
|
if (standing.driver && !driverMap.has(standing.driver.id)) {
|
|
const driver = standing.driver;
|
|
driverMap.set(driver.id, {
|
|
id: driver.id,
|
|
name: driver.name,
|
|
avatarUrl: null, // DTO may not have this
|
|
iracingId: driver.iracingId,
|
|
rating: undefined,
|
|
country: driver.country,
|
|
});
|
|
}
|
|
});
|
|
const driverData: DriverData[] = Array.from(driverMap.values());
|
|
|
|
// Convert LeagueMemberDTO to LeagueMembershipData
|
|
const membershipData: LeagueMembershipData[] = members.map(member => ({
|
|
driverId: member.driverId,
|
|
leagueId: leagueId,
|
|
role: (member.role as LeagueMembershipData['role']) || 'member',
|
|
joinedAt: member.joinedAt,
|
|
status: 'active' as const,
|
|
}));
|
|
|
|
return {
|
|
standings: standingData,
|
|
drivers: driverData,
|
|
memberships: membershipData,
|
|
leagueId,
|
|
currentDriverId: null, // Would need to get from auth
|
|
isAdmin: false, // Would need to check permissions
|
|
};
|
|
}
|
|
} |