website refactor
This commit is contained in:
@@ -18,9 +18,9 @@ export class AdminUsersViewDataBuilder {
|
||||
roles: user.roles,
|
||||
status: user.status,
|
||||
isSystemAdmin: user.isSystemAdmin,
|
||||
createdAt: user.createdAt.toISOString(),
|
||||
updatedAt: user.updatedAt.toISOString(),
|
||||
lastLoginAt: user.lastLoginAt?.toISOString(),
|
||||
createdAt: typeof user.createdAt === 'string' ? user.createdAt : (user.createdAt as unknown as Date).toISOString(),
|
||||
updatedAt: typeof user.updatedAt === 'string' ? user.updatedAt : (user.updatedAt as unknown as Date).toISOString(),
|
||||
lastLoginAt: user.lastLoginAt ? (typeof user.lastLoginAt === 'string' ? user.lastLoginAt : (user.lastLoginAt as unknown as Date).toISOString()) : undefined,
|
||||
primaryDriverId: user.primaryDriverId,
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { DriverProfileDriverSummaryDTO } from '@/lib/types/generated/DriverProfileDriverSummaryDTO';
|
||||
import type { DriverProfileStatsDTO } from '@/lib/types/generated/DriverProfileStatsDTO';
|
||||
import type { DriverProfileFinishDistributionDTO } from '@/lib/types/generated/DriverProfileFinishDistributionDTO';
|
||||
import type { DriverProfileTeamMembershipDTO } from '@/lib/types/generated/DriverProfileTeamMembershipDTO';
|
||||
import type { DriverProfileSocialSummaryDTO } from '@/lib/types/generated/DriverProfileSocialSummaryDTO';
|
||||
import type { DriverProfileExtendedProfileDTO } from '@/lib/types/generated/DriverProfileExtendedProfileDTO';
|
||||
|
||||
export interface DriverProfileViewData {
|
||||
currentDriver: DriverProfileDriverSummaryDTO | null;
|
||||
stats: DriverProfileStatsDTO | null;
|
||||
finishDistribution: DriverProfileFinishDistributionDTO | null;
|
||||
teamMemberships: DriverProfileTeamMembershipDTO[];
|
||||
socialSummary: DriverProfileSocialSummaryDTO;
|
||||
extendedProfile: DriverProfileExtendedProfileDTO | null;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { GetDriverProfileOutputDTO } from '@/lib/types/generated/GetDriverProfileOutputDTO';
|
||||
import type { DriverProfileViewData } from './DriverProfileViewData';
|
||||
import type { DriverProfileViewData } from '@/lib/types/view-data/DriverProfileViewData';
|
||||
|
||||
/**
|
||||
* DriverProfileViewDataBuilder
|
||||
@@ -10,12 +10,82 @@ import type { DriverProfileViewData } from './DriverProfileViewData';
|
||||
export class DriverProfileViewDataBuilder {
|
||||
static build(apiDto: GetDriverProfileOutputDTO): DriverProfileViewData {
|
||||
return {
|
||||
currentDriver: apiDto.currentDriver || null,
|
||||
stats: apiDto.stats || null,
|
||||
finishDistribution: apiDto.finishDistribution || null,
|
||||
teamMemberships: apiDto.teamMemberships,
|
||||
socialSummary: apiDto.socialSummary,
|
||||
extendedProfile: apiDto.extendedProfile || null,
|
||||
currentDriver: apiDto.currentDriver ? {
|
||||
id: apiDto.currentDriver.id,
|
||||
name: apiDto.currentDriver.name,
|
||||
country: apiDto.currentDriver.country,
|
||||
avatarUrl: apiDto.currentDriver.avatarUrl || '',
|
||||
iracingId: typeof apiDto.currentDriver.iracingId === 'string' ? parseInt(apiDto.currentDriver.iracingId, 10) : (apiDto.currentDriver.iracingId ?? null),
|
||||
joinedAt: apiDto.currentDriver.joinedAt,
|
||||
rating: apiDto.currentDriver.rating ?? null,
|
||||
globalRank: apiDto.currentDriver.globalRank ?? null,
|
||||
consistency: apiDto.currentDriver.consistency ?? null,
|
||||
bio: apiDto.currentDriver.bio ?? null,
|
||||
totalDrivers: apiDto.currentDriver.totalDrivers ?? null,
|
||||
} : null,
|
||||
stats: apiDto.stats ? {
|
||||
totalRaces: apiDto.stats.totalRaces,
|
||||
wins: apiDto.stats.wins,
|
||||
podiums: apiDto.stats.podiums,
|
||||
dnfs: apiDto.stats.dnfs,
|
||||
avgFinish: apiDto.stats.avgFinish ?? null,
|
||||
bestFinish: apiDto.stats.bestFinish ?? null,
|
||||
worstFinish: apiDto.stats.worstFinish ?? null,
|
||||
finishRate: apiDto.stats.finishRate ?? null,
|
||||
winRate: apiDto.stats.winRate ?? null,
|
||||
podiumRate: apiDto.stats.podiumRate ?? null,
|
||||
percentile: apiDto.stats.percentile ?? null,
|
||||
rating: apiDto.stats.rating ?? null,
|
||||
consistency: apiDto.stats.consistency ?? null,
|
||||
overallRank: apiDto.stats.overallRank ?? null,
|
||||
} : null,
|
||||
finishDistribution: apiDto.finishDistribution ? {
|
||||
totalRaces: apiDto.finishDistribution.totalRaces,
|
||||
wins: apiDto.finishDistribution.wins,
|
||||
podiums: apiDto.finishDistribution.podiums,
|
||||
topTen: apiDto.finishDistribution.topTen,
|
||||
dnfs: apiDto.finishDistribution.dnfs,
|
||||
other: apiDto.finishDistribution.other,
|
||||
} : null,
|
||||
teamMemberships: apiDto.teamMemberships.map(m => ({
|
||||
teamId: m.teamId,
|
||||
teamName: m.teamName,
|
||||
teamTag: m.teamTag ?? null,
|
||||
role: m.role,
|
||||
joinedAt: m.joinedAt,
|
||||
isCurrent: m.isCurrent,
|
||||
})),
|
||||
socialSummary: {
|
||||
friendsCount: apiDto.socialSummary.friendsCount,
|
||||
friends: apiDto.socialSummary.friends.map(f => ({
|
||||
id: f.id,
|
||||
name: f.name,
|
||||
country: f.country,
|
||||
avatarUrl: f.avatarUrl || '',
|
||||
})),
|
||||
},
|
||||
extendedProfile: apiDto.extendedProfile ? {
|
||||
socialHandles: apiDto.extendedProfile.socialHandles.map(h => ({
|
||||
platform: h.platform,
|
||||
handle: h.handle,
|
||||
url: h.url,
|
||||
})),
|
||||
achievements: apiDto.extendedProfile.achievements.map(a => ({
|
||||
id: a.id,
|
||||
title: a.title,
|
||||
description: a.description,
|
||||
icon: a.icon,
|
||||
rarity: a.rarity,
|
||||
earnedAt: a.earnedAt,
|
||||
})),
|
||||
racingStyle: apiDto.extendedProfile.racingStyle,
|
||||
favoriteTrack: apiDto.extendedProfile.favoriteTrack,
|
||||
favoriteCar: apiDto.extendedProfile.favoriteCar,
|
||||
timezone: apiDto.extendedProfile.timezone,
|
||||
availableHours: apiDto.extendedProfile.availableHours,
|
||||
lookingForTeam: apiDto.extendedProfile.lookingForTeam,
|
||||
openToRequests: apiDto.extendedProfile.openToRequests,
|
||||
} : null,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { DriversLeaderboardDTO } from '@/lib/types/generated/DriversLeaderboardDTO';
|
||||
import type { DriverLeaderboardItemDTO } from '@/lib/types/generated/DriverLeaderboardItemDTO';
|
||||
|
||||
export interface DriversViewData {
|
||||
drivers: DriverLeaderboardItemDTO[];
|
||||
totalRaces: number;
|
||||
totalWins: number;
|
||||
activeCount: number;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ export class LeagueDetailViewDataBuilder {
|
||||
const membersCount = Array.isArray(memberships.members) ? memberships.members.length : 0;
|
||||
const completedRacesCount = races.filter(r => r.name.includes('Completed')).length; // Placeholder
|
||||
const avgSOF = races.length > 0
|
||||
? Math.round(races.reduce((sum, r) => sum + 0, 0) / races.length)
|
||||
? Math.round(races.reduce((sum, _r) => sum + 0, 0) / races.length)
|
||||
: null;
|
||||
|
||||
const info: LeagueInfoData = {
|
||||
|
||||
@@ -5,9 +5,11 @@ export class LeagueSponsorshipsViewDataBuilder {
|
||||
static build(apiDto: LeagueSponsorshipsApiDto): LeagueSponsorshipsViewData {
|
||||
return {
|
||||
leagueId: apiDto.leagueId,
|
||||
activeTab: 'overview',
|
||||
onTabChange: () => {},
|
||||
league: apiDto.league,
|
||||
sponsorshipSlots: apiDto.sponsorshipSlots,
|
||||
sponsorshipRequests: apiDto.sponsorshipRequests,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
import { LeagueWalletViewData } from '@/lib/view-data/leagues/LeagueWalletViewData';
|
||||
import { LeagueWalletViewData, LeagueWalletTransactionViewData } from '@/lib/view-data/leagues/LeagueWalletViewData';
|
||||
import { LeagueWalletApiDto } from '@/lib/types/tbd/LeagueWalletApiDto';
|
||||
|
||||
export class LeagueWalletViewDataBuilder {
|
||||
static build(apiDto: LeagueWalletApiDto): LeagueWalletViewData {
|
||||
const transactions: LeagueWalletTransactionViewData[] = apiDto.transactions.map(t => ({
|
||||
...t,
|
||||
formattedAmount: `${t.amount} ${apiDto.currency}`,
|
||||
amountColor: t.amount >= 0 ? 'green' : 'red',
|
||||
formattedDate: new Date(t.createdAt).toLocaleDateString(),
|
||||
statusColor: t.status === 'completed' ? 'green' : t.status === 'pending' ? 'yellow' : 'red',
|
||||
typeColor: 'blue',
|
||||
}));
|
||||
|
||||
return {
|
||||
leagueId: apiDto.leagueId,
|
||||
balance: apiDto.balance,
|
||||
formattedBalance: `${apiDto.balance} ${apiDto.currency}`,
|
||||
totalRevenue: apiDto.balance, // Mock
|
||||
formattedTotalRevenue: `${apiDto.balance} ${apiDto.currency}`,
|
||||
totalFees: 0, // Mock
|
||||
formattedTotalFees: `0 ${apiDto.currency}`,
|
||||
pendingPayouts: 0, // Mock
|
||||
formattedPendingPayouts: `0 ${apiDto.currency}`,
|
||||
currency: apiDto.currency,
|
||||
transactions: apiDto.transactions,
|
||||
transactions,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { RaceResultsViewData, RaceResultsResult, RaceResultsPenalty } from '@/li
|
||||
* Deterministic, side-effect free.
|
||||
*/
|
||||
export class RaceResultsViewDataBuilder {
|
||||
static build(apiDto: any): RaceResultsViewData {
|
||||
static build(apiDto: unknown): RaceResultsViewData {
|
||||
if (!apiDto) {
|
||||
return {
|
||||
raceSOF: null,
|
||||
@@ -18,8 +18,11 @@ export class RaceResultsViewDataBuilder {
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const dto = apiDto as any;
|
||||
|
||||
// Transform results
|
||||
const results: RaceResultsResult[] = (apiDto.results || []).map((result: any) => ({
|
||||
const results: RaceResultsResult[] = (dto.results || []).map((result: any) => ({
|
||||
position: result.position,
|
||||
driverId: result.driverId,
|
||||
driverName: result.driverName,
|
||||
@@ -35,7 +38,7 @@ export class RaceResultsViewDataBuilder {
|
||||
}));
|
||||
|
||||
// Transform penalties
|
||||
const penalties: RaceResultsPenalty[] = (apiDto.penalties || []).map((penalty: any) => ({
|
||||
const penalties: RaceResultsPenalty[] = (dto.penalties || []).map((penalty: any) => ({
|
||||
driverId: penalty.driverId,
|
||||
driverName: penalty.driverName || 'Unknown',
|
||||
type: penalty.type as 'time_penalty' | 'grid_penalty' | 'points_deduction' | 'disqualification' | 'warning' | 'license_points',
|
||||
@@ -45,15 +48,15 @@ export class RaceResultsViewDataBuilder {
|
||||
}));
|
||||
|
||||
return {
|
||||
raceTrack: apiDto.race?.track,
|
||||
raceScheduledAt: apiDto.race?.scheduledAt,
|
||||
totalDrivers: apiDto.stats?.totalDrivers,
|
||||
leagueName: apiDto.league?.name,
|
||||
raceSOF: apiDto.strengthOfField || null,
|
||||
raceTrack: dto.race?.track,
|
||||
raceScheduledAt: dto.race?.scheduledAt,
|
||||
totalDrivers: dto.stats?.totalDrivers,
|
||||
leagueName: dto.league?.name,
|
||||
raceSOF: dto.strengthOfField || null,
|
||||
results,
|
||||
penalties,
|
||||
pointsSystem: apiDto.pointsSystem || {},
|
||||
fastestLapTime: apiDto.fastestLapTime || 0,
|
||||
pointsSystem: dto.pointsSystem || {},
|
||||
fastestLapTime: dto.fastestLapTime || 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import { RaceStewardingViewData, Protest, Penalty, Driver } from '@/lib/view-dat
|
||||
* Deterministic, side-effect free.
|
||||
*/
|
||||
export class RaceStewardingViewDataBuilder {
|
||||
static build(apiDto: any): RaceStewardingViewData {
|
||||
static build(apiDto: unknown): RaceStewardingViewData {
|
||||
if (!apiDto) {
|
||||
return {
|
||||
race: null,
|
||||
@@ -22,17 +22,20 @@ export class RaceStewardingViewDataBuilder {
|
||||
};
|
||||
}
|
||||
|
||||
const race = apiDto.race ? {
|
||||
id: apiDto.race.id,
|
||||
track: apiDto.race.track,
|
||||
scheduledAt: apiDto.race.scheduledAt,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const dto = apiDto as any;
|
||||
|
||||
const race = dto.race ? {
|
||||
id: dto.race.id,
|
||||
track: dto.race.track,
|
||||
scheduledAt: dto.race.scheduledAt,
|
||||
} : null;
|
||||
|
||||
const league = apiDto.league ? {
|
||||
id: apiDto.league.id,
|
||||
const league = dto.league ? {
|
||||
id: dto.league.id,
|
||||
} : null;
|
||||
|
||||
const pendingProtests: Protest[] = (apiDto.pendingProtests || []).map((p: any) => ({
|
||||
const pendingProtests: Protest[] = (dto.pendingProtests || []).map((p: any) => ({
|
||||
id: p.id,
|
||||
protestingDriverId: p.protestingDriverId,
|
||||
accusedDriverId: p.accusedDriverId,
|
||||
@@ -46,7 +49,7 @@ export class RaceStewardingViewDataBuilder {
|
||||
decisionNotes: p.decisionNotes,
|
||||
}));
|
||||
|
||||
const resolvedProtests: Protest[] = (apiDto.resolvedProtests || []).map((p: any) => ({
|
||||
const resolvedProtests: Protest[] = (dto.resolvedProtests || []).map((p: any) => ({
|
||||
id: p.id,
|
||||
protestingDriverId: p.protestingDriverId,
|
||||
accusedDriverId: p.accusedDriverId,
|
||||
@@ -60,7 +63,7 @@ export class RaceStewardingViewDataBuilder {
|
||||
decisionNotes: p.decisionNotes,
|
||||
}));
|
||||
|
||||
const penalties: Penalty[] = (apiDto.penalties || []).map((p: any) => ({
|
||||
const penalties: Penalty[] = (dto.penalties || []).map((p: any) => ({
|
||||
id: p.id,
|
||||
driverId: p.driverId,
|
||||
type: p.type,
|
||||
@@ -69,7 +72,7 @@ export class RaceStewardingViewDataBuilder {
|
||||
notes: p.notes,
|
||||
}));
|
||||
|
||||
const driverMap: Record<string, Driver> = apiDto.driverMap || {};
|
||||
const driverMap: Record<string, Driver> = dto.driverMap || {};
|
||||
|
||||
return {
|
||||
race,
|
||||
@@ -78,9 +81,9 @@ export class RaceStewardingViewDataBuilder {
|
||||
resolvedProtests,
|
||||
penalties,
|
||||
driverMap,
|
||||
pendingCount: apiDto.pendingCount || pendingProtests.length,
|
||||
resolvedCount: apiDto.resolvedCount || resolvedProtests.length,
|
||||
penaltiesCount: apiDto.penaltiesCount || penalties.length,
|
||||
pendingCount: dto.pendingCount || pendingProtests.length,
|
||||
resolvedCount: dto.resolvedCount || resolvedProtests.length,
|
||||
penaltiesCount: dto.penaltiesCount || penalties.length,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RacesAllViewData, RacesAllRace } from '@/lib/view-data/races/RacesAllViewData';
|
||||
import { RacesAllViewData } from '@/lib/view-data/races/RacesAllViewData';
|
||||
|
||||
/**
|
||||
* Races All View Data Builder
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { TeamDetailPageDto } from '@/lib/page-queries/page-queries/TeamDetailPageQuery';
|
||||
import type { TeamDetailPageDto } from '@/lib/page-queries/TeamDetailPageQuery';
|
||||
import type { TeamDetailViewData, TeamDetailData, TeamMemberData, SponsorMetric, TeamTab } from '@/lib/view-data/TeamDetailViewData';
|
||||
import { Users, Zap, Calendar } from 'lucide-react';
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { TeamsPageDto } from '@/lib/page-queries/page-queries/TeamsPageQuery';
|
||||
import type { TeamsPageDto } from '@/lib/page-queries/TeamsPageQuery';
|
||||
import type { TeamsViewData, TeamSummaryData } from '@/lib/view-data/TeamsViewData';
|
||||
import type { TeamListItemDTO } from '@/lib/types/generated/TeamListItemDTO';
|
||||
|
||||
/**
|
||||
* TeamsViewDataBuilder - Transforms TeamsPageDto into ViewData for TeamsTemplate
|
||||
@@ -7,7 +8,7 @@ import type { TeamsViewData, TeamSummaryData } from '@/lib/view-data/TeamsViewDa
|
||||
*/
|
||||
export class TeamsViewDataBuilder {
|
||||
static build(apiDto: TeamsPageDto): TeamsViewData {
|
||||
const teams: TeamSummaryData[] = apiDto.teams.map((team): TeamSummaryData => ({
|
||||
const teams: TeamSummaryData[] = apiDto.teams.map((team: TeamListItemDTO): TeamSummaryData => ({
|
||||
teamId: team.id,
|
||||
teamName: team.name,
|
||||
leagueName: team.leagues[0] || '',
|
||||
@@ -17,4 +18,4 @@ export class TeamsViewDataBuilder {
|
||||
|
||||
return { teams };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user