presenter refactoring
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import type { CompleteDriverOnboardingOutputPort } from '@core/racing/application/ports/output/CompleteDriverOnboardingOutputPort';
|
||||
import type { CompleteOnboardingOutputDTO } from '../dtos/CompleteOnboardingOutputDTO';
|
||||
|
||||
export class CompleteOnboardingPresenter {
|
||||
private result: CompleteOnboardingOutputDTO | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(output: CompleteDriverOnboardingOutputPort): void {
|
||||
this.result = {
|
||||
success: true,
|
||||
driverId: output.driverId,
|
||||
};
|
||||
}
|
||||
|
||||
presentError(errorCode: string): void {
|
||||
this.result = {
|
||||
success: false,
|
||||
errorMessage: errorCode,
|
||||
};
|
||||
}
|
||||
|
||||
get viewModel(): CompleteOnboardingOutputDTO {
|
||||
if (!this.result) throw new Error('Presenter not presented');
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
30
apps/api/src/domain/driver/presenters/DriverPresenter.ts
Normal file
30
apps/api/src/domain/driver/presenters/DriverPresenter.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { Driver } from '@core/racing/domain/entities/Driver';
|
||||
import type { GetDriverOutputDTO } from '../dtos/GetDriverOutputDTO';
|
||||
|
||||
export class DriverPresenter {
|
||||
private result: GetDriverOutputDTO | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(driver: Driver | null): void {
|
||||
if (!driver) {
|
||||
this.result = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.result = {
|
||||
id: driver.id,
|
||||
iracingId: driver.iracingId.toString(),
|
||||
name: driver.name.toString(),
|
||||
country: driver.country.toString(),
|
||||
bio: driver.bio?.toString(),
|
||||
joinedAt: driver.joinedAt.toDate().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
get viewModel(): GetDriverOutputDTO | null {
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import type { ProfileOverviewOutputPort } from '@core/racing/application/ports/output/ProfileOverviewOutputPort';
|
||||
import type { GetDriverProfileOutputDTO } from '../dtos/GetDriverProfileOutputDTO';
|
||||
|
||||
export class DriverProfilePresenter {
|
||||
private result: GetDriverProfileOutputDTO | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(output: ProfileOverviewOutputPort): void {
|
||||
this.result = {
|
||||
currentDriver: output.driver
|
||||
? {
|
||||
id: output.driver.id,
|
||||
name: output.driver.name,
|
||||
country: output.driver.country,
|
||||
avatarUrl: output.driver.avatarUrl,
|
||||
iracingId: output.driver.iracingId,
|
||||
joinedAt: output.driver.joinedAt.toISOString(),
|
||||
rating: output.driver.rating,
|
||||
globalRank: output.driver.globalRank,
|
||||
consistency: output.driver.consistency,
|
||||
bio: output.driver.bio,
|
||||
totalDrivers: output.driver.totalDrivers,
|
||||
}
|
||||
: null,
|
||||
stats: output.stats,
|
||||
finishDistribution: output.finishDistribution,
|
||||
teamMemberships: output.teamMemberships.map(membership => ({
|
||||
teamId: membership.teamId,
|
||||
teamName: membership.teamName,
|
||||
teamTag: membership.teamTag,
|
||||
role: membership.role,
|
||||
joinedAt: membership.joinedAt.toISOString(),
|
||||
isCurrent: membership.isCurrent,
|
||||
})),
|
||||
socialSummary: output.socialSummary,
|
||||
extendedProfile: output.extendedProfile,
|
||||
};
|
||||
}
|
||||
|
||||
get viewModel(): GetDriverProfileOutputDTO {
|
||||
if (!this.result) throw new Error('Presenter not presented');
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { DriverRegistrationStatusDTO } from '../dtos/DriverRegistrationStatusDTO';
|
||||
|
||||
export class DriverRegistrationStatusPresenter {
|
||||
private result: DriverRegistrationStatusDTO | null = null;
|
||||
|
||||
reset(): void {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(isRegistered: boolean, raceId: string, driverId: string): void {
|
||||
this.result = {
|
||||
isRegistered,
|
||||
raceId,
|
||||
driverId,
|
||||
};
|
||||
}
|
||||
|
||||
get viewModel(): DriverRegistrationStatusDTO {
|
||||
if (!this.result) {
|
||||
throw new Error('Presenter not presented');
|
||||
}
|
||||
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +1,31 @@
|
||||
import { DriversLeaderboardDTO } from '../dtos/DriversLeaderboardDTO';
|
||||
import { DriverLeaderboardItemDTO } from '../dtos/DriverLeaderboardItemDTO';
|
||||
import type { IDriversLeaderboardPresenter, DriversLeaderboardResultDTO } from '../../../../../core/racing/application/presenters/IDriversLeaderboardPresenter';
|
||||
import { SkillLevelService } from '../../../../../core/racing/domain/services/SkillLevelService';
|
||||
import type { DriversLeaderboardOutputPort } from '../../../../../core/racing/application/ports/output/DriversLeaderboardOutputPort';
|
||||
|
||||
export class DriversLeaderboardPresenter implements IDriversLeaderboardPresenter {
|
||||
export class DriversLeaderboardPresenter {
|
||||
private result: DriversLeaderboardDTO | null = null;
|
||||
|
||||
reset() {
|
||||
reset(): void {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(dto: DriversLeaderboardResultDTO) {
|
||||
const drivers: DriverLeaderboardItemDTO[] = dto.drivers.map(driver => {
|
||||
const ranking = dto.rankings.find(r => r.driverId === driver.id);
|
||||
const stats = dto.stats[driver.id];
|
||||
const avatarUrl = dto.avatarUrls[driver.id];
|
||||
|
||||
const rating = ranking?.rating ?? 0;
|
||||
const racesCompleted = stats?.racesCompleted ?? 0;
|
||||
|
||||
return {
|
||||
present(output: DriversLeaderboardOutputPort): void {
|
||||
this.result = {
|
||||
drivers: output.drivers.map(driver => ({
|
||||
id: driver.id,
|
||||
name: driver.name,
|
||||
rating,
|
||||
// Use core SkillLevelService to derive band from rating
|
||||
skillLevel: SkillLevelService.getSkillLevel(rating),
|
||||
nationality: driver.country,
|
||||
racesCompleted,
|
||||
wins: stats?.wins ?? 0,
|
||||
podiums: stats?.podiums ?? 0,
|
||||
// Consider a driver active if they have completed at least one race
|
||||
isActive: racesCompleted > 0,
|
||||
rank: ranking?.overallRank ?? 0,
|
||||
avatarUrl,
|
||||
};
|
||||
});
|
||||
|
||||
// Calculate totals
|
||||
const totalRaces = drivers.reduce((sum, d) => sum + (d.racesCompleted ?? 0), 0);
|
||||
const totalWins = drivers.reduce((sum, d) => sum + (d.wins ?? 0), 0);
|
||||
const activeCount = drivers.filter(d => d.isActive).length;
|
||||
|
||||
this.result = {
|
||||
drivers: drivers.sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0)),
|
||||
totalRaces,
|
||||
totalWins,
|
||||
activeCount,
|
||||
rating: driver.rating,
|
||||
skillLevel: driver.skillLevel,
|
||||
nationality: driver.nationality,
|
||||
racesCompleted: driver.racesCompleted,
|
||||
wins: driver.wins,
|
||||
podiums: driver.podiums,
|
||||
isActive: driver.isActive,
|
||||
rank: driver.rank,
|
||||
avatarUrl: driver.avatarUrl,
|
||||
})),
|
||||
totalRaces: output.totalRaces,
|
||||
totalWins: output.totalWins,
|
||||
activeCount: output.activeCount,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user