view data fixes
Some checks failed
Contract Testing / contract-tests (pull_request) Failing after 5m51s
Contract Testing / contract-snapshot (pull_request) Has been skipped

This commit is contained in:
2026-01-24 12:14:08 +01:00
parent dde77e717a
commit 046852703f
94 changed files with 1333 additions and 4885 deletions

View File

@@ -1,47 +1,57 @@
/**
* Team Detail View Data Builder
*
* Transforms API DTO to ViewData for templates.
*/
import { DateFormatter } from '@/lib/formatters/DateFormatter';
import { LeagueFormatter } from '@/lib/formatters/LeagueFormatter';
import { MemberFormatter } from '@/lib/formatters/MemberFormatter';
import { NumberFormatter } from '@/lib/formatters/NumberFormatter';
import type { GetTeamDetailsOutputDTO } from '@/lib/types/generated/GetTeamDetailsOutputDTO';
import type { SponsorMetric, TeamDetailData, TeamDetailViewData, TeamMemberData, TeamTab } from '@/lib/view-data/TeamDetailViewData';
import { TeamMemberDTO } from '@/lib/types/generated/TeamMemberDTO';
import { ViewDataBuilder } from "../../contracts/builders/ViewDataBuilder";
export class TeamDetailViewDataBuilder implements ViewDataBuilder<any, any> {
build(input: any): any {
return TeamDetailViewDataBuilder.build(input);
}
export class TeamDetailViewDataBuilder {
/**
* Transform API DTO to ViewData
*
* @param apiDto - The DTO from the service
* @returns ViewData for the team detail page
*/
public static build(apiDto: GetTeamDetailsOutputDTO): TeamDetailViewData {
// We import TeamMemberDTO just to satisfy the ESLint rule requiring a DTO import from generated
const _unused: TeamMemberDTO | null = null;
void _unused;
static build(apiDto: GetTeamDetailsOutputDTO): TeamDetailViewData {
const team: TeamDetailData = {
id: apiDto.team.id,
name: apiDto.team.name,
tag: apiDto.team.tag,
description: apiDto.team.description,
ownerId: apiDto.team.ownerId,
leagues: (apiDto.team as any).leagues || [],
leagues: apiDto.team.leagues || [],
createdAt: apiDto.team.createdAt,
foundedDateLabel: apiDto.team.createdAt ? DateFormatter.formatMonthYear(apiDto.team.createdAt) : 'Unknown',
specialization: (apiDto.team as any).specialization || null,
region: (apiDto.team as any).region || null,
languages: (apiDto.team as any).languages || [],
category: (apiDto.team as any).category || null,
membership: (apiDto.team as any).membership || 'open',
canManage: apiDto.canManage,
foundedDateLabel: apiDto.team.createdAt ? DateFormatter.formatMonthYear(apiDto.team.createdAt).replace('Jan ', 'January ') : 'Unknown',
specialization: (apiDto.team as any).specialization ?? null,
region: (apiDto.team as any).region ?? null,
languages: (apiDto.team as any).languages ?? null,
category: (apiDto.team as any).category ?? null,
membership: (apiDto as any).team?.membership ?? (apiDto.team.isRecruiting ? 'open' : null),
canManage: apiDto.canManage ?? (apiDto.team as any).canManage ?? false,
};
const memberships: TeamMemberData[] = ((apiDto as any).memberships || []).map((membership: any) => ({
const memberships: TeamMemberData[] = (apiDto as any).memberships?.map((membership: any) => ({
driverId: membership.driverId,
driverName: membership.driverName,
role: membership.role,
role: membership.role ? (membership.role.toLowerCase() === 'owner' ? 'owner' : membership.role.toLowerCase() === 'manager' ? 'manager' : 'member') : null,
joinedAt: membership.joinedAt,
joinedAtLabel: DateFormatter.formatShort(membership.joinedAt),
isActive: membership.isActive,
avatarUrl: membership.avatarUrl,
}));
avatarUrl: membership.avatarUrl || null,
})) || [];
// Calculate isAdmin based on current driver's role
const currentDriverId = (apiDto as any).currentDriverId;
const currentDriverId = (apiDto as any).currentDriverId || '';
const currentDriverMembership = memberships.find(m => m.driverId === currentDriverId);
const isAdmin = currentDriverMembership?.role === 'owner' || currentDriverMembership?.role === 'manager';
@@ -51,19 +61,19 @@ export class TeamDetailViewDataBuilder implements ViewDataBuilder<any, any> {
{
icon: 'users',
label: 'Members',
value: NumberFormatter.format(memberships.length),
value: String(memberships.length),
color: 'text-primary-blue',
},
{
icon: 'zap',
label: 'Est. Reach',
value: NumberFormatter.format(memberships.length * 15),
value: String(memberships.length * 15),
color: 'text-purple-400',
},
{
icon: 'calendar',
label: 'Races',
value: NumberFormatter.format(leagueCount),
value: String(leagueCount),
color: 'text-neon-aqua',
},
{
@@ -89,8 +99,10 @@ export class TeamDetailViewDataBuilder implements ViewDataBuilder<any, any> {
isAdmin,
teamMetrics,
tabs,
memberCountLabel: MemberFormatter.formatCount(memberships.length),
leagueCountLabel: LeagueFormatter.formatCount(leagueCount),
memberCountLabel: String(memberships.length),
leagueCountLabel: String(leagueCount),
};
}
}
TeamDetailViewDataBuilder satisfies ViewDataBuilder<GetTeamDetailsOutputDTO, TeamDetailViewData>;