Files
gridpilot.gg/apps/website/lib/builders/view-data/StewardingViewDataBuilder.ts
Marc Mintel 046852703f
Some checks failed
Contract Testing / contract-tests (pull_request) Failing after 5m51s
Contract Testing / contract-snapshot (pull_request) Has been skipped
view data fixes
2026-01-24 12:14:08 +01:00

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>;