Files
gridpilot.gg/apps/website/lib/builders/view-data/TeamDetailViewDataBuilder.ts
2026-01-19 00:46:46 +01:00

93 lines
3.1 KiB
TypeScript

import type { TeamDetailPageDto } from '@/lib/page-queries/TeamDetailPageQuery';
import type { TeamDetailViewData, TeamDetailData, TeamMemberData, SponsorMetric, TeamTab } from '@/lib/view-data/TeamDetailViewData';
import { DateDisplay } from '@/lib/display-objects/DateDisplay';
import { MemberDisplay } from '@/lib/display-objects/MemberDisplay';
import { LeagueDisplay } from '@/lib/display-objects/LeagueDisplay';
/**
* TeamDetailViewDataBuilder - Transforms TeamDetailPageDto into ViewData
* Deterministic; side-effect free; no HTTP calls
*/
export class TeamDetailViewDataBuilder {
static build(apiDto: TeamDetailPageDto): 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.leagues,
createdAt: apiDto.team.createdAt,
foundedDateLabel: apiDto.team.createdAt ? DateDisplay.formatMonthYear(apiDto.team.createdAt) : 'Unknown',
specialization: apiDto.team.specialization,
region: apiDto.team.region,
languages: apiDto.team.languages,
category: apiDto.team.category,
membership: apiDto.team.membership,
canManage: apiDto.team.canManage,
};
const memberships: TeamMemberData[] = apiDto.memberships.map((membership) => ({
driverId: membership.driverId,
driverName: membership.driverName,
role: membership.role,
joinedAt: membership.joinedAt,
joinedAtLabel: DateDisplay.formatShort(membership.joinedAt),
isActive: membership.isActive,
avatarUrl: membership.avatarUrl,
}));
// Calculate isAdmin based on current driver's role
const currentDriverMembership = memberships.find(m => m.driverId === apiDto.currentDriverId);
const isAdmin = currentDriverMembership?.role === 'owner' || currentDriverMembership?.role === 'manager';
// Build sponsor metrics
const leagueCount = team.leagues?.length ?? 0;
const teamMetrics: SponsorMetric[] = [
{
icon: 'users',
label: 'Members',
value: memberships.length,
color: 'text-primary-blue',
},
{
icon: 'zap',
label: 'Est. Reach',
value: memberships.length * 15,
color: 'text-purple-400',
},
{
icon: 'calendar',
label: 'Races',
value: leagueCount,
color: 'text-neon-aqua',
},
{
icon: 'users',
label: 'Engagement',
value: '82%',
color: 'text-performance-green',
},
];
// Build tabs
const tabs: TeamTab[] = [
{ id: 'overview', label: 'Overview', visible: true },
{ id: 'roster', label: 'Roster', visible: true },
{ id: 'standings', label: 'Standings', visible: true },
{ id: 'admin', label: 'Admin', visible: isAdmin },
];
return {
team,
memberships,
currentDriverId: apiDto.currentDriverId,
isAdmin,
teamMetrics,
tabs,
memberCountLabel: MemberDisplay.formatCount(memberships.length),
leagueCountLabel: LeagueDisplay.formatCount(leagueCount),
};
}
}