website refactor
This commit is contained in:
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user