website refactor

This commit is contained in:
2026-01-14 13:27:26 +01:00
parent e7887f054f
commit faa4c3309e
24 changed files with 964 additions and 401 deletions

View File

@@ -0,0 +1,30 @@
import { Result } from '@/lib/contracts/Result';
import { Service } from '@/lib/contracts/services/Service';
import { RulebookApiDto } from '@/lib/types/tbd/RulebookApiDto';
export class LeagueRulebookService implements Service {
async getRulebookData(leagueId: string): Promise<Result<RulebookApiDto, never>> {
// Mock data since backend not implemented
const mockData: RulebookApiDto = {
leagueId,
scoringConfig: {
gameName: 'iRacing',
scoringPresetName: 'Custom Rules',
championships: [
{
type: 'driver',
sessionTypes: ['Race'],
pointsPreview: [
{ sessionType: 'Race', position: 1, points: 25 },
{ sessionType: 'Race', position: 2, points: 20 },
{ sessionType: 'Race', position: 3, points: 16 },
],
bonusSummary: ['Pole Position: +1', 'Fastest Lap: +1'],
}
],
dropPolicySummary: 'All results count',
},
};
return Result.ok(mockData);
}
}

View File

@@ -0,0 +1,89 @@
import { Result } from '@/lib/contracts/Result';
import { Service } from '@/lib/contracts/services/Service';
import { LeagueStandingsApiDto, LeagueMembershipsApiDto } from '@/lib/types/tbd/LeagueStandingsApiDto';
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter';
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
export class LeagueStandingsService implements Service {
private apiClient: LeaguesApiClient;
constructor() {
const baseUrl = getWebsiteApiBaseUrl();
this.apiClient = new LeaguesApiClient(
baseUrl,
new ConsoleErrorReporter(),
new ConsoleLogger()
);
}
async getStandingsData(leagueId: string): Promise<Result<{ standings: LeagueStandingsApiDto; memberships: LeagueMembershipsApiDto }, never>> {
// Mock data since backend may not be implemented
const mockStandings: LeagueStandingsApiDto = {
standings: [
{
driverId: 'driver1',
driver: {
id: 'driver1',
name: 'John Doe',
iracingId: '12345',
country: 'US',
joinedAt: new Date().toISOString(),
},
points: 100,
position: 1,
wins: 2,
podiums: 3,
races: 5,
},
{
driverId: 'driver2',
driver: {
id: 'driver2',
name: 'Jane Smith',
iracingId: '67890',
country: 'UK',
joinedAt: new Date().toISOString(),
},
points: 80,
position: 2,
wins: 1,
podiums: 2,
races: 5,
},
],
};
const mockMemberships: LeagueMembershipsApiDto = {
members: [
{
driverId: 'driver1',
driver: {
id: 'driver1',
name: 'John Doe',
iracingId: '12345',
country: 'US',
joinedAt: new Date().toISOString(),
},
role: 'member',
joinedAt: new Date().toISOString(),
},
{
driverId: 'driver2',
driver: {
id: 'driver2',
name: 'Jane Smith',
iracingId: '67890',
country: 'UK',
joinedAt: new Date().toISOString(),
},
role: 'member',
joinedAt: new Date().toISOString(),
},
],
};
return Result.ok({ standings: mockStandings, memberships: mockMemberships });
}
}

View File

@@ -1,41 +1,18 @@
import { RaceService } from '@/lib/services/races/RaceService';
import { ProtestService } from '@/lib/services/protests/ProtestService';
import { PenaltyService } from '@/lib/services/penalties/PenaltyService';
import { DriverService } from '@/lib/services/drivers/DriverService';
import { LeagueMembershipService } from '@/lib/services/leagues/LeagueMembershipService';
import { Result } from '@/lib/contracts/Result';
import { Service } from '@/lib/contracts/services/Service';
import { StewardingApiDto } from '@/lib/types/tbd/StewardingApiDto';
/**
* League Stewarding Service - DTO Only
*
* Returns raw API DTOs. No ViewModels or UX logic.
* All client-side presentation logic must be handled by hooks/components.
*/
export class LeagueStewardingService {
constructor(
private readonly raceService: RaceService,
private readonly protestService: ProtestService,
private readonly penaltyService: PenaltyService,
private readonly driverService: DriverService,
private readonly membershipService: LeagueMembershipService
) {}
async getLeagueProtests(leagueId: string): Promise<any> {
return this.protestService.getLeagueProtests(leagueId);
}
async getProtestById(leagueId: string, protestId: string): Promise<any> {
return this.protestService.getProtestById(leagueId, protestId);
}
async applyPenalty(input: any): Promise<void> {
return this.protestService.applyPenalty(input);
}
async requestDefense(input: any): Promise<void> {
return this.protestService.requestDefense(input);
}
async reviewProtest(input: any): Promise<void> {
return this.protestService.reviewProtest(input);
export class LeagueStewardingService implements Service {
async getStewardingData(leagueId: string): Promise<Result<StewardingApiDto, never>> {
// Mock data since backend not implemented
const mockData: StewardingApiDto = {
leagueId,
totalPending: 0,
totalResolved: 0,
totalPenalties: 0,
races: [],
drivers: []
};
return Result.ok(mockData);
}
}

View File

@@ -0,0 +1,38 @@
import { Result } from '@/lib/contracts/Result';
import { Service } from '@/lib/contracts/services/Service';
import { ProtestDetailApiDto } from '@/lib/types/tbd/ProtestDetailApiDto';
export class ProtestDetailService implements Service {
async getProtestDetail(leagueId: string, protestId: string): Promise<Result<ProtestDetailApiDto, never>> {
// Mock data since backend not implemented
const mockData: ProtestDetailApiDto = {
id: protestId,
leagueId,
status: 'pending',
submittedAt: new Date().toISOString(),
incident: {
lap: 5,
description: 'Contact on corner 3, causing spin',
},
protestingDriver: {
id: 'driver1',
name: 'John Doe',
},
accusedDriver: {
id: 'driver2',
name: 'Jane Smith',
},
race: {
id: 'race1',
name: 'Race 1',
scheduledAt: new Date().toISOString(),
},
penaltyTypes: [
{ type: 'warning', label: 'Warning', description: 'Official warning' },
{ type: 'time_penalty', label: 'Time Penalty', description: 'Add seconds to race time' },
{ type: 'grid_penalty', label: 'Grid Penalty', description: 'Drop grid positions' },
],
};
return Result.ok(mockData);
}
}