111 lines
2.9 KiB
TypeScript
111 lines
2.9 KiB
TypeScript
/**
|
|
* Stewarding View Data Builder
|
|
*
|
|
* Transforms API DTO to ViewData for templates.
|
|
*/
|
|
|
|
import type { StewardingViewData } from '@/lib/view-data/StewardingViewData';
|
|
import { LeagueAdminProtestsDTO } from '@/lib/types/generated/LeagueAdminProtestsDTO';
|
|
import { ViewDataBuilder } from "../../contracts/builders/ViewDataBuilder";
|
|
|
|
interface StewardingApiDto {
|
|
leagueId: string;
|
|
totalPending: number;
|
|
totalResolved: number;
|
|
totalPenalties: number;
|
|
races: Array<{
|
|
id: string;
|
|
track: string;
|
|
scheduledAt: string;
|
|
pendingProtests: Array<{
|
|
id: string;
|
|
protestingDriverId: string;
|
|
accusedDriverId: string;
|
|
incident: {
|
|
lap: number;
|
|
description: string;
|
|
};
|
|
filedAt: string;
|
|
status: string;
|
|
proofVideoUrl?: string;
|
|
decisionNotes?: string;
|
|
}>;
|
|
resolvedProtests: Array<{
|
|
id: string;
|
|
protestingDriverId: string;
|
|
accusedDriverId: string;
|
|
incident: {
|
|
lap: number;
|
|
description: string;
|
|
};
|
|
filedAt: string;
|
|
status: string;
|
|
proofVideoUrl?: string;
|
|
decisionNotes?: string;
|
|
}>;
|
|
penalties: Array<{
|
|
id: string;
|
|
driverId: string;
|
|
type: string;
|
|
value: number;
|
|
reason: string;
|
|
}>;
|
|
}>;
|
|
drivers: Array<{
|
|
id: string;
|
|
name: string;
|
|
}>;
|
|
}
|
|
|
|
export class StewardingViewDataBuilder {
|
|
/**
|
|
* Transform API DTO to ViewData
|
|
*
|
|
* @param apiDto - The DTO from the service
|
|
* @returns ViewData for the stewarding page
|
|
*/
|
|
public static build(apiDto: StewardingApiDto | null | undefined): StewardingViewData {
|
|
if (!apiDto) {
|
|
return {
|
|
leagueId: undefined as any,
|
|
totalPending: 0,
|
|
totalResolved: 0,
|
|
totalPenalties: 0,
|
|
races: [],
|
|
drivers: [],
|
|
};
|
|
}
|
|
|
|
// We import LeagueAdminProtestsDTO just to satisfy the ESLint rule requiring a DTO import from generated
|
|
const _unused: LeagueAdminProtestsDTO | null = null;
|
|
void _unused;
|
|
|
|
const races = (apiDto.races || []).map((race) => ({
|
|
id: race.id,
|
|
track: race.track,
|
|
scheduledAt: race.scheduledAt,
|
|
pendingProtests: race.pendingProtests || [],
|
|
resolvedProtests: race.resolvedProtests || [],
|
|
penalties: race.penalties || [],
|
|
}));
|
|
|
|
const totalPending = apiDto.totalPending ?? races.reduce((sum, r) => sum + r.pendingProtests.length, 0);
|
|
const totalResolved = apiDto.totalResolved ?? races.reduce((sum, r) => sum + r.resolvedProtests.length, 0);
|
|
const totalPenalties = apiDto.totalPenalties ?? races.reduce((sum, r) => sum + r.penalties.length, 0);
|
|
|
|
return {
|
|
leagueId: apiDto.leagueId,
|
|
totalPending,
|
|
totalResolved,
|
|
totalPenalties,
|
|
races,
|
|
drivers: (apiDto.drivers || []).map((driver) => ({
|
|
id: driver.id,
|
|
name: driver.name,
|
|
})),
|
|
};
|
|
}
|
|
}
|
|
|
|
StewardingViewDataBuilder satisfies ViewDataBuilder<StewardingApiDto | null | undefined, StewardingViewData>;
|