105 lines
3.5 KiB
TypeScript
105 lines
3.5 KiB
TypeScript
import type { LeagueMembershipsViewModel } from '@/lib/view-models/LeagueMembershipsViewModel';
|
|
import type { RaceResultsDetailViewModel } from '@/lib/view-models/RaceResultsDetailViewModel';
|
|
import type { RaceWithSOFViewModel } from '@/lib/view-models/RaceWithSOFViewModel';
|
|
|
|
// TODO fucking violating our architecture, it should be a ViewModel
|
|
|
|
export interface TransformedRaceResultsData {
|
|
raceTrack?: string;
|
|
raceScheduledAt?: string;
|
|
totalDrivers?: number;
|
|
leagueName?: string;
|
|
raceSOF: number | null;
|
|
results: Array<{
|
|
position: number;
|
|
driverId: string;
|
|
driverName: string;
|
|
driverAvatar: string;
|
|
country: string;
|
|
car: string;
|
|
laps: number;
|
|
time: string;
|
|
fastestLap: string;
|
|
points: number;
|
|
incidents: number;
|
|
isCurrentUser: boolean;
|
|
}>;
|
|
penalties: Array<{
|
|
driverId: string;
|
|
driverName: string;
|
|
type: 'time_penalty' | 'grid_penalty' | 'points_deduction' | 'disqualification' | 'warning' | 'license_points';
|
|
value: number;
|
|
reason: string;
|
|
notes?: string;
|
|
}>;
|
|
pointsSystem: Record<string, number>;
|
|
fastestLapTime: number;
|
|
memberships?: Array<{
|
|
driverId: string;
|
|
role: string;
|
|
}>;
|
|
}
|
|
|
|
export class RaceResultsDataTransformer {
|
|
static transform(
|
|
resultsData: RaceResultsDetailViewModel | null,
|
|
sofData: RaceWithSOFViewModel | null,
|
|
currentDriverId: string,
|
|
membershipsData?: LeagueMembershipsViewModel
|
|
): TransformedRaceResultsData {
|
|
if (!resultsData) {
|
|
return {
|
|
raceSOF: null,
|
|
results: [],
|
|
penalties: [],
|
|
pointsSystem: {},
|
|
fastestLapTime: 0,
|
|
};
|
|
}
|
|
|
|
// Transform results
|
|
const results = resultsData.results.map((result: any) => ({
|
|
position: result.position,
|
|
driverId: result.driverId,
|
|
driverName: result.driverName,
|
|
driverAvatar: result.avatarUrl,
|
|
country: 'US', // Default since view model doesn't have car
|
|
car: 'Unknown', // Default since view model doesn't have car
|
|
laps: 0, // Default since view model doesn't have laps
|
|
time: '0:00.00', // Default since view model doesn't have time
|
|
fastestLap: result.fastestLap.toString(), // Convert number to string
|
|
points: 0, // Default since view model doesn't have points
|
|
incidents: result.incidents,
|
|
isCurrentUser: result.driverId === currentDriverId,
|
|
}));
|
|
|
|
// Transform penalties
|
|
const penalties = resultsData.penalties.map((penalty: any) => ({
|
|
driverId: penalty.driverId,
|
|
driverName: resultsData.results.find((r: any) => r.driverId === penalty.driverId)?.driverName || 'Unknown',
|
|
type: penalty.type as 'time_penalty' | 'grid_penalty' | 'points_deduction' | 'disqualification' | 'warning' | 'license_points',
|
|
value: penalty.value || 0,
|
|
reason: 'Penalty applied', // Default since view model doesn't have reason
|
|
notes: undefined, // Default since view model doesn't have notes
|
|
}));
|
|
|
|
// Transform memberships
|
|
const memberships = membershipsData?.memberships.map((membership: any) => ({
|
|
driverId: membership.driverId,
|
|
role: membership.role || 'member',
|
|
}));
|
|
|
|
return {
|
|
raceTrack: resultsData.race?.track,
|
|
raceScheduledAt: resultsData.race?.scheduledAt,
|
|
totalDrivers: resultsData.stats?.totalDrivers,
|
|
leagueName: resultsData.league?.name,
|
|
raceSOF: sofData?.strengthOfField || null,
|
|
results,
|
|
penalties,
|
|
pointsSystem: resultsData.pointsSystem || {},
|
|
fastestLapTime: resultsData.fastestLapTime || 0,
|
|
memberships,
|
|
};
|
|
}
|
|
} |