website refactor

This commit is contained in:
2026-01-21 17:50:02 +01:00
parent 4b54c3603b
commit 02987f60c8
29 changed files with 1673 additions and 35 deletions

View File

@@ -3,7 +3,7 @@ import type { LeagueMembershipsDTO } from '@/lib/types/generated/LeagueMembershi
import type { RaceDTO } from '@/lib/types/generated/RaceDTO';
import type { GetDriverOutputDTO } from '@/lib/types/generated/GetDriverOutputDTO';
import type { LeagueScoringConfigDTO } from '@/lib/types/generated/LeagueScoringConfigDTO';
import type { LeagueDetailViewData, LeagueInfoData, LiveRaceData, DriverSummaryData, SponsorInfo } from '@/lib/view-data/LeagueDetailViewData';
import type { LeagueDetailViewData, LeagueInfoData, LiveRaceData, DriverSummaryData, SponsorInfo, NextRaceInfo, SeasonProgress, RecentResult } from '@/lib/view-data/LeagueDetailViewData';
/**
* LeagueDetailViewDataBuilder
@@ -138,6 +138,45 @@ export class LeagueDetailViewDataBuilder {
profileUrl: `/drivers/${m.driverId}`,
}));
// Calculate next race (first upcoming race)
const now = new Date();
const nextRace: NextRaceInfo | undefined = races
.filter(r => new Date(r.date) > now)
.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())
.map(r => ({
id: r.id,
name: r.name,
date: r.date,
track: (r as any).track,
car: (r as any).car,
}))[0];
// Calculate season progress (completed races vs total races)
const completedRaces = races.filter(r => {
const raceDate = new Date(r.date);
return raceDate < now;
}).length;
const totalRaces = races.length;
const percentage = totalRaces > 0 ? Math.round((completedRaces / totalRaces) * 100) : 0;
const seasonProgress: SeasonProgress = {
completedRaces,
totalRaces,
percentage,
};
// Get recent results (top 3 from last completed race)
const recentResults: RecentResult[] = races
.filter(r => new Date(r.date) < now)
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
.slice(0, 3)
.map(r => ({
raceId: r.id,
raceName: r.name,
position: (r as any).position || 0,
points: (r as any).points || 0,
finishedAt: r.date,
}));
return {
leagueId: league.id,
name: league.name,
@@ -151,6 +190,12 @@ export class LeagueDetailViewDataBuilder {
stewardSummaries,
memberSummaries,
sponsorInsights: null, // Only for sponsor mode
nextRace,
seasonProgress,
recentResults,
walletBalance: league.walletBalance,
pendingProtestsCount: league.pendingProtestsCount,
pendingJoinRequestsCount: league.pendingJoinRequestsCount,
};
}
}

View File

@@ -2,7 +2,7 @@ import { LeagueScheduleViewData } from '@/lib/view-data/leagues/LeagueScheduleVi
import { LeagueScheduleApiDto } from '@/lib/types/tbd/LeagueScheduleApiDto';
export class LeagueScheduleViewDataBuilder {
static build(apiDto: LeagueScheduleApiDto): LeagueScheduleViewData {
static build(apiDto: LeagueScheduleApiDto, currentDriverId?: string, isAdmin: boolean = false): LeagueScheduleViewData {
const now = new Date();
return {
@@ -22,8 +22,16 @@ export class LeagueScheduleViewDataBuilder {
isPast,
isUpcoming,
status: isPast ? 'completed' : 'scheduled',
// Registration info (would come from API in real implementation)
isUserRegistered: false,
canRegister: isUpcoming,
// Admin info
canEdit: isAdmin,
canReschedule: isAdmin,
};
}),
currentDriverId,
isAdmin,
};
}
}

View File

@@ -20,7 +20,8 @@ export class LeagueStandingsViewDataBuilder {
static build(
standingsDto: LeagueStandingsApiDto,
membershipsDto: LeagueMembershipsApiDto,
leagueId: string
leagueId: string,
isTeamChampionship: boolean = false
): LeagueStandingsViewData {
const standings = standingsDto.standings || [];
const members = membershipsDto.members || [];
@@ -35,6 +36,12 @@ export class LeagueStandingsViewDataBuilder {
avgFinish: null, // Not in DTO
penaltyPoints: 0, // Not in DTO
bonusPoints: 0, // Not in DTO
// New fields from Phase 3
positionChange: standing.positionChange || 0,
lastRacePoints: standing.lastRacePoints || 0,
droppedRaceIds: standing.droppedRaceIds || [],
wins: standing.wins || 0,
podiums: standing.podiums || 0,
}));
// Extract unique drivers from standings
@@ -70,6 +77,7 @@ export class LeagueStandingsViewDataBuilder {
leagueId,
currentDriverId: null, // Would need to get from auth
isAdmin: false, // Would need to check permissions
isTeamChampionship: isTeamChampionship,
};
}
}