Files
gridpilot.gg/apps/website/lib/services/dashboard/DashboardService.ts
2026-01-11 13:04:33 +01:00

113 lines
4.0 KiB
TypeScript

import { DashboardOverviewViewModel } from '../../view-models/DashboardOverviewViewModel';
import { DashboardApiClient } from '../../api/dashboard/DashboardApiClient';
import type { DashboardOverviewDTO } from '../../types/generated/DashboardOverviewDTO';
import type { DashboardOverviewViewModelData } from '../../view-models/DashboardOverviewViewModelData';
/**
* Dashboard Service
*
* Orchestrates dashboard operations by coordinating API calls and view model creation.
* All dependencies are injected via constructor.
*/
export class DashboardService {
constructor(
private readonly apiClient: DashboardApiClient
) {}
/**
* Get dashboard overview data with view model transformation
* Returns the ViewModel for backward compatibility
*/
async getDashboardOverview(): Promise<DashboardOverviewViewModel> {
const dto = await this.apiClient.getDashboardOverview();
// Convert DTO to ViewModelData format for the ViewModel
const viewModelData: DashboardOverviewViewModelData = {
currentDriver: dto.currentDriver ? {
id: dto.currentDriver.id,
name: dto.currentDriver.name,
avatarUrl: dto.currentDriver.avatarUrl || '',
country: dto.currentDriver.country,
totalRaces: dto.currentDriver.totalRaces,
wins: dto.currentDriver.wins,
podiums: dto.currentDriver.podiums,
rating: dto.currentDriver.rating ?? 0,
globalRank: dto.currentDriver.globalRank ?? 0,
consistency: dto.currentDriver.consistency ?? 0,
} : undefined,
myUpcomingRaces: dto.myUpcomingRaces.map(race => ({
id: race.id,
track: race.track,
car: race.car,
scheduledAt: new Date(race.scheduledAt).toISOString(),
status: race.status,
isMyLeague: race.isMyLeague,
})),
otherUpcomingRaces: dto.otherUpcomingRaces.map(race => ({
id: race.id,
track: race.track,
car: race.car,
scheduledAt: new Date(race.scheduledAt).toISOString(),
status: race.status,
isMyLeague: race.isMyLeague,
})),
upcomingRaces: dto.upcomingRaces.map(race => ({
id: race.id,
track: race.track,
car: race.car,
scheduledAt: new Date(race.scheduledAt).toISOString(),
status: race.status,
isMyLeague: race.isMyLeague,
})),
activeLeaguesCount: dto.activeLeaguesCount,
nextRace: dto.nextRace ? {
id: dto.nextRace.id,
track: dto.nextRace.track,
car: dto.nextRace.car,
scheduledAt: new Date(dto.nextRace.scheduledAt).toISOString(),
status: dto.nextRace.status,
isMyLeague: dto.nextRace.isMyLeague,
} : undefined,
recentResults: dto.recentResults.map(result => ({
id: result.raceId,
track: result.raceName,
car: '',
position: result.position,
date: new Date(result.finishedAt).toISOString(),
})),
leagueStandingsSummaries: dto.leagueStandingsSummaries.map(standing => ({
leagueId: standing.leagueId,
leagueName: standing.leagueName,
position: standing.position,
points: standing.points,
totalDrivers: standing.totalDrivers,
})),
feedSummary: {
notificationCount: dto.feedSummary.notificationCount,
items: dto.feedSummary.items.map(item => ({
id: item.id,
type: item.type,
headline: item.headline,
body: item.body,
timestamp: new Date(item.timestamp).toISOString(),
ctaHref: item.ctaHref,
ctaLabel: item.ctaLabel,
})),
},
friends: dto.friends.map(friend => ({
id: friend.id,
name: friend.name,
avatarUrl: friend.avatarUrl || '',
country: friend.country,
})),
};
return new DashboardOverviewViewModel(viewModelData);
}
/**
* Get raw DTO for page queries
*/
async getDashboardOverviewDTO(): Promise<DashboardOverviewDTO> {
return await this.apiClient.getDashboardOverview();
}
}