website refactor

This commit is contained in:
2026-01-12 01:01:49 +01:00
parent 5ca6023a5a
commit fefd8d1cd6
294 changed files with 4628 additions and 4991 deletions

View File

@@ -1,10 +1,7 @@
import { LeagueWithCapacityAndScoringDTO } from '../types/generated/LeagueWithCapacityAndScoringDTO';
import { LeagueStatsDTO } from '../types/generated/LeagueStatsDTO';
import { LeagueMembershipsDTO } from '../types/generated/LeagueMembershipsDTO';
import { LeagueScheduleDTO } from '../types/generated/LeagueScheduleDTO';
import { LeagueStandingsDTO } from '../types/generated/LeagueStandingsDTO';
import { GetDriverOutputDTO } from '../types/generated/GetDriverOutputDTO';
import { RaceDTO } from '../types/generated/RaceDTO';
import { LeagueWithCapacityAndScoringDTO } from '@/lib/types/generated/LeagueWithCapacityAndScoringDTO';
import { LeagueStatsDTO } from '@/lib/types/generated/LeagueStatsDTO';
import { LeagueMembershipsDTO } from '@/lib/types/generated/LeagueMembershipsDTO';
import { GetDriverOutputDTO } from '@/lib/types/generated/GetDriverOutputDTO';
import { LeagueScoringConfigDTO } from '@/lib/types/generated/LeagueScoringConfigDTO';
import { RaceViewModel } from './RaceViewModel';
import { DriverViewModel } from './DriverViewModel';
@@ -34,6 +31,29 @@ export interface LeagueMembershipWithRole {
joinedAt: string;
}
// Helper interfaces for type narrowing
interface LeagueSettings {
maxDrivers?: number;
}
interface SocialLinks {
discordUrl?: string;
youtubeUrl?: string;
websiteUrl?: string;
}
interface LeagueStatsExtended {
averageSOF?: number;
averageRating?: number;
completedRaces?: number;
totalRaces?: number;
}
interface MembershipsContainer {
members?: Array<{ driverId: string; role: string; status?: 'active' | 'inactive'; joinedAt: string }>;
memberships?: Array<{ driverId: string; role: string; status?: 'active' | 'inactive'; joinedAt: string }>;
}
export class LeagueDetailPageViewModel {
// League basic info
id: string;
@@ -107,25 +127,35 @@ export class LeagueDetailPageViewModel {
this.description = league.description ?? '';
this.ownerId = league.ownerId;
this.createdAt = league.createdAt;
// Handle settings with proper type narrowing
const settings = league.settings as LeagueSettings | undefined;
const maxDrivers = settings?.maxDrivers;
this.settings = {
maxDrivers: league.settings?.maxDrivers ?? (league as any).maxDrivers,
maxDrivers: maxDrivers,
};
// Handle social links with proper type narrowing
const socialLinks = league.socialLinks as SocialLinks | undefined;
const discordUrl = socialLinks?.discordUrl;
const youtubeUrl = socialLinks?.youtubeUrl;
const websiteUrl = socialLinks?.websiteUrl;
this.socialLinks = {
discordUrl: league.socialLinks?.discordUrl ?? (league as any).socialLinks?.discordUrl,
youtubeUrl: league.socialLinks?.youtubeUrl ?? (league as any).socialLinks?.youtubeUrl,
websiteUrl: league.socialLinks?.websiteUrl ?? (league as any).socialLinks?.websiteUrl,
discordUrl,
youtubeUrl,
websiteUrl,
};
this.owner = owner;
this.scoringConfig = scoringConfig;
this.drivers = drivers;
const membershipDtos = ((memberships as any).members ?? (memberships as any).memberships ?? []) as Array<{
driverId: string;
role: string;
status?: 'active' | 'inactive';
joinedAt: string;
}>;
// Handle memberships with proper type narrowing
const membershipsContainer = memberships as MembershipsContainer;
const membershipDtos = membershipsContainer.members ??
membershipsContainer.memberships ??
[];
this.memberships = membershipDtos.map((m) => ({
driverId: m.driverId,
@@ -137,11 +167,15 @@ export class LeagueDetailPageViewModel {
this.allRaces = allRaces;
this.runningRaces = allRaces.filter(r => r.status === 'running');
const leagueStatsAny = leagueStats as any;
// Calculate SOF from available data with proper type narrowing
const statsExtended = leagueStats as LeagueStatsExtended;
const averageSOF = statsExtended.averageSOF ??
statsExtended.averageRating ?? undefined;
const completedRaces = statsExtended.completedRaces ??
statsExtended.totalRaces ?? undefined;
// Calculate SOF from available data
this.averageSOF = leagueStatsAny.averageSOF ?? leagueStats.averageRating ?? null;
this.completedRacesCount = leagueStatsAny.completedRaces ?? leagueStats.totalRaces ?? 0;
this.averageSOF = typeof averageSOF === 'number' ? averageSOF : null;
this.completedRacesCount = typeof completedRaces === 'number' ? completedRaces : 0;
this.sponsors = sponsors;
@@ -183,10 +217,14 @@ export class LeagueDetailPageViewModel {
const driverDto = this.drivers.find(d => d.id === driverId);
if (!driverDto) return null;
// Handle avatarUrl with proper type checking
const driverAny = driverDto as { avatarUrl?: unknown };
const avatarUrl = typeof driverAny.avatarUrl === 'string' ? driverAny.avatarUrl : null;
const driver = new DriverViewModel({
id: driverDto.id,
name: driverDto.name,
avatarUrl: (driverDto as any).avatarUrl ?? null,
avatarUrl: avatarUrl,
iracingId: driverDto.iracingId,
});