100 lines
3.7 KiB
TypeScript
100 lines
3.7 KiB
TypeScript
import type { GetLeagueFullConfigResult } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
|
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
|
import { LeagueConfigFormModelDTO } from '../dtos/LeagueConfigFormModelDTO';
|
|
|
|
export class LeagueConfigPresenter implements UseCaseOutputPort<GetLeagueFullConfigResult> {
|
|
private result: LeagueConfigFormModelDTO | null = null;
|
|
|
|
reset() {
|
|
this.result = null;
|
|
}
|
|
|
|
present(result: GetLeagueFullConfigResult): void {
|
|
const dto = result.config as unknown as {
|
|
league: { id: string; name: string; description: string; settings: { pointsSystem: string } };
|
|
activeSeason?: {
|
|
stewardingConfig?: {
|
|
decisionMode: string;
|
|
requireDefense: boolean;
|
|
defenseTimeLimit: number;
|
|
voteTimeLimit: number;
|
|
protestDeadlineHours: number;
|
|
stewardingClosesHours: number;
|
|
notifyAccusedOnProtest: boolean;
|
|
notifyOnVoteRequired: boolean;
|
|
requiredVotes?: number;
|
|
};
|
|
dropPolicy?: { strategy: string; n?: number };
|
|
schedule?: {
|
|
startDate?: Date;
|
|
timeOfDay?: { hour: number; minute: number };
|
|
};
|
|
};
|
|
scoringConfig?: { championships: { sessionTypes: string[]; pointsTableBySessionType: Record<string, { getPointsForPosition: (pos: number) => number }> }[] };
|
|
};
|
|
const league = dto.league;
|
|
const settings = league.settings;
|
|
const stewarding = dto.activeSeason?.stewardingConfig;
|
|
const dropPolicy = dto.activeSeason?.dropPolicy;
|
|
const schedule = dto.activeSeason?.schedule;
|
|
const scoringConfig = dto.scoringConfig;
|
|
|
|
const visibility: 'public' | 'private' = 'public';
|
|
|
|
const championships = scoringConfig?.championships ?? [];
|
|
|
|
const firstChampionship = championships[0];
|
|
const firstSessionType = firstChampionship?.sessionTypes[0];
|
|
const firstPointsTable = firstSessionType
|
|
? firstChampionship.pointsTableBySessionType[firstSessionType]
|
|
: undefined;
|
|
const pointsForWin = firstPointsTable?.getPointsForPosition(1) ?? 0;
|
|
|
|
const raceDayOfWeek = schedule?.startDate
|
|
? schedule.startDate.toLocaleDateString('en-US', { weekday: 'long' }).toLowerCase()
|
|
: 'sunday';
|
|
const raceTimeHour = schedule?.timeOfDay?.hour ?? 20;
|
|
const raceTimeMinute = schedule?.timeOfDay?.minute ?? 0;
|
|
|
|
this.result = {
|
|
leagueId: league.id,
|
|
basics: {
|
|
name: league.name,
|
|
description: league.description,
|
|
visibility,
|
|
},
|
|
structure: {
|
|
mode: 'solo',
|
|
},
|
|
championships,
|
|
scoring: {
|
|
type: settings.pointsSystem,
|
|
points: pointsForWin,
|
|
},
|
|
dropPolicy: {
|
|
strategy: dropPolicy?.strategy === 'none' ? 'none' : 'worst_n',
|
|
...(dropPolicy?.n !== undefined ? { n: dropPolicy.n } : {}),
|
|
},
|
|
timings: {
|
|
raceDayOfWeek,
|
|
raceTimeHour,
|
|
raceTimeMinute,
|
|
},
|
|
stewarding: {
|
|
decisionMode: stewarding?.decisionMode === 'steward_vote' ? 'committee_vote' : 'single_steward',
|
|
requireDefense: stewarding?.requireDefense ?? false,
|
|
defenseTimeLimit: stewarding?.defenseTimeLimit ?? 48,
|
|
voteTimeLimit: stewarding?.voteTimeLimit ?? 72,
|
|
protestDeadlineHours: stewarding?.protestDeadlineHours ?? 48,
|
|
stewardingClosesHours: stewarding?.stewardingClosesHours ?? 168,
|
|
notifyAccusedOnProtest: stewarding?.notifyAccusedOnProtest ?? true,
|
|
notifyOnVoteRequired: stewarding?.notifyOnVoteRequired ?? true,
|
|
...(stewarding?.requiredVotes !== undefined ? { requiredVotes: stewarding.requiredVotes } : {}),
|
|
},
|
|
};
|
|
}
|
|
|
|
getViewModel(): LeagueConfigFormModelDTO | null {
|
|
return this.result;
|
|
}
|
|
} |