111 lines
3.1 KiB
TypeScript
111 lines
3.1 KiB
TypeScript
/**
|
|
* AllLeaguesWithCapacityAndScoringPresenter - Pure data transformer
|
|
* Transforms API response to view model without DI dependencies.
|
|
*/
|
|
|
|
import { apiClient, type AllLeaguesWithCapacityViewModel } from '@/lib/apiClient';
|
|
|
|
export interface LeagueScoringViewModel {
|
|
gameId: string;
|
|
gameName: string;
|
|
primaryChampionshipType: string;
|
|
scoringPresetId: string;
|
|
scoringPresetName: string;
|
|
dropPolicySummary: string;
|
|
scoringPatternSummary: string;
|
|
}
|
|
|
|
export interface LeagueSummaryViewModel {
|
|
id: string;
|
|
name: string;
|
|
description?: string | undefined;
|
|
ownerId: string;
|
|
createdAt: string;
|
|
maxDrivers: number;
|
|
usedDriverSlots: number;
|
|
maxTeams: number;
|
|
usedTeamSlots: number;
|
|
structureSummary: string;
|
|
scoringPatternSummary: string;
|
|
timingSummary: string;
|
|
scoring: LeagueScoringViewModel;
|
|
}
|
|
|
|
export interface AllLeaguesWithCapacityAndScoringViewModel {
|
|
leagues: LeagueSummaryViewModel[];
|
|
totalCount: number;
|
|
}
|
|
|
|
export interface IAllLeaguesWithCapacityAndScoringPresenter {
|
|
reset(): void;
|
|
getViewModel(): AllLeaguesWithCapacityAndScoringViewModel | null;
|
|
}
|
|
|
|
/**
|
|
* Transform API response to view model
|
|
*/
|
|
function transformApiResponse(apiResponse: AllLeaguesWithCapacityViewModel): AllLeaguesWithCapacityAndScoringViewModel {
|
|
const leagueItems: LeagueSummaryViewModel[] = apiResponse.leagues.map((league) => {
|
|
const maxDrivers = league.maxMembers;
|
|
const usedDriverSlots = league.memberCount;
|
|
const structureSummary = `Solo • ${maxDrivers} drivers`;
|
|
const timingSummary = '30 min Quali • 40 min Race';
|
|
const scoringPatternSummary = 'Custom • All results count';
|
|
|
|
const scoringSummary: LeagueScoringViewModel = {
|
|
gameId: 'unknown',
|
|
gameName: 'Unknown',
|
|
primaryChampionshipType: 'driver',
|
|
scoringPresetId: 'custom',
|
|
scoringPresetName: 'Custom',
|
|
dropPolicySummary: 'All results count',
|
|
scoringPatternSummary,
|
|
};
|
|
|
|
return {
|
|
id: league.id,
|
|
name: league.name,
|
|
description: league.description,
|
|
ownerId: league.ownerId,
|
|
createdAt: new Date().toISOString(), // Would need from API
|
|
maxDrivers,
|
|
usedDriverSlots,
|
|
maxTeams: 0,
|
|
usedTeamSlots: 0,
|
|
structureSummary,
|
|
scoringPatternSummary,
|
|
timingSummary,
|
|
scoring: scoringSummary,
|
|
};
|
|
});
|
|
|
|
return {
|
|
leagues: leagueItems,
|
|
totalCount: leagueItems.length,
|
|
};
|
|
}
|
|
|
|
export class AllLeaguesWithCapacityAndScoringPresenter implements IAllLeaguesWithCapacityAndScoringPresenter {
|
|
private viewModel: AllLeaguesWithCapacityAndScoringViewModel | null = null;
|
|
|
|
reset(): void {
|
|
this.viewModel = null;
|
|
}
|
|
|
|
async fetchAndPresent(): Promise<void> {
|
|
const apiResponse = await apiClient.leagues.getAllWithCapacity();
|
|
this.viewModel = transformApiResponse(apiResponse);
|
|
}
|
|
|
|
getViewModel(): AllLeaguesWithCapacityAndScoringViewModel | null {
|
|
return this.viewModel;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convenience function to fetch and transform all leagues
|
|
*/
|
|
export async function fetchAllLeaguesWithCapacityAndScoring(): Promise<AllLeaguesWithCapacityAndScoringViewModel> {
|
|
const apiResponse = await apiClient.leagues.getAllWithCapacity();
|
|
return transformApiResponse(apiResponse);
|
|
} |