96 lines
3.4 KiB
TypeScript
96 lines
3.4 KiB
TypeScript
import { LeaguesApiClient } from "@/lib/api/leagues/LeaguesApiClient";
|
|
import { CreateLeagueInputDTO } from "@/lib/types/generated/CreateLeagueInputDTO";
|
|
import { LeagueWithCapacityDTO } from "@/lib/types/generated/LeagueWithCapacityDTO";
|
|
import { CreateLeagueViewModel } from "@/lib/view-models/CreateLeagueViewModel";
|
|
import { LeagueMembershipsViewModel } from "@/lib/view-models/LeagueMembershipsViewModel";
|
|
import { LeagueScheduleViewModel } from "@/lib/view-models/LeagueScheduleViewModel";
|
|
import { LeagueStandingsViewModel } from "@/lib/view-models/LeagueStandingsViewModel";
|
|
import { LeagueStatsViewModel } from "@/lib/view-models/LeagueStatsViewModel";
|
|
import { LeagueSummaryViewModel } from "@/lib/view-models/LeagueSummaryViewModel";
|
|
import { RemoveMemberViewModel } from "@/lib/view-models/RemoveMemberViewModel";
|
|
import { SubmitBlocker, ThrottleBlocker } from "@/lib/blockers";
|
|
|
|
|
|
/**
|
|
* League Service
|
|
*
|
|
* Orchestrates league operations by coordinating API calls and view model creation.
|
|
* All dependencies are injected via constructor.
|
|
*/
|
|
export class LeagueService {
|
|
private readonly submitBlocker = new SubmitBlocker();
|
|
private readonly throttle = new ThrottleBlocker(500);
|
|
|
|
constructor(
|
|
private readonly apiClient: LeaguesApiClient
|
|
) {}
|
|
|
|
/**
|
|
* Get all leagues with view model transformation
|
|
*/
|
|
async getAllLeagues(): Promise<LeagueSummaryViewModel[]> {
|
|
const dto = await this.apiClient.getAllWithCapacity();
|
|
return dto.leagues.map((league: LeagueWithCapacityDTO) => new LeagueSummaryViewModel(league));
|
|
}
|
|
|
|
/**
|
|
* Get league standings with view model transformation
|
|
*/
|
|
async getLeagueStandings(leagueId: string, currentUserId: string): Promise<LeagueStandingsViewModel> {
|
|
const dto = await this.apiClient.getStandings(leagueId);
|
|
// TODO: include drivers and memberships in dto
|
|
const dtoWithExtras = {
|
|
...dto,
|
|
drivers: [], // TODO: fetch drivers
|
|
memberships: [], // TODO: fetch memberships
|
|
};
|
|
return new LeagueStandingsViewModel(dtoWithExtras, currentUserId);
|
|
}
|
|
|
|
/**
|
|
* Get league statistics
|
|
*/
|
|
async getLeagueStats(): Promise<LeagueStatsViewModel> {
|
|
const dto = await this.apiClient.getTotal();
|
|
return new LeagueStatsViewModel(dto);
|
|
}
|
|
|
|
/**
|
|
* Get league schedule
|
|
*/
|
|
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleViewModel> {
|
|
const dto = await this.apiClient.getSchedule(leagueId);
|
|
return new LeagueScheduleViewModel(dto);
|
|
}
|
|
|
|
/**
|
|
* Get league memberships
|
|
*/
|
|
async getLeagueMemberships(leagueId: string, currentUserId: string): Promise<LeagueMembershipsViewModel> {
|
|
const dto = await this.apiClient.getMemberships(leagueId);
|
|
return new LeagueMembershipsViewModel(dto, currentUserId);
|
|
}
|
|
|
|
/**
|
|
* Create a new league
|
|
*/
|
|
async createLeague(input: CreateLeagueInputDTO): Promise<void> {
|
|
if (!this.submitBlocker.canExecute() || !this.throttle.canExecute()) return;
|
|
|
|
this.submitBlocker.block();
|
|
this.throttle.block();
|
|
try {
|
|
await this.apiClient.create(input);
|
|
} finally {
|
|
this.submitBlocker.release();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove a member from league
|
|
*/
|
|
async removeMember(leagueId: string, performerDriverId: string, targetDriverId: string): Promise<RemoveMemberViewModel> {
|
|
const dto = await this.apiClient.removeMember(leagueId, performerDriverId, targetDriverId);
|
|
return new RemoveMemberViewModel(dto);
|
|
}
|
|
} |