Files
gridpilot.gg/apps/website/lib/presenters/LeagueStandingsPresenter.ts
2026-01-14 02:02:24 +01:00

103 lines
3.1 KiB
TypeScript

'use client';
/**
* LeagueStandingsPresenter
* Pure client-side presenter for LeagueStandingsTemplate
* Converts ViewModels to ViewData
*/
import type { Presenter } from '@/lib/contracts/presenters/Presenter';
import type { LeagueMembership } from '@/lib/types/LeagueMembership';
import type { DriverData, LeagueMembershipData, LeagueStandingsViewData, StandingEntryData } from '@/lib/view-data/LeagueStandingsViewData';
import type { DriverViewModel } from '@/lib/view-models/DriverViewModel';
import type { StandingEntryViewModel } from '@/lib/view-models/StandingEntryViewModel';
interface LeagueStandingsInput {
standings: StandingEntryViewModel[];
drivers: DriverViewModel[];
memberships: LeagueMembership[];
leagueId: string;
currentDriverId: string | null;
isAdmin: boolean;
}
export class LeagueStandingsPresenter implements Presenter<LeagueStandingsInput, LeagueStandingsViewData> {
/**
* Convert StandingEntryViewModel to StandingEntryData
*/
private static convertStanding(standing: StandingEntryViewModel): StandingEntryData {
return {
driverId: standing.driverId,
position: standing.position,
totalPoints: standing.points,
racesFinished: standing.races,
racesStarted: standing.races,
avgFinish: null, // Not available in current ViewModel
penaltyPoints: 0, // Not available in current ViewModel
bonusPoints: 0, // Not available in current ViewModel
};
}
/**
* Convert DriverViewModel to DriverData
*/
private static convertDriver(driver: DriverViewModel): DriverData {
return {
id: driver.id,
name: driver.name,
avatarUrl: driver.avatarUrl,
iracingId: driver.iracingId,
rating: driver.rating,
country: driver.country,
};
}
/**
* Convert LeagueMembership to LeagueMembershipData
*/
private static convertMembership(membership: LeagueMembership): LeagueMembershipData {
return {
driverId: membership.driverId,
leagueId: membership.leagueId,
role: membership.role,
joinedAt: membership.joinedAt,
status: membership.status,
};
}
/**
* Transform input to output
*/
present(input: LeagueStandingsInput): LeagueStandingsViewData {
return {
standings: input.standings.map(s => LeagueStandingsPresenter.convertStanding(s)),
drivers: input.drivers.map(d => LeagueStandingsPresenter.convertDriver(d)),
memberships: input.memberships.map(m => LeagueStandingsPresenter.convertMembership(m)),
leagueId: input.leagueId,
currentDriverId: input.currentDriverId,
isAdmin: input.isAdmin,
};
}
/**
* Static helper for backward compatibility
*/
static createViewData(
standings: StandingEntryViewModel[],
drivers: DriverViewModel[],
memberships: LeagueMembership[],
leagueId: string,
currentDriverId: string | null,
isAdmin: boolean
): LeagueStandingsViewData {
const presenter = new LeagueStandingsPresenter();
return presenter.present({
standings,
drivers,
memberships,
leagueId,
currentDriverId,
isAdmin,
});
}
}