80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
|
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
|
import { TeamsApiClient } from '@/lib/api/teams/TeamsApiClient';
|
|
import type { LeagueSummaryDTO } from '@/lib/types/generated/LeagueSummaryDTO';
|
|
import type { GetAllTeamsOutputDTO, TeamListItemDTO } from '@/lib/types/generated/GetAllTeamsOutputDTO';
|
|
import { RacesPageViewModel } from '@/lib/view-models/RacesPageViewModel';
|
|
import { HomeDiscoveryViewModel } from '@/lib/view-models/HomeDiscoveryViewModel';
|
|
import { LeagueCardViewModel } from '@/lib/view-models/LeagueCardViewModel';
|
|
import { TeamCardViewModel } from '@/lib/view-models/TeamCardViewModel';
|
|
import { UpcomingRaceCardViewModel } from '@/lib/view-models/UpcomingRaceCardViewModel';
|
|
|
|
// DTO matching backend RacesPageDataDTO for discovery usage
|
|
interface RacesPageDataDTO {
|
|
races: {
|
|
id: string;
|
|
track: string;
|
|
car: string;
|
|
scheduledAt: string;
|
|
status: string;
|
|
leagueId: string;
|
|
leagueName: string;
|
|
strengthOfField: number | null;
|
|
isUpcoming: boolean;
|
|
isLive: boolean;
|
|
isPast: boolean;
|
|
}[];
|
|
}
|
|
|
|
export class LandingService {
|
|
constructor(
|
|
private readonly racesApi: RacesApiClient,
|
|
private readonly leaguesApi: LeaguesApiClient,
|
|
private readonly teamsApi: TeamsApiClient,
|
|
) {}
|
|
|
|
async getHomeDiscovery(): Promise<HomeDiscoveryViewModel> {
|
|
const [racesDto, leaguesDto, teamsDto] = await Promise.all([
|
|
this.racesApi.getPageData() as Promise<RacesPageDataDTO>,
|
|
this.leaguesApi.getAllWithCapacity() as Promise<{ leagues: LeagueSummaryDTO[] }>,
|
|
this.teamsApi.getAll(),
|
|
]);
|
|
|
|
const racesVm = new RacesPageViewModel(racesDto);
|
|
|
|
const topLeagues = leaguesDto.leagues.slice(0, 4).map(
|
|
league => new LeagueCardViewModel({
|
|
id: league.id,
|
|
name: league.name,
|
|
description: 'Competitive iRacing league',
|
|
}),
|
|
);
|
|
|
|
const teams = (teamsDto as GetAllTeamsOutputDTO).teams.slice(0, 4).map(
|
|
(team: TeamListItemDTO) =>
|
|
new TeamCardViewModel({
|
|
id: team.id,
|
|
name: team.name,
|
|
tag: team.tag,
|
|
description: team.description,
|
|
}),
|
|
);
|
|
|
|
const upcomingRaces = racesVm.upcomingRaces.slice(0, 4).map(
|
|
race =>
|
|
new UpcomingRaceCardViewModel({
|
|
id: race.id,
|
|
track: race.track,
|
|
car: race.car,
|
|
scheduledAt: race.scheduledAt,
|
|
}),
|
|
);
|
|
|
|
return new HomeDiscoveryViewModel({
|
|
topLeagues,
|
|
teams,
|
|
upcomingRaces,
|
|
});
|
|
}
|
|
}
|