This commit is contained in:
2025-12-16 10:50:15 +01:00
parent 775d41e055
commit 8ed6ba1fd1
144 changed files with 5763 additions and 1985 deletions

View File

@@ -1,8 +1,53 @@
import type {
ITeamDetailsPresenter,
TeamDetailsViewModel,
TeamDetailsResultDTO,
} from '@gridpilot/racing/application/presenters/ITeamDetailsPresenter';
/**
* TeamDetailsPresenter - Pure data transformer
* Transforms API response to view model without DI dependencies.
*/
import { apiClient, type TeamDetailsViewModel as ApiTeamDetailsViewModel } from '@/lib/apiClient';
export interface TeamMembershipViewModel {
role: string;
joinedAt: string;
isActive: boolean;
}
export interface TeamInfoViewModel {
id: string;
name: string;
tag?: string | undefined;
description?: string | undefined;
ownerId: string;
leagues?: string[] | undefined;
createdAt: string;
}
export interface TeamDetailsViewModel {
team: TeamInfoViewModel;
membership: TeamMembershipViewModel | null;
canManage: boolean;
}
export interface ITeamDetailsPresenter {
reset(): void;
getViewModel(): TeamDetailsViewModel | null;
}
/**
* Transform API response to view model
*/
function transformApiResponse(apiResponse: ApiTeamDetailsViewModel): TeamDetailsViewModel {
return {
team: {
id: apiResponse.id,
name: apiResponse.name,
description: apiResponse.description,
ownerId: apiResponse.ownerId,
createdAt: new Date().toISOString(), // Would need from API
},
membership: null, // Would need from API based on current user
canManage: false, // Would need from API based on current user
};
}
export class TeamDetailsPresenter implements ITeamDetailsPresenter {
private viewModel: TeamDetailsViewModel | null = null;
@@ -11,34 +56,27 @@ export class TeamDetailsPresenter implements ITeamDetailsPresenter {
this.viewModel = null;
}
present(input: TeamDetailsResultDTO): void {
const { team, membership } = input;
const canManage = membership?.role === 'owner' || membership?.role === 'manager';
const viewModel: TeamDetailsViewModel = {
team: {
id: team.id,
name: team.name,
tag: team.tag,
description: team.description,
ownerId: team.ownerId,
leagues: team.leagues,
createdAt: team.createdAt.toISOString(),
},
membership: membership
? {
role: membership.role === 'driver' ? 'member' : membership.role,
joinedAt: membership.joinedAt.toISOString(),
isActive: membership.status === 'active',
}
: null,
canManage,
};
this.viewModel = viewModel;
async fetchAndPresent(teamId: string): Promise<void> {
const apiResponse = await apiClient.teams.getDetails(teamId);
if (apiResponse) {
this.viewModel = transformApiResponse(apiResponse);
} else {
this.viewModel = null;
}
}
getViewModel(): TeamDetailsViewModel | null {
return this.viewModel;
}
}
/**
* Convenience function to fetch and transform team details
*/
export async function fetchTeamDetails(teamId: string): Promise<TeamDetailsViewModel | null> {
const apiResponse = await apiClient.teams.getDetails(teamId);
if (!apiResponse) {
return null;
}
return transformApiResponse(apiResponse);
}