website cleanup
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import { AuthSessionDTO } from '../../types/generated/AuthSessionDTO';
|
||||
import { LoginParams } from '../../types/generated/LoginParams';
|
||||
import { SignupParams } from '../../types/generated/SignupParams';
|
||||
import { LoginWithIracingCallbackParams } from '../../types/generated/LoginWithIracingCallbackParams';
|
||||
import { IracingAuthRedirectResult } from '../../types/generated/IracingAuthRedirectResult';
|
||||
import { LoginParamsDTO } from '../../types/generated/LoginParamsDTO';
|
||||
import { SignupParamsDTO } from '../../types/generated/SignupParamsDTO';
|
||||
import { LoginWithIracingCallbackParamsDTO } from '../../types/generated/LoginWithIracingCallbackParamsDTO';
|
||||
import { IracingAuthRedirectResultDTO } from '../../types/generated/IracingAuthRedirectResultDTO';
|
||||
|
||||
/**
|
||||
* Auth API Client
|
||||
@@ -12,12 +12,12 @@ import { IracingAuthRedirectResult } from '../../types/generated/IracingAuthRedi
|
||||
*/
|
||||
export class AuthApiClient extends BaseApiClient {
|
||||
/** Sign up with email */
|
||||
signup(params: SignupParams): Promise<AuthSessionDTO> {
|
||||
signup(params: SignupParamsDTO): Promise<AuthSessionDTO> {
|
||||
return this.post<AuthSessionDTO>('/auth/signup', params);
|
||||
}
|
||||
|
||||
/** Login with email */
|
||||
login(params: LoginParams): Promise<AuthSessionDTO> {
|
||||
login(params: LoginParamsDTO): Promise<AuthSessionDTO> {
|
||||
return this.post<AuthSessionDTO>('/auth/login', params);
|
||||
}
|
||||
|
||||
@@ -32,13 +32,22 @@ export class AuthApiClient extends BaseApiClient {
|
||||
}
|
||||
|
||||
/** Start iRacing auth redirect */
|
||||
startIracingAuthRedirect(returnTo?: string): Promise<IracingAuthRedirectResult> {
|
||||
startIracingAuthRedirect(returnTo?: string): Promise<IracingAuthRedirectResultDTO> {
|
||||
const query = returnTo ? `?returnTo=${encodeURIComponent(returnTo)}` : '';
|
||||
return this.get<IracingAuthRedirectResult>(`/auth/iracing/start${query}`);
|
||||
return this.get<IracingAuthRedirectResultDTO>(`/auth/iracing/start${query}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: build iRacing auth start URL.
|
||||
* Used by AuthService for view-layer navigation.
|
||||
*/
|
||||
getIracingAuthUrl(returnTo?: string): string {
|
||||
const query = returnTo ? `?returnTo=${encodeURIComponent(returnTo)}` : '';
|
||||
return `${this.baseUrl}/auth/iracing/start${query}`;
|
||||
}
|
||||
|
||||
/** Login with iRacing callback */
|
||||
loginWithIracingCallback(params: LoginWithIracingCallbackParams): Promise<AuthSessionDTO> {
|
||||
loginWithIracingCallback(params: LoginWithIracingCallbackParamsDTO): Promise<AuthSessionDTO> {
|
||||
const query = new URLSearchParams();
|
||||
query.append('code', params.code);
|
||||
query.append('state', params.state);
|
||||
@@ -47,4 +56,4 @@ export class AuthApiClient extends BaseApiClient {
|
||||
}
|
||||
return this.get<AuthSessionDTO>(`/auth/iracing/callback?${query.toString()}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Logger } from '../../interfaces/Logger';
|
||||
import { ErrorReporter } from '../../interfaces/ErrorReporter';
|
||||
|
||||
export class BaseApiClient {
|
||||
private baseUrl: string;
|
||||
protected baseUrl: string;
|
||||
private errorReporter: ErrorReporter;
|
||||
private logger: Logger;
|
||||
|
||||
@@ -19,12 +19,16 @@ export class BaseApiClient {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
protected async request<T>(method: string, path: string, data?: object): Promise<T> {
|
||||
protected async request<T>(method: string, path: string, data?: object | FormData): Promise<T> {
|
||||
this.logger.info(`${method} ${path}`);
|
||||
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
const isFormData = typeof FormData !== 'undefined' && data instanceof FormData;
|
||||
|
||||
const headers: HeadersInit = isFormData
|
||||
? {}
|
||||
: {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
|
||||
const config: RequestInit = {
|
||||
method,
|
||||
@@ -33,7 +37,7 @@ export class BaseApiClient {
|
||||
};
|
||||
|
||||
if (data) {
|
||||
config.body = JSON.stringify(data);
|
||||
config.body = isFormData ? data : JSON.stringify(data);
|
||||
}
|
||||
|
||||
const response = await fetch(`${this.baseUrl}${path}`, config);
|
||||
@@ -45,7 +49,10 @@ export class BaseApiClient {
|
||||
} catch {
|
||||
// Keep default error message
|
||||
}
|
||||
const error = new Error(errorData.message || `API request failed with status ${response.status}`);
|
||||
const error = new Error(
|
||||
errorData.message || `API request failed with status ${response.status}`,
|
||||
) as Error & { status?: number };
|
||||
error.status = response.status;
|
||||
this.errorReporter.report(error);
|
||||
throw error;
|
||||
}
|
||||
@@ -76,4 +83,4 @@ export class BaseApiClient {
|
||||
protected patch<T>(path: string, data: object): Promise<T> {
|
||||
return this.request<T>('PATCH', path, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,5 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import {
|
||||
DashboardDriverSummaryDTO,
|
||||
DashboardRaceSummaryDTO,
|
||||
DashboardLeagueStandingSummaryDTO,
|
||||
DashboardFeedItemSummaryDTO,
|
||||
DashboardFriendSummaryDTO,
|
||||
DashboardRecentResultDTO,
|
||||
} from '../../types/generated';
|
||||
|
||||
// Define DashboardOverviewDTO using generated types
|
||||
export type DashboardOverviewDto = {
|
||||
currentDriver: DashboardDriverSummaryDTO | null;
|
||||
myUpcomingRaces: DashboardRaceSummaryDTO[];
|
||||
otherUpcomingRaces: DashboardRaceSummaryDTO[];
|
||||
upcomingRaces: DashboardRaceSummaryDTO[];
|
||||
activeLeaguesCount: number;
|
||||
nextRace: DashboardRaceSummaryDTO | null;
|
||||
recentResults: DashboardRecentResultDTO[];
|
||||
leagueStandingsSummaries: DashboardLeagueStandingSummaryDTO[];
|
||||
feedSummary: {
|
||||
feedItems: DashboardFeedItemSummaryDTO[];
|
||||
};
|
||||
friends: DashboardFriendSummaryDTO[];
|
||||
};
|
||||
import type { DashboardOverviewDTO } from '../../types/generated/DashboardOverviewDTO';
|
||||
|
||||
/**
|
||||
* Dashboard API Client
|
||||
@@ -31,7 +8,7 @@ export type DashboardOverviewDto = {
|
||||
*/
|
||||
export class DashboardApiClient extends BaseApiClient {
|
||||
/** Get dashboard overview data */
|
||||
getDashboardOverview(): Promise<DashboardOverviewDto> {
|
||||
return this.get<DashboardOverviewDto>('/dashboard/overview');
|
||||
getDashboardOverview(): Promise<DashboardOverviewDTO> {
|
||||
return this.get<DashboardOverviewDTO>('/dashboard/overview');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
// Import generated types
|
||||
import type { CompleteOnboardingInputDTO, CompleteOnboardingOutputDTO, DriverRegistrationStatusDTO, DriverLeaderboardItemDTO, DriverProfileDTO, GetDriverOutputDTO } from '../../types/generated';
|
||||
import type { CompleteOnboardingInputDTO } from '../../types/generated/CompleteOnboardingInputDTO';
|
||||
import type { CompleteOnboardingOutputDTO } from '../../types/generated/CompleteOnboardingOutputDTO';
|
||||
import type { DriverRegistrationStatusDTO } from '../../types/generated/DriverRegistrationStatusDTO';
|
||||
import type { DriverLeaderboardItemDTO } from '../../types/generated/DriverLeaderboardItemDTO';
|
||||
import type { GetDriverOutputDTO } from '../../types/generated/GetDriverOutputDTO';
|
||||
import type { GetDriverProfileOutputDTO } from '../../types/generated/GetDriverProfileOutputDTO';
|
||||
|
||||
type DriversLeaderboardDto = {
|
||||
drivers: DriverLeaderboardItemDTO[];
|
||||
@@ -38,12 +42,12 @@ export class DriversApiClient extends BaseApiClient {
|
||||
}
|
||||
|
||||
/** Get driver profile with full details */
|
||||
getDriverProfile(driverId: string): Promise<DriverProfileDTO> {
|
||||
return this.get<DriverProfileDTO>(`/drivers/${driverId}/profile`);
|
||||
getDriverProfile(driverId: string): Promise<GetDriverProfileOutputDTO> {
|
||||
return this.get<GetDriverProfileOutputDTO>(`/drivers/${driverId}/profile`);
|
||||
}
|
||||
|
||||
/** Update current driver profile */
|
||||
updateProfile(updates: { bio?: string; country?: string }): Promise<GetDriverOutputDTO> {
|
||||
return this.put<GetDriverOutputDTO>('/drivers/profile', updates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import type {
|
||||
AllLeaguesWithCapacityDto,
|
||||
LeagueStatsDto,
|
||||
LeagueStandingsDto,
|
||||
LeagueScheduleDto,
|
||||
LeagueMembershipsDto,
|
||||
CreateLeagueInputDto,
|
||||
CreateLeagueOutputDto,
|
||||
SponsorshipDetailDTO,
|
||||
RaceDTO,
|
||||
} from '../../dtos';
|
||||
import type { AllLeaguesWithCapacityDTO } from '../../types/generated/AllLeaguesWithCapacityDTO';
|
||||
import type { TotalLeaguesDTO } from '../../types/generated/TotalLeaguesDTO';
|
||||
import type { LeagueStandingsDTO } from '../../types/generated/LeagueStandingsDTO';
|
||||
import type { LeagueScheduleDTO } from '../../types/generated/LeagueScheduleDTO';
|
||||
import type { LeagueMembershipsDTO } from '../../types/generated/LeagueMembershipsDTO';
|
||||
import type { CreateLeagueInputDTO } from '../../types/generated/CreateLeagueInputDTO';
|
||||
import type { CreateLeagueOutputDTO } from '../../types/generated/CreateLeagueOutputDTO';
|
||||
import type { SponsorshipDetailDTO } from '../../types/generated/SponsorshipDetailDTO';
|
||||
import type { RaceDTO } from '../../types/generated/RaceDTO';
|
||||
import type { GetLeagueAdminConfigOutputDTO } from '../../types/generated/GetLeagueAdminConfigOutputDTO';
|
||||
import type { LeagueScoringPresetDTO } from '../../types/generated/LeagueScoringPresetDTO';
|
||||
import type { LeagueSeasonSummaryDTO } from '../../types/generated/LeagueSeasonSummaryDTO';
|
||||
|
||||
/**
|
||||
* Leagues API Client
|
||||
@@ -18,33 +19,33 @@ import type {
|
||||
*/
|
||||
export class LeaguesApiClient extends BaseApiClient {
|
||||
/** Get all leagues with capacity information */
|
||||
getAllWithCapacity(): Promise<AllLeaguesWithCapacityDto> {
|
||||
return this.get<AllLeaguesWithCapacityDto>('/leagues/all-with-capacity');
|
||||
getAllWithCapacity(): Promise<AllLeaguesWithCapacityDTO> {
|
||||
return this.get<AllLeaguesWithCapacityDTO>('/leagues/all-with-capacity');
|
||||
}
|
||||
|
||||
/** Get total number of leagues */
|
||||
getTotal(): Promise<LeagueStatsDto> {
|
||||
return this.get<LeagueStatsDto>('/leagues/total-leagues');
|
||||
getTotal(): Promise<TotalLeaguesDTO> {
|
||||
return this.get<TotalLeaguesDTO>('/leagues/total-leagues');
|
||||
}
|
||||
|
||||
/** Get league standings */
|
||||
getStandings(leagueId: string): Promise<LeagueStandingsDto> {
|
||||
return this.get<LeagueStandingsDto>(`/leagues/${leagueId}/standings`);
|
||||
getStandings(leagueId: string): Promise<LeagueStandingsDTO> {
|
||||
return this.get<LeagueStandingsDTO>(`/leagues/${leagueId}/standings`);
|
||||
}
|
||||
|
||||
/** Get league schedule */
|
||||
getSchedule(leagueId: string): Promise<LeagueScheduleDto> {
|
||||
return this.get<LeagueScheduleDto>(`/leagues/${leagueId}/schedule`);
|
||||
getSchedule(leagueId: string): Promise<LeagueScheduleDTO> {
|
||||
return this.get<LeagueScheduleDTO>(`/leagues/${leagueId}/schedule`);
|
||||
}
|
||||
|
||||
/** Get league memberships */
|
||||
getMemberships(leagueId: string): Promise<LeagueMembershipsDto> {
|
||||
return this.get<LeagueMembershipsDto>(`/leagues/${leagueId}/memberships`);
|
||||
getMemberships(leagueId: string): Promise<LeagueMembershipsDTO> {
|
||||
return this.get<LeagueMembershipsDTO>(`/leagues/${leagueId}/memberships`);
|
||||
}
|
||||
|
||||
/** Create a new league */
|
||||
create(input: CreateLeagueInputDto): Promise<CreateLeagueOutputDto> {
|
||||
return this.post<CreateLeagueOutputDto>('/leagues', input);
|
||||
create(input: CreateLeagueInputDTO): Promise<CreateLeagueOutputDTO> {
|
||||
return this.post<CreateLeagueOutputDTO>('/leagues', input);
|
||||
}
|
||||
|
||||
/** Remove a member from league */
|
||||
@@ -58,8 +59,8 @@ export class LeaguesApiClient extends BaseApiClient {
|
||||
}
|
||||
|
||||
/** Get league seasons */
|
||||
getSeasons(leagueId: string): Promise<{ seasons: Array<{ id: string; status: string }> }> {
|
||||
return this.get<{ seasons: Array<{ id: string; status: string }> }>(`/leagues/${leagueId}/seasons`);
|
||||
getSeasons(leagueId: string): Promise<LeagueSeasonSummaryDTO[]> {
|
||||
return this.get<LeagueSeasonSummaryDTO[]>(`/leagues/${leagueId}/seasons`);
|
||||
}
|
||||
|
||||
/** Get season sponsorships */
|
||||
@@ -68,13 +69,13 @@ export class LeaguesApiClient extends BaseApiClient {
|
||||
}
|
||||
|
||||
/** Get league config */
|
||||
getLeagueConfig(leagueId: string): Promise<{ config: any }> {
|
||||
return this.get<{ config: any }>(`/leagues/${leagueId}/config`);
|
||||
getLeagueConfig(leagueId: string): Promise<GetLeagueAdminConfigOutputDTO> {
|
||||
return this.get<GetLeagueAdminConfigOutputDTO>(`/leagues/${leagueId}/config`);
|
||||
}
|
||||
|
||||
/** Get league scoring presets */
|
||||
getScoringPresets(): Promise<{ presets: any[] }> {
|
||||
return this.get<{ presets: any[] }>(`/leagues/scoring-presets`);
|
||||
getScoringPresets(): Promise<{ presets: LeagueScoringPresetDTO[] }> {
|
||||
return this.get<{ presets: LeagueScoringPresetDTO[] }>(`/leagues/scoring-presets`);
|
||||
}
|
||||
|
||||
/** Transfer league ownership */
|
||||
@@ -89,4 +90,4 @@ export class LeaguesApiClient extends BaseApiClient {
|
||||
getRaces(leagueId: string): Promise<{ races: RaceDTO[] }> {
|
||||
return this.get<{ races: RaceDTO[] }>(`/leagues/${leagueId}/races`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import type {
|
||||
DeleteMediaOutputDTO,
|
||||
GetMediaOutputDTO,
|
||||
RequestAvatarGenerationInputDTO,
|
||||
RequestAvatarGenerationOutputDTO,
|
||||
UpdateAvatarInputDTO,
|
||||
UpdateAvatarOutputDTO,
|
||||
UploadMediaOutputDTO,
|
||||
} from '../generated';
|
||||
import type { GetAvatarOutputDTO } from '../generated';
|
||||
import type { DeleteMediaOutputDTO } from '../../types/generated/DeleteMediaOutputDTO';
|
||||
import type { GetAvatarOutputDTO } from '../../types/generated/GetAvatarOutputDTO';
|
||||
import type { GetMediaOutputDTO } from '../../types/generated/GetMediaOutputDTO';
|
||||
import type { RequestAvatarGenerationInputDTO } from '../../types/generated/RequestAvatarGenerationInputDTO';
|
||||
import type { RequestAvatarGenerationOutputDTO } from '../../types/generated/RequestAvatarGenerationOutputDTO';
|
||||
import type { UpdateAvatarInputDTO } from '../../types/generated/UpdateAvatarInputDTO';
|
||||
import type { UpdateAvatarOutputDTO } from '../../types/generated/UpdateAvatarOutputDTO';
|
||||
import type { UploadMediaOutputDTO } from '../../types/generated/UploadMediaOutputDTO';
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
|
||||
/**
|
||||
@@ -51,4 +49,4 @@ export class MediaApiClient extends BaseApiClient {
|
||||
updateAvatar(input: UpdateAvatarInputDTO): Promise<UpdateAvatarOutputDTO> {
|
||||
return this.put<UpdateAvatarOutputDTO>(`/media/avatar/${input.driverId}`, { avatarUrl: input.avatarUrl });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import type { PaymentDto, MembershipFeeDto, MemberPaymentDto, PrizeDto, WalletDto, TransactionDto, UpdatePaymentStatusInputDTO } from '../types/generated';
|
||||
import type { MembershipFeeDTO } from '../../types/generated/MembershipFeeDTO';
|
||||
import type { MemberPaymentDTO } from '../../types/generated/MemberPaymentDTO';
|
||||
import type { PaymentDTO } from '../../types/generated/PaymentDTO';
|
||||
import type { PrizeDTO } from '../../types/generated/PrizeDTO';
|
||||
import type { TransactionDTO } from '../../types/generated/TransactionDTO';
|
||||
import type { UpdatePaymentStatusInputDTO } from '../../types/generated/UpdatePaymentStatusInputDTO';
|
||||
import type { WalletDTO } from '../../types/generated/WalletDTO';
|
||||
|
||||
// Define missing types that are not fully generated
|
||||
type GetPaymentsOutputDto = { payments: PaymentDto[] };
|
||||
type GetPaymentsOutputDto = { payments: PaymentDTO[] };
|
||||
type CreatePaymentInputDto = {
|
||||
type: 'sponsorship' | 'membership_fee';
|
||||
amount: number;
|
||||
@@ -11,15 +17,15 @@ type CreatePaymentInputDto = {
|
||||
leagueId: string;
|
||||
seasonId?: string;
|
||||
};
|
||||
type CreatePaymentOutputDto = { payment: PaymentDto };
|
||||
type CreatePaymentOutputDto = { payment: PaymentDTO };
|
||||
type GetMembershipFeesOutputDto = {
|
||||
fee: MembershipFeeDto | null;
|
||||
payments: MemberPaymentDto[]
|
||||
fee: MembershipFeeDTO | null;
|
||||
payments: MemberPaymentDTO[]
|
||||
};
|
||||
type GetPrizesOutputDto = { prizes: PrizeDto[] };
|
||||
type GetPrizesOutputDto = { prizes: PrizeDTO[] };
|
||||
type GetWalletOutputDto = {
|
||||
wallet: WalletDto;
|
||||
transactions: TransactionDto[]
|
||||
wallet: WalletDTO;
|
||||
transactions: TransactionDTO[]
|
||||
};
|
||||
type ProcessWalletTransactionInputDto = {
|
||||
leagueId: string;
|
||||
@@ -30,8 +36,8 @@ type ProcessWalletTransactionInputDto = {
|
||||
referenceType?: 'sponsorship' | 'membership_fee' | 'prize';
|
||||
};
|
||||
type ProcessWalletTransactionOutputDto = {
|
||||
wallet: WalletDto;
|
||||
transaction: TransactionDto
|
||||
wallet: WalletDTO;
|
||||
transaction: TransactionDTO
|
||||
};
|
||||
type UpdateMemberPaymentInputDto = {
|
||||
feeId: string;
|
||||
@@ -39,16 +45,16 @@ type UpdateMemberPaymentInputDto = {
|
||||
status?: 'pending' | 'paid' | 'overdue';
|
||||
paidAt?: Date | string;
|
||||
};
|
||||
type UpdateMemberPaymentOutputDto = { payment: MemberPaymentDto };
|
||||
type GetWalletTransactionsOutputDto = { transactions: TransactionDto[] };
|
||||
type UpdatePaymentStatusOutputDto = { payment: PaymentDto };
|
||||
type UpdateMemberPaymentOutputDto = { payment: MemberPaymentDTO };
|
||||
type GetWalletTransactionsOutputDto = { transactions: TransactionDTO[] };
|
||||
type UpdatePaymentStatusOutputDto = { payment: PaymentDTO };
|
||||
type UpsertMembershipFeeInputDto = {
|
||||
leagueId: string;
|
||||
seasonId?: string;
|
||||
type: 'season' | 'monthly' | 'per_race';
|
||||
amount: number;
|
||||
};
|
||||
type UpsertMembershipFeeOutputDto = { fee: MembershipFeeDto };
|
||||
type UpsertMembershipFeeOutputDto = { fee: MembershipFeeDTO };
|
||||
type CreatePrizeInputDto = {
|
||||
leagueId: string;
|
||||
seasonId: string;
|
||||
@@ -58,12 +64,12 @@ type CreatePrizeInputDto = {
|
||||
type: 'cash' | 'merchandise' | 'other';
|
||||
description?: string;
|
||||
};
|
||||
type CreatePrizeOutputDto = { prize: PrizeDto };
|
||||
type CreatePrizeOutputDto = { prize: PrizeDTO };
|
||||
type AwardPrizeInputDto = {
|
||||
prizeId: string;
|
||||
driverId: string;
|
||||
};
|
||||
type AwardPrizeOutputDto = { prize: PrizeDto };
|
||||
type AwardPrizeOutputDto = { prize: PrizeDTO };
|
||||
type DeletePrizeInputDto = { prizeId: string };
|
||||
type DeletePrizeOutputDto = { success: boolean };
|
||||
|
||||
@@ -149,4 +155,4 @@ export class PaymentsApiClient extends BaseApiClient {
|
||||
processWalletTransaction(input: ProcessWalletTransactionInputDto): Promise<ProcessWalletTransactionOutputDto> {
|
||||
return this.post<ProcessWalletTransactionOutputDto>('/payments/wallets/transactions', input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import type {
|
||||
LeagueAdminProtestsDTO,
|
||||
ApplyPenaltyCommandDTO,
|
||||
RequestProtestDefenseCommandDTO,
|
||||
ReviewProtestCommandDTO,
|
||||
} from '../../types/generated';
|
||||
import type { RaceProtestsDTO } from '../../types';
|
||||
import type { ApplyPenaltyCommandDTO } from '../../types/generated/ApplyPenaltyCommandDTO';
|
||||
import type { LeagueAdminProtestsDTO } from '../../types/generated/LeagueAdminProtestsDTO';
|
||||
import type { RaceProtestsDTO } from '../../types/generated/RaceProtestsDTO';
|
||||
import type { RequestProtestDefenseCommandDTO } from '../../types/generated/RequestProtestDefenseCommandDTO';
|
||||
import type { ReviewProtestCommandDTO } from '../../types/generated/ReviewProtestCommandDTO';
|
||||
|
||||
/**
|
||||
* Protests API Client
|
||||
@@ -42,4 +40,4 @@ export class ProtestsApiClient extends BaseApiClient {
|
||||
getRaceProtests(raceId: string): Promise<RaceProtestsDTO> {
|
||||
return this.get<RaceProtestsDTO>(`/races/${raceId}/protests`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { RaceDetailLeagueDTO } from '../../types/generated/RaceDetailLeague
|
||||
import type { RaceDetailEntryDTO } from '../../types/generated/RaceDetailEntryDTO';
|
||||
import type { RaceDetailRegistrationDTO } from '../../types/generated/RaceDetailRegistrationDTO';
|
||||
import type { RaceDetailUserResultDTO } from '../../types/generated/RaceDetailUserResultDTO';
|
||||
import type { FileProtestCommandDTO } from '../../types/generated/FileProtestCommandDTO';
|
||||
|
||||
// Define missing types
|
||||
type RacesPageDataDTO = { races: RacesPageDataRaceDTO[] };
|
||||
@@ -42,8 +43,9 @@ export class RacesApiClient extends BaseApiClient {
|
||||
}
|
||||
|
||||
/** Get races page data */
|
||||
getPageData(): Promise<RacesPageDataDTO> {
|
||||
return this.get<RacesPageDataDTO>('/races/page-data');
|
||||
getPageData(leagueId?: string): Promise<RacesPageDataDTO> {
|
||||
const query = leagueId ? `?leagueId=${encodeURIComponent(leagueId)}` : '';
|
||||
return this.get<RacesPageDataDTO>(`/races/page-data${query}`);
|
||||
}
|
||||
|
||||
/** Get race detail */
|
||||
@@ -90,4 +92,9 @@ export class RacesApiClient extends BaseApiClient {
|
||||
reopen(raceId: string): Promise<void> {
|
||||
return this.post<void>(`/races/${raceId}/reopen`, {});
|
||||
}
|
||||
}
|
||||
|
||||
/** File a protest */
|
||||
fileProtest(input: FileProtestCommandDTO): Promise<void> {
|
||||
return this.post<void>('/races/protests/file', input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,11 @@ import {
|
||||
} from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import type { AuthSession } from './AuthService';
|
||||
import type { SessionViewModel } from '@/lib/view-models/SessionViewModel';
|
||||
import { useServices } from '@/lib/services/ServiceProvider';
|
||||
|
||||
type AuthContextValue = {
|
||||
session: AuthSession | null;
|
||||
session: SessionViewModel | null;
|
||||
loading: boolean;
|
||||
login: (returnTo?: string) => void;
|
||||
logout: () => Promise<void>;
|
||||
@@ -24,33 +25,24 @@ type AuthContextValue = {
|
||||
const AuthContext = createContext<AuthContextValue | undefined>(undefined);
|
||||
|
||||
interface AuthProviderProps {
|
||||
initialSession?: AuthSession | null;
|
||||
initialSession?: SessionViewModel | null;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function AuthProvider({ initialSession = null, children }: AuthProviderProps) {
|
||||
const router = useRouter();
|
||||
const [session, setSession] = useState<AuthSession | null>(initialSession);
|
||||
const { sessionService, authService } = useServices();
|
||||
const [session, setSession] = useState<SessionViewModel | null>(initialSession);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const fetchSession = useCallback(async () => {
|
||||
try {
|
||||
const res = await fetch('/api/auth/session', {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
setSession(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = (await res.json()) as { session: AuthSession | null };
|
||||
setSession(data.session ?? null);
|
||||
const current = await sessionService.getSession();
|
||||
setSession(current);
|
||||
} catch {
|
||||
setSession(null);
|
||||
}
|
||||
}, []);
|
||||
}, [sessionService]);
|
||||
|
||||
const refreshSession = useCallback(async () => {
|
||||
await fetchSession();
|
||||
@@ -79,17 +71,14 @@ export function AuthProvider({ initialSession = null, children }: AuthProviderPr
|
||||
const logout = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await fetch('/api/auth/logout', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
});
|
||||
await authService.logout();
|
||||
setSession(null);
|
||||
router.push('/');
|
||||
router.refresh();
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [router]);
|
||||
}, [authService, router]);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
@@ -111,4 +100,4 @@ export function useAuth(): AuthContextValue {
|
||||
throw new Error('useAuth must be used within an AuthProvider');
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CreateLeagueInputDTO } from '@/lib/types/CreateLeagueInputDTO';
|
||||
import type { CreateLeagueInputDTO } from '@/lib/types/generated/CreateLeagueInputDTO';
|
||||
import { LeagueWizardValidationMessages } from '@/lib/display-objects/LeagueWizardValidationMessages';
|
||||
import { ScoringPresetApplier } from '@/lib/utilities/ScoringPresetApplier';
|
||||
|
||||
@@ -267,21 +267,11 @@ export class LeagueWizardCommandModel {
|
||||
}
|
||||
|
||||
toCreateLeagueCommand(ownerId: string): CreateLeagueInputDTO {
|
||||
let maxMembers: number;
|
||||
|
||||
if (this.structure.mode === 'solo') {
|
||||
maxMembers = this.structure.maxDrivers ?? 0;
|
||||
} else {
|
||||
const teams = this.structure.maxTeams ?? 0;
|
||||
const perTeam = this.structure.driversPerTeam ?? 0;
|
||||
maxMembers = teams * perTeam;
|
||||
}
|
||||
|
||||
return {
|
||||
name: this.basics.name.trim(),
|
||||
description: this.basics.description?.trim() ?? '',
|
||||
isPublic: this.basics.visibility === 'public',
|
||||
maxMembers,
|
||||
// API currently only supports public/private. Treat unlisted as private for now.
|
||||
visibility: this.basics.visibility === 'public' ? 'public' : 'private',
|
||||
ownerId,
|
||||
};
|
||||
}
|
||||
@@ -311,4 +301,4 @@ export class LeagueWizardCommandModel {
|
||||
stewarding: instance.stewarding,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import { PenaltiesApiClient } from '../api/penalties/PenaltiesApiClient';
|
||||
import { PenaltyService } from './penalties/PenaltyService';
|
||||
import { ConsoleErrorReporter } from '../infrastructure/logging/ConsoleErrorReporter';
|
||||
import { ConsoleLogger } from '../infrastructure/logging/ConsoleLogger';
|
||||
import { LandingService } from './landing/LandingService';
|
||||
|
||||
// Services
|
||||
import { RaceService } from './races/RaceService';
|
||||
@@ -88,6 +89,23 @@ export class ServiceFactory {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy compatibility: older pages/components were written against a static ServiceFactory.
|
||||
* Prefer `useServices()` + react-query hooks.
|
||||
*/
|
||||
private static defaultInstance: ServiceFactory | null = null;
|
||||
|
||||
private static getDefaultInstance(): ServiceFactory {
|
||||
if (!this.defaultInstance) {
|
||||
this.defaultInstance = new ServiceFactory(process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001');
|
||||
}
|
||||
return this.defaultInstance;
|
||||
}
|
||||
|
||||
static getSponsorService(): SponsorService {
|
||||
return this.getDefaultInstance().createSponsorService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create RaceService instance
|
||||
*/
|
||||
@@ -151,8 +169,8 @@ export class ServiceFactory {
|
||||
/**
|
||||
* Create LeagueMembershipService instance
|
||||
*/
|
||||
createLeagueMembershipService(): LeagueMembershipService {
|
||||
return new LeagueMembershipService(this.apiClients.leagues);
|
||||
createLeagueMembershipService(): LeagueMembershipService {
|
||||
return new LeagueMembershipService();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,4 +297,11 @@ export class ServiceFactory {
|
||||
createPenaltyService(): PenaltyService {
|
||||
return new PenaltyService(this.apiClients.penalties);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create LandingService instance (used by server components)
|
||||
*/
|
||||
createLandingService(): LandingService {
|
||||
return new LandingService(this.apiClients.races, this.apiClients.leagues, this.apiClients.teams);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
'use client';
|
||||
|
||||
import React, { createContext, useContext, useMemo, ReactNode } from 'react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { createContext, ReactNode, useContext, useMemo } from 'react';
|
||||
import { ServiceFactory } from './ServiceFactory';
|
||||
|
||||
// Import all service types
|
||||
import { RaceService } from './races/RaceService';
|
||||
import { RaceResultsService } from './races/RaceResultsService';
|
||||
import { RaceStewardingService } from './races/RaceStewardingService';
|
||||
import { DriverService } from './drivers/DriverService';
|
||||
import { AnalyticsService } from './analytics/AnalyticsService';
|
||||
import { AuthService } from './auth/AuthService';
|
||||
import { SessionService } from './auth/SessionService';
|
||||
import { DashboardService } from './dashboard/DashboardService';
|
||||
import { DriverRegistrationService } from './drivers/DriverRegistrationService';
|
||||
import { TeamService } from './teams/TeamService';
|
||||
import { TeamJoinService } from './teams/TeamJoinService';
|
||||
import { LeagueService } from './leagues/LeagueService';
|
||||
import { DriverService } from './drivers/DriverService';
|
||||
import { LeagueMembershipService } from './leagues/LeagueMembershipService';
|
||||
import { LeagueService } from './leagues/LeagueService';
|
||||
import { LeagueSettingsService } from './leagues/LeagueSettingsService';
|
||||
import { LeagueStewardingService } from './leagues/LeagueStewardingService';
|
||||
import { LeagueWalletService } from './leagues/LeagueWalletService';
|
||||
import { AvatarService } from './media/AvatarService';
|
||||
import { MediaService } from './media/MediaService';
|
||||
import { MembershipFeeService } from './payments/MembershipFeeService';
|
||||
import { PaymentService } from './payments/PaymentService';
|
||||
import { WalletService } from './payments/WalletService';
|
||||
import { PenaltyService } from './penalties/PenaltyService';
|
||||
import { ProtestService } from './protests/ProtestService';
|
||||
import { RaceResultsService } from './races/RaceResultsService';
|
||||
import { RaceService } from './races/RaceService';
|
||||
import { RaceStewardingService } from './races/RaceStewardingService';
|
||||
import { SponsorService } from './sponsors/SponsorService';
|
||||
import { SponsorshipService } from './sponsors/SponsorshipService';
|
||||
import { PaymentService } from './payments/PaymentService';
|
||||
import { AnalyticsService } from './analytics/AnalyticsService';
|
||||
import { DashboardService } from './dashboard/DashboardService';
|
||||
import { MediaService } from './media/MediaService';
|
||||
import { AvatarService } from './media/AvatarService';
|
||||
import { WalletService } from './payments/WalletService';
|
||||
import { MembershipFeeService } from './payments/MembershipFeeService';
|
||||
import { AuthService } from './auth/AuthService';
|
||||
import { SessionService } from './auth/SessionService';
|
||||
import { ProtestService } from './protests/ProtestService';
|
||||
import { PenaltyService } from './penalties/PenaltyService';
|
||||
import { TeamJoinService } from './teams/TeamJoinService';
|
||||
import { TeamService } from './teams/TeamService';
|
||||
|
||||
export interface Services {
|
||||
raceService: RaceService;
|
||||
@@ -115,7 +115,7 @@ export function ServiceProvider({ children }: ServiceProviderProps) {
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
// Before using this check for enhanced hooks that use react-query
|
||||
export function useServices(): Services {
|
||||
const services = useContext(ServicesContext);
|
||||
if (!services) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { AuthApiClient } from '../../api/auth/AuthApiClient';
|
||||
import { SessionViewModel } from '../../view-models/SessionViewModel';
|
||||
import type { LoginParams } from '../../types/generated/LoginParams';
|
||||
import type { SignupParams } from '../../types/generated/SignupParams';
|
||||
import type { LoginWithIracingCallbackParams } from '../../types/generated/LoginWithIracingCallbackParams';
|
||||
import type { LoginParamsDTO } from '../../types/generated/LoginParamsDTO';
|
||||
import type { SignupParamsDTO } from '../../types/generated/SignupParamsDTO';
|
||||
import type { LoginWithIracingCallbackParamsDTO } from '../../types/generated/LoginWithIracingCallbackParamsDTO';
|
||||
|
||||
/**
|
||||
* Auth Service
|
||||
@@ -18,7 +18,7 @@ export class AuthService {
|
||||
/**
|
||||
* Sign up a new user
|
||||
*/
|
||||
async signup(params: SignupParams): Promise<SessionViewModel> {
|
||||
async signup(params: SignupParamsDTO): Promise<SessionViewModel> {
|
||||
try {
|
||||
const dto = await this.apiClient.signup(params);
|
||||
return new SessionViewModel(dto.user);
|
||||
@@ -30,7 +30,7 @@ export class AuthService {
|
||||
/**
|
||||
* Log in an existing user
|
||||
*/
|
||||
async login(params: LoginParams): Promise<SessionViewModel> {
|
||||
async login(params: LoginParamsDTO): Promise<SessionViewModel> {
|
||||
try {
|
||||
const dto = await this.apiClient.login(params);
|
||||
return new SessionViewModel(dto.user);
|
||||
@@ -60,7 +60,7 @@ export class AuthService {
|
||||
/**
|
||||
* Login with iRacing callback
|
||||
*/
|
||||
async loginWithIracingCallback(params: LoginWithIracingCallbackParams): Promise<SessionViewModel> {
|
||||
async loginWithIracingCallback(params: LoginWithIracingCallbackParamsDTO): Promise<SessionViewModel> {
|
||||
try {
|
||||
const dto = await this.apiClient.loginWithIracingCallback(params);
|
||||
return new SessionViewModel(dto.user);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { DriversApiClient } from "@/lib/api/drivers/DriversApiClient";
|
||||
import { CompleteOnboardingInputDTO } from "@/lib/types/generated/CompleteOnboardingInputDTO";
|
||||
import { DriverProfileDTO } from "@/lib/types/generated/DriverProfileDTO";
|
||||
import type { DriverDTO } from "@/lib/types/generated/DriverDTO";
|
||||
import { DriversApiClient } from '@/lib/api/drivers/DriversApiClient';
|
||||
import type { CompleteOnboardingInputDTO } from '@/lib/types/generated/CompleteOnboardingInputDTO';
|
||||
import type { GetDriverOutputDTO } from '@/lib/types/generated/GetDriverOutputDTO';
|
||||
import { CompleteOnboardingViewModel } from "@/lib/view-models/CompleteOnboardingViewModel";
|
||||
import { DriverLeaderboardViewModel } from "@/lib/view-models/DriverLeaderboardViewModel";
|
||||
import { DriverViewModel } from "@/lib/view-models/DriverViewModel";
|
||||
@@ -50,7 +49,92 @@ export class DriverService {
|
||||
*/
|
||||
async getDriverProfile(driverId: string): Promise<DriverProfileViewModel> {
|
||||
const dto = await this.apiClient.getDriverProfile(driverId);
|
||||
return new DriverProfileViewModel(dto);
|
||||
return new DriverProfileViewModel({
|
||||
currentDriver: dto.currentDriver
|
||||
? {
|
||||
id: dto.currentDriver.id,
|
||||
name: dto.currentDriver.name,
|
||||
country: dto.currentDriver.country,
|
||||
avatarUrl: dto.currentDriver.avatarUrl,
|
||||
iracingId: dto.currentDriver.iracingId ?? null,
|
||||
joinedAt: dto.currentDriver.joinedAt,
|
||||
rating: dto.currentDriver.rating ?? null,
|
||||
globalRank: dto.currentDriver.globalRank ?? null,
|
||||
consistency: dto.currentDriver.consistency ?? null,
|
||||
bio: dto.currentDriver.bio ?? null,
|
||||
totalDrivers: dto.currentDriver.totalDrivers ?? null,
|
||||
}
|
||||
: null,
|
||||
stats: dto.stats
|
||||
? {
|
||||
totalRaces: dto.stats.totalRaces,
|
||||
wins: dto.stats.wins,
|
||||
podiums: dto.stats.podiums,
|
||||
dnfs: dto.stats.dnfs,
|
||||
avgFinish: dto.stats.avgFinish ?? null,
|
||||
bestFinish: dto.stats.bestFinish ?? null,
|
||||
worstFinish: dto.stats.worstFinish ?? null,
|
||||
finishRate: dto.stats.finishRate ?? null,
|
||||
winRate: dto.stats.winRate ?? null,
|
||||
podiumRate: dto.stats.podiumRate ?? null,
|
||||
percentile: dto.stats.percentile ?? null,
|
||||
rating: dto.stats.rating ?? null,
|
||||
consistency: dto.stats.consistency ?? null,
|
||||
overallRank: dto.stats.overallRank ?? null,
|
||||
}
|
||||
: null,
|
||||
finishDistribution: dto.finishDistribution
|
||||
? {
|
||||
totalRaces: dto.finishDistribution.totalRaces,
|
||||
wins: dto.finishDistribution.wins,
|
||||
podiums: dto.finishDistribution.podiums,
|
||||
topTen: dto.finishDistribution.topTen,
|
||||
dnfs: dto.finishDistribution.dnfs,
|
||||
other: dto.finishDistribution.other,
|
||||
}
|
||||
: null,
|
||||
teamMemberships: dto.teamMemberships.map((m) => ({
|
||||
teamId: m.teamId,
|
||||
teamName: m.teamName,
|
||||
teamTag: m.teamTag ?? null,
|
||||
role: m.role,
|
||||
joinedAt: m.joinedAt,
|
||||
isCurrent: m.isCurrent,
|
||||
})),
|
||||
socialSummary: {
|
||||
friendsCount: dto.socialSummary.friendsCount,
|
||||
friends: dto.socialSummary.friends.map((f) => ({
|
||||
id: f.id,
|
||||
name: f.name,
|
||||
country: f.country,
|
||||
avatarUrl: f.avatarUrl,
|
||||
})),
|
||||
},
|
||||
extendedProfile: dto.extendedProfile
|
||||
? {
|
||||
socialHandles: dto.extendedProfile.socialHandles.map((h) => ({
|
||||
platform: h.platform as any,
|
||||
handle: h.handle,
|
||||
url: h.url,
|
||||
})),
|
||||
achievements: dto.extendedProfile.achievements.map((a) => ({
|
||||
id: a.id,
|
||||
title: a.title,
|
||||
description: a.description,
|
||||
icon: a.icon as any,
|
||||
rarity: a.rarity as any,
|
||||
earnedAt: a.earnedAt,
|
||||
})),
|
||||
racingStyle: dto.extendedProfile.racingStyle,
|
||||
favoriteTrack: dto.extendedProfile.favoriteTrack,
|
||||
favoriteCar: dto.extendedProfile.favoriteCar,
|
||||
timezone: dto.extendedProfile.timezone,
|
||||
availableHours: dto.extendedProfile.availableHours,
|
||||
lookingForTeam: dto.extendedProfile.lookingForTeam,
|
||||
openToRequests: dto.extendedProfile.openToRequests,
|
||||
}
|
||||
: null,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,15 +149,15 @@ export class DriverService {
|
||||
/**
|
||||
* Find driver by ID
|
||||
*/
|
||||
async findById(id: string): Promise<DriverDTO | null> {
|
||||
async findById(id: string): Promise<GetDriverOutputDTO | null> {
|
||||
return this.apiClient.getDriver(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find multiple drivers by IDs
|
||||
*/
|
||||
async findByIds(ids: string[]): Promise<DriverDTO[]> {
|
||||
async findByIds(ids: string[]): Promise<GetDriverOutputDTO[]> {
|
||||
const drivers = await Promise.all(ids.map(id => this.apiClient.getDriver(id)));
|
||||
return drivers.filter((d): d is DriverDTO => d !== null);
|
||||
return drivers.filter((d): d is GetDriverOutputDTO => d !== null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,17 @@
|
||||
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
||||
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
||||
import { TeamsApiClient } from '@/lib/api/teams/TeamsApiClient';
|
||||
import type { AllLeaguesWithCapacityDTO } from '@/lib/types/generated/AllLeaguesWithCapacityDTO';
|
||||
import type { GetAllTeamsOutputDTO } from '@/lib/types/generated/GetAllTeamsOutputDTO';
|
||||
import type { RacesPageDataDTO } from '@/lib/types/generated/RacesPageDataDTO';
|
||||
import type { LeagueSummaryDTO } from '@/lib/types/generated/LeagueSummaryDTO';
|
||||
import type { GetAllTeamsOutputDTO, TeamListItemDTO } from '@/lib/types/generated/GetAllTeamsOutputDTO';
|
||||
import type { TeamListItemDTO } from '@/lib/types/generated/TeamListItemDTO';
|
||||
import { RacesPageViewModel } from '@/lib/view-models/RacesPageViewModel';
|
||||
import { HomeDiscoveryViewModel } from '@/lib/view-models/HomeDiscoveryViewModel';
|
||||
import { LeagueCardViewModel } from '@/lib/view-models/LeagueCardViewModel';
|
||||
import { TeamCardViewModel } from '@/lib/view-models/TeamCardViewModel';
|
||||
import { UpcomingRaceCardViewModel } from '@/lib/view-models/UpcomingRaceCardViewModel';
|
||||
|
||||
// DTO matching backend RacesPageDataDTO for discovery usage
|
||||
interface RacesPageDataDTO {
|
||||
races: {
|
||||
id: string;
|
||||
track: string;
|
||||
car: string;
|
||||
scheduledAt: string;
|
||||
status: string;
|
||||
leagueId: string;
|
||||
leagueName: string;
|
||||
strengthOfField: number | null;
|
||||
isUpcoming: boolean;
|
||||
isLive: boolean;
|
||||
isPast: boolean;
|
||||
}[];
|
||||
}
|
||||
|
||||
export class LandingService {
|
||||
constructor(
|
||||
private readonly racesApi: RacesApiClient,
|
||||
@@ -36,21 +22,21 @@ export class LandingService {
|
||||
async getHomeDiscovery(): Promise<HomeDiscoveryViewModel> {
|
||||
const [racesDto, leaguesDto, teamsDto] = await Promise.all([
|
||||
this.racesApi.getPageData() as Promise<RacesPageDataDTO>,
|
||||
this.leaguesApi.getAllWithCapacity() as Promise<{ leagues: LeagueSummaryDTO[] }>,
|
||||
this.teamsApi.getAll(),
|
||||
this.leaguesApi.getAllWithCapacity() as Promise<AllLeaguesWithCapacityDTO>,
|
||||
this.teamsApi.getAll() as Promise<GetAllTeamsOutputDTO>,
|
||||
]);
|
||||
|
||||
const racesVm = new RacesPageViewModel(racesDto);
|
||||
|
||||
const topLeagues = leaguesDto.leagues.slice(0, 4).map(
|
||||
league => new LeagueCardViewModel({
|
||||
(league: LeagueSummaryDTO) => new LeagueCardViewModel({
|
||||
id: league.id,
|
||||
name: league.name,
|
||||
description: 'Competitive iRacing league',
|
||||
}),
|
||||
);
|
||||
|
||||
const teams = (teamsDto as GetAllTeamsOutputDTO).teams.slice(0, 4).map(
|
||||
const teams = teamsDto.teams.slice(0, 4).map(
|
||||
(team: TeamListItemDTO) =>
|
||||
new TeamCardViewModel({
|
||||
id: team.id,
|
||||
|
||||
@@ -47,6 +47,26 @@ export class LeagueMembershipService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a league.
|
||||
*
|
||||
* NOTE: The API currently exposes membership mutations via league member management endpoints.
|
||||
* For now we keep the website decoupled by consuming only the API through this service.
|
||||
*/
|
||||
async joinLeague(leagueId: string, driverId: string): Promise<void> {
|
||||
// Temporary: no join endpoint exposed yet in API.
|
||||
// Keep behavior predictable for UI.
|
||||
throw new Error('Joining leagues is not available in this build.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a league.
|
||||
*/
|
||||
async leaveLeague(leagueId: string, driverId: string): Promise<void> {
|
||||
// Temporary: no leave endpoint exposed yet in API.
|
||||
throw new Error('Leaving leagues is not available in this build.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set memberships in cache (for use after API calls).
|
||||
*/
|
||||
@@ -118,4 +138,4 @@ export class LeagueMembershipService {
|
||||
clearLeagueMemberships(leagueId: string): void {
|
||||
LeagueMembershipService.clearLeagueMemberships(leagueId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import { SubmitBlocker, ThrottleBlocker } from "@/lib/blockers";
|
||||
import { RaceDTO } from "@/lib/types/generated/RaceDTO";
|
||||
import { LeagueStatsDTO } from "@/lib/types/generated/LeagueStatsDTO";
|
||||
import { LeagueScoringConfigDTO } from "@/lib/types/LeagueScoringConfigDTO";
|
||||
import type { LeagueMembership } from "@/lib/types/LeagueMembership";
|
||||
import type { LeagueSeasonSummaryDTO } from '@/lib/types/generated/LeagueSeasonSummaryDTO';
|
||||
|
||||
|
||||
/**
|
||||
@@ -48,9 +50,9 @@ export class LeagueService {
|
||||
name: league.name,
|
||||
description: league.description ?? '',
|
||||
ownerId: league.ownerId,
|
||||
createdAt: '', // Not provided by API
|
||||
maxDrivers: league.maxMembers,
|
||||
usedDriverSlots: league.memberCount,
|
||||
createdAt: league.createdAt,
|
||||
maxDrivers: league.settings.maxDrivers ?? 0,
|
||||
usedDriverSlots: league.usedSlots,
|
||||
structureSummary: 'TBD',
|
||||
timingSummary: 'TBD'
|
||||
}));
|
||||
@@ -66,16 +68,20 @@ export class LeagueService {
|
||||
// League memberships (roles, statuses)
|
||||
const membershipsDto = await this.apiClient.getMemberships(leagueId);
|
||||
|
||||
const memberships: LeagueMembership[] = membershipsDto.members.map((m) => ({
|
||||
driverId: m.driverId,
|
||||
leagueId,
|
||||
role: (m.role as LeagueMembership['role']) ?? 'member',
|
||||
joinedAt: m.joinedAt,
|
||||
status: 'active',
|
||||
}));
|
||||
|
||||
// Resolve unique drivers that appear in standings
|
||||
const driverIds: string[] = Array.from(new Set(dto.standings.map((entry: any) => entry.driverId)));
|
||||
const driverDtos = await Promise.all(driverIds.map((id: string) => this.driversApiClient.getDriver(id)));
|
||||
const drivers = driverDtos.filter((d): d is NonNullable<typeof d> => d !== null);
|
||||
|
||||
const dtoWithExtras = {
|
||||
standings: dto.standings,
|
||||
drivers,
|
||||
memberships: membershipsDto.members,
|
||||
};
|
||||
const dtoWithExtras = { standings: dto.standings, drivers, memberships };
|
||||
|
||||
return new LeagueStandingsViewModel(dtoWithExtras, currentUserId);
|
||||
}
|
||||
@@ -96,6 +102,13 @@ export class LeagueService {
|
||||
return new LeagueScheduleViewModel(dto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get seasons for a league
|
||||
*/
|
||||
async getLeagueSeasons(leagueId: string): Promise<LeagueSeasonSummaryDTO[]> {
|
||||
return this.apiClient.getSeasons(leagueId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get league memberships
|
||||
*/
|
||||
@@ -162,18 +175,19 @@ export class LeagueService {
|
||||
// Get membership
|
||||
const membershipsDto = await this.apiClient.getMemberships(leagueId);
|
||||
const membership = membershipsDto.members.find((m: any) => m.driverId === currentDriverId);
|
||||
const isAdmin = membership ? ['admin', 'owner'].includes(membership.role) : false;
|
||||
const isAdmin = membership ? ['admin', 'owner'].includes((membership as any).role) : false;
|
||||
|
||||
// Get main sponsor
|
||||
let mainSponsor = null;
|
||||
try {
|
||||
const seasonsDto = await this.apiClient.getSeasons(leagueId);
|
||||
const activeSeason = seasonsDto.seasons.find((s: any) => s.status === 'active') ?? seasonsDto.seasons[0];
|
||||
const seasons = await this.apiClient.getSeasons(leagueId);
|
||||
const activeSeason = seasons.find((s) => s.status === 'active') ?? seasons[0];
|
||||
if (activeSeason) {
|
||||
const sponsorshipsDto = await this.apiClient.getSeasonSponsorships(activeSeason.id);
|
||||
const sponsorshipsDto = await this.apiClient.getSeasonSponsorships(activeSeason.seasonId);
|
||||
const mainSponsorship = sponsorshipsDto.sponsorships.find((s: any) => s.tier === 'main' && s.status === 'active');
|
||||
if (mainSponsorship) {
|
||||
const sponsor = await this.sponsorsApiClient.getSponsor(mainSponsorship.sponsorId);
|
||||
const sponsorResult = await this.sponsorsApiClient.getSponsor((mainSponsorship as any).sponsorId ?? (mainSponsorship as any).sponsor?.id);
|
||||
const sponsor = (sponsorResult as any)?.sponsor ?? null;
|
||||
if (sponsor) {
|
||||
mainSponsor = {
|
||||
name: sponsor.name,
|
||||
@@ -241,7 +255,11 @@ export class LeagueService {
|
||||
const allRaces = leagueRaces.races.map(r => new RaceViewModel(r as RaceDTO));
|
||||
|
||||
// League stats endpoint currently returns global league statistics rather than per-league values
|
||||
const leagueStats = await this.apiClient.getTotal();
|
||||
const leagueStats: LeagueStatsDTO = {
|
||||
totalMembers: league.usedSlots,
|
||||
totalRaces: allRaces.length,
|
||||
averageRating: 0,
|
||||
};
|
||||
|
||||
// Get sponsors
|
||||
const sponsors = await this.getLeagueSponsors(leagueId);
|
||||
@@ -268,16 +286,17 @@ export class LeagueService {
|
||||
private async getLeagueSponsors(leagueId: string): Promise<SponsorInfo[]> {
|
||||
try {
|
||||
const seasons = await this.apiClient.getSeasons(leagueId);
|
||||
const activeSeason = seasons.seasons.find((s: any) => s.status === 'active') ?? seasons.seasons[0];
|
||||
const activeSeason = seasons.find((s) => s.status === 'active') ?? seasons[0];
|
||||
|
||||
if (!activeSeason) return [];
|
||||
|
||||
const sponsorships = await this.apiClient.getSeasonSponsorships(activeSeason.id);
|
||||
const sponsorships = await this.apiClient.getSeasonSponsorships(activeSeason.seasonId);
|
||||
const activeSponsorships = sponsorships.sponsorships.filter((s: any) => s.status === 'active');
|
||||
|
||||
const sponsorInfos: SponsorInfo[] = [];
|
||||
for (const sponsorship of activeSponsorships) {
|
||||
const sponsor = await this.sponsorsApiClient.getSponsor(sponsorship.sponsorId);
|
||||
const sponsorResult = await this.sponsorsApiClient.getSponsor((sponsorship as any).sponsorId ?? (sponsorship as any).sponsor?.id);
|
||||
const sponsor = (sponsorResult as any)?.sponsor ?? null;
|
||||
if (sponsor) {
|
||||
// Tagline is not supplied by the sponsor API in this build; callers may derive one from marketing content if needed
|
||||
sponsorInfos.push({
|
||||
@@ -285,7 +304,7 @@ export class LeagueService {
|
||||
name: sponsor.name,
|
||||
logoUrl: sponsor.logoUrl ?? '',
|
||||
websiteUrl: sponsor.websiteUrl ?? '',
|
||||
tier: sponsorship.tier,
|
||||
tier: ((sponsorship as any).tier as 'main' | 'secondary') ?? 'secondary',
|
||||
tagline: '',
|
||||
});
|
||||
}
|
||||
@@ -312,4 +331,4 @@ export class LeagueService {
|
||||
const result = await this.apiClient.getScoringPresets();
|
||||
return result.presets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { LeaguesApiClient } from "@/lib/api/leagues/LeaguesApiClient";
|
||||
import { DriversApiClient } from "@/lib/api/drivers/DriversApiClient";
|
||||
import type { LeagueConfigFormModel } from "@core/racing/application";
|
||||
import type { LeagueScoringPresetDTO } from "@core/racing/application/ports/LeagueScoringPresetProvider";
|
||||
import type { GetDriverOutputDTO } from "@/lib/types/generated/GetDriverOutputDTO";
|
||||
import type { LeagueConfigFormModel } from "@/lib/types/LeagueConfigFormModel";
|
||||
import type { LeagueScoringPresetDTO } from "@/lib/types/generated/LeagueScoringPresetDTO";
|
||||
import { LeagueSettingsViewModel } from "@/lib/view-models/LeagueSettingsViewModel";
|
||||
import { DriverSummaryViewModel } from "@/lib/view-models/DriverSummaryViewModel";
|
||||
|
||||
@@ -36,7 +35,7 @@ export class LeagueSettingsService {
|
||||
|
||||
// Get config
|
||||
const configDto = await this.leaguesApiClient.getLeagueConfig(leagueId);
|
||||
const config: LeagueConfigFormModel = configDto.config;
|
||||
const config: LeagueConfigFormModel = (configDto.form ?? undefined) as unknown as LeagueConfigFormModel;
|
||||
|
||||
// Get presets
|
||||
const presetsDto = await this.leaguesApiClient.getScoringPresets();
|
||||
@@ -102,4 +101,4 @@ export class LeagueSettingsService {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { RacesApiClient } from '../../api/races/RacesApiClient';
|
||||
import { RaceDetailViewModel } from '../../view-models/RaceDetailViewModel';
|
||||
import { RacesPageViewModel } from '../../view-models/RacesPageViewModel';
|
||||
import { RaceStatsViewModel } from '../../view-models/RaceStatsViewModel';
|
||||
import type { FileProtestCommandDTO } from '../../types/generated/FileProtestCommandDTO';
|
||||
import type { RaceStatsDTO } from '../../types/generated/RaceStatsDTO';
|
||||
/**
|
||||
* Race Service
|
||||
@@ -33,6 +34,14 @@ export class RaceService {
|
||||
return new RacesPageViewModel(dto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get races page data filtered by league
|
||||
*/
|
||||
async getLeagueRacesPageData(leagueId: string): Promise<RacesPageViewModel> {
|
||||
const dto = await this.apiClient.getPageData(leagueId);
|
||||
return new RacesPageViewModel(dto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all races page data with view model transformation
|
||||
* Currently same as getRacesPageData, but can be extended for different filtering
|
||||
@@ -54,14 +63,14 @@ export class RaceService {
|
||||
* Register for a race
|
||||
*/
|
||||
async registerForRace(raceId: string, leagueId: string, driverId: string): Promise<void> {
|
||||
await this.apiClient.register(raceId, { leagueId, driverId });
|
||||
await this.apiClient.register(raceId, { raceId, leagueId, driverId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraw from a race
|
||||
*/
|
||||
async withdrawFromRace(raceId: string, driverId: string): Promise<void> {
|
||||
await this.apiClient.withdraw(raceId, { driverId });
|
||||
await this.apiClient.withdraw(raceId, { raceId, driverId });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,6 +94,13 @@ export class RaceService {
|
||||
await this.apiClient.reopen(raceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* File a protest
|
||||
*/
|
||||
async fileProtest(input: FileProtestCommandDTO): Promise<void> {
|
||||
await this.apiClient.fileProtest(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find races by league ID
|
||||
*
|
||||
@@ -92,7 +108,8 @@ export class RaceService {
|
||||
* so this method deliberately signals that the operation is unavailable instead of making
|
||||
* assumptions about URL structure.
|
||||
*/
|
||||
async findByLeagueId(_leagueId: string): Promise<never> {
|
||||
throw new Error('Finding races by league ID is not supported in this build');
|
||||
async findByLeagueId(leagueId: string): Promise<RacesPageViewModel['races']> {
|
||||
const page = await this.getLeagueRacesPageData(leagueId);
|
||||
return page.races;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { SponsorsApiClient } from '../../api/sponsors/SponsorsApiClient';
|
||||
import type { GetEntitySponsorshipPricingResultDto } from '../../api/sponsors/SponsorsApiClient';
|
||||
import { SponsorshipPricingViewModel } from '../../view-models/SponsorshipPricingViewModel';
|
||||
import { SponsorSponsorshipsViewModel } from '../../view-models/SponsorSponsorshipsViewModel';
|
||||
import { SponsorshipRequestViewModel } from '../../view-models/SponsorshipRequestViewModel';
|
||||
import type { SponsorSponsorshipsDTO } from '../../types/generated';
|
||||
import type { GetPendingSponsorshipRequestsOutputDTO } from '../../types/generated/GetPendingSponsorshipRequestsOutputDTO';
|
||||
import type { SponsorshipRequestDTO } from '../../types/generated/SponsorshipRequestDTO';
|
||||
|
||||
/**
|
||||
* Sponsorship Service
|
||||
@@ -20,8 +20,16 @@ export class SponsorshipService {
|
||||
* Get sponsorship pricing with view model transformation
|
||||
*/
|
||||
async getSponsorshipPricing(): Promise<SponsorshipPricingViewModel> {
|
||||
// Pricing shape isn't finalized in the API yet.
|
||||
// Keep a predictable, UI-friendly structure until a dedicated DTO is introduced.
|
||||
const dto = await this.apiClient.getPricing();
|
||||
return new SponsorshipPricingViewModel(dto);
|
||||
const main = dto.pricing.find((p) => p.entityType === 'main')?.price ?? 0;
|
||||
const secondary = dto.pricing.find((p) => p.entityType === 'secondary')?.price ?? 0;
|
||||
return new SponsorshipPricingViewModel({
|
||||
mainSlotPrice: main,
|
||||
secondarySlotPrice: secondary,
|
||||
currency: 'USD',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,21 +47,22 @@ export class SponsorshipService {
|
||||
* Get pending sponsorship requests for an entity
|
||||
*/
|
||||
async getPendingSponsorshipRequests(params: { entityType: string; entityId: string }): Promise<SponsorshipRequestViewModel[]> {
|
||||
const dto = await this.apiClient.getPendingSponsorshipRequests(params);
|
||||
return dto.requests.map(dto => new SponsorshipRequestViewModel(dto));
|
||||
const dto = (await this.apiClient.getPendingSponsorshipRequests(params)) as unknown as GetPendingSponsorshipRequestsOutputDTO;
|
||||
const requests = (dto as any).requests as SponsorshipRequestDTO[];
|
||||
return (requests ?? []).map((r: SponsorshipRequestDTO) => new SponsorshipRequestViewModel(r));
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a sponsorship request
|
||||
*/
|
||||
async acceptSponsorshipRequest(requestId: string, respondedBy: string): Promise<void> {
|
||||
await this.apiClient.acceptSponsorshipRequest(requestId, respondedBy);
|
||||
await this.apiClient.acceptSponsorshipRequest(requestId, { respondedBy });
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject a sponsorship request
|
||||
*/
|
||||
async rejectSponsorshipRequest(requestId: string, respondedBy: string, reason?: string): Promise<void> {
|
||||
await this.apiClient.rejectSponsorshipRequest(requestId, respondedBy, reason);
|
||||
await this.apiClient.rejectSponsorshipRequest(requestId, { respondedBy, ...(reason ? { reason } : {}) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import { TeamSummaryViewModel } from '@/lib/view-models/TeamSummaryViewModel';
|
||||
import { CreateTeamViewModel } from '@/lib/view-models/CreateTeamViewModel';
|
||||
import { UpdateTeamViewModel } from '@/lib/view-models/UpdateTeamViewModel';
|
||||
import { DriverTeamViewModel } from '@/lib/view-models/DriverTeamViewModel';
|
||||
import { LeagueMemberDTO } from '@/lib/types/generated/LeagueMemberDTO';
|
||||
import type { TeamsApiClient } from '../../api/teams/TeamsApiClient';
|
||||
import type { GetAllTeamsOutputDTO, TeamListItemDTO } from '@/lib/types/generated/GetAllTeamsOutputDTO';
|
||||
import type { GetAllTeamsOutputDTO } from '@/lib/types/generated/GetAllTeamsOutputDTO';
|
||||
import type { TeamListItemDTO } from '@/lib/types/generated/TeamListItemDTO';
|
||||
import type { GetTeamDetailsOutputDTO } from '@/lib/types/generated/GetTeamDetailsOutputDTO';
|
||||
import type { GetTeamMembersOutputDTO, TeamMemberDTO } from '@/lib/types/generated/GetTeamMembersOutputDTO';
|
||||
import type { GetTeamMembersOutputDTO } from '@/lib/types/generated/GetTeamMembersOutputDTO';
|
||||
import type { TeamMemberDTO } from '@/lib/types/generated/TeamMemberDTO';
|
||||
import type { CreateTeamInputDTO } from '@/lib/types/generated/CreateTeamInputDTO';
|
||||
import type { CreateTeamOutputDTO } from '@/lib/types/generated/CreateTeamOutputDTO';
|
||||
import type { UpdateTeamInputDTO } from '@/lib/types/generated/UpdateTeamInputDTO';
|
||||
@@ -71,19 +72,19 @@ export class TeamService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get driver's team with view model transformation
|
||||
*/
|
||||
async getDriverTeam(driverId: string): Promise<DriverTeamViewModel | null> {
|
||||
const dto: GetDriverTeamOutputDTO | null = await this.apiClient.getDriverTeam(driverId);
|
||||
return dto ? new DriverTeamViewModel(dto) : null;
|
||||
}
|
||||
* Get driver's team with view model transformation
|
||||
*/
|
||||
async getDriverTeam(driverId: string): Promise<DriverTeamViewModel | null> {
|
||||
const dto: GetDriverTeamOutputDTO | null = await this.apiClient.getDriverTeam(driverId);
|
||||
return dto ? new DriverTeamViewModel(dto) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get team membership for a driver
|
||||
*/
|
||||
async getMembership(teamId: string, driverId: string): Promise<GetTeamMembershipOutputDTO | null> {
|
||||
return this.apiClient.getMembership(teamId, driverId);
|
||||
}
|
||||
/**
|
||||
* Get team membership for a driver
|
||||
*/
|
||||
async getMembership(teamId: string, driverId: string): Promise<GetTeamMembershipOutputDTO | null> {
|
||||
return this.apiClient.getMembership(teamId, driverId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a driver from the team
|
||||
@@ -91,11 +92,11 @@ export class TeamService {
|
||||
* The backend does not yet expose a dedicated endpoint for removing team memberships,
|
||||
* so this method fails explicitly to avoid silently ignoring removal requests.
|
||||
*/
|
||||
async removeMembership(teamId: string, driverId: string): Promise<void> {
|
||||
void teamId;
|
||||
void driverId;
|
||||
throw new Error('Team membership removal is not supported in this build');
|
||||
}
|
||||
async removeMembership(teamId: string, driverId: string): Promise<void> {
|
||||
void teamId;
|
||||
void driverId;
|
||||
throw new Error('Team membership removal is not supported in this build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update team membership role
|
||||
@@ -103,10 +104,10 @@ export class TeamService {
|
||||
* Role updates for team memberships are not supported by the current API surface;
|
||||
* callers must treat this as an unavailable operation.
|
||||
*/
|
||||
async updateMembership(teamId: string, driverId: string, role: string): Promise<void> {
|
||||
void teamId;
|
||||
void driverId;
|
||||
void role;
|
||||
throw new Error('Team membership role updates are not supported in this build');
|
||||
}
|
||||
}
|
||||
async updateMembership(teamId: string, driverId: string, role: string): Promise<void> {
|
||||
void teamId;
|
||||
void driverId;
|
||||
void role;
|
||||
throw new Error('Team membership role updates are not supported in this build');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
export interface LeagueConfigFormModel {
|
||||
leagueId?: string;
|
||||
basics?: {
|
||||
basics: {
|
||||
name: string;
|
||||
description?: string;
|
||||
visibility: 'public' | 'private' | 'unlisted';
|
||||
gameId: string;
|
||||
};
|
||||
structure?: {
|
||||
structure: {
|
||||
mode: 'solo' | 'fixedTeams';
|
||||
maxDrivers?: number;
|
||||
maxTeams?: number;
|
||||
driversPerTeam?: number;
|
||||
/** Prototype flag kept for backward compatibility with older wizard UI */
|
||||
multiClassEnabled?: boolean;
|
||||
};
|
||||
championships?: {
|
||||
championships: {
|
||||
enableDriverChampionship: boolean;
|
||||
enableTeamChampionship: boolean;
|
||||
enableNationsChampionship: boolean;
|
||||
enableTrophyChampionship: boolean;
|
||||
};
|
||||
scoring?: {
|
||||
scoring: {
|
||||
patternId?: string;
|
||||
customScoringEnabled?: boolean;
|
||||
};
|
||||
dropPolicy?: {
|
||||
dropPolicy: {
|
||||
strategy: 'none' | 'bestNResults' | 'dropWorstN';
|
||||
n?: number;
|
||||
};
|
||||
timings?: {
|
||||
timings: {
|
||||
practiceMinutes?: number;
|
||||
qualifyingMinutes?: number;
|
||||
sprintRaceMinutes?: number;
|
||||
@@ -39,9 +41,24 @@ export interface LeagueConfigFormModel {
|
||||
recurrenceStrategy?: string;
|
||||
timezoneId?: string;
|
||||
seasonStartDate?: string;
|
||||
/** Prototype fields used by scheduling UI */
|
||||
seasonEndDate?: string;
|
||||
raceStartTime?: string;
|
||||
};
|
||||
stewarding?: {
|
||||
decisionMode: 'owner_only' | 'admin_vote' | 'steward_panel';
|
||||
stewarding: {
|
||||
/**
|
||||
* Matches API `LeagueConfigFormModelStewardingDTO.decisionMode`.
|
||||
* Website should not depend on core enums.
|
||||
*/
|
||||
decisionMode:
|
||||
| 'single_steward'
|
||||
| 'committee_vote'
|
||||
// legacy wizard values
|
||||
| 'owner_only'
|
||||
| 'admin_vote'
|
||||
| 'steward_panel'
|
||||
| 'admin_only'
|
||||
| 'steward_vote';
|
||||
requiredVotes?: number;
|
||||
requireDefense: boolean;
|
||||
defenseTimeLimit: number;
|
||||
@@ -51,4 +68,4 @@ export interface LeagueConfigFormModel {
|
||||
notifyAccusedOnProtest: boolean;
|
||||
notifyOnVoteRequired: boolean;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,8 @@
|
||||
|
||||
export interface ActivityItemDTO {
|
||||
id: string;
|
||||
type: string;
|
||||
message: string;
|
||||
time: string;
|
||||
impressions?: number;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueSummaryDTO } from './LeagueSummaryDTO';
|
||||
|
||||
export interface AllLeaguesWithCapacityAndScoringDTO {
|
||||
leagues: LeagueSummaryDTO[];
|
||||
totalCount: number;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueWithCapacityDTO } from './LeagueWithCapacityDTO';
|
||||
|
||||
export interface AllLeaguesWithCapacityDTO {
|
||||
leagues: LeagueWithCapacityDTO[];
|
||||
totalCount: number;
|
||||
}
|
||||
13
apps/website/lib/types/generated/AllRacesFilterOptionsDTO.ts
Normal file
13
apps/website/lib/types/generated/AllRacesFilterOptionsDTO.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { AllRacesStatusFilterDTO } from './AllRacesStatusFilterDTO';
|
||||
import type { AllRacesLeagueFilterDTO } from './AllRacesLeagueFilterDTO';
|
||||
|
||||
export interface AllRacesFilterOptionsDTO {
|
||||
statuses: AllRacesStatusFilterDTO[];
|
||||
leagues: AllRacesLeagueFilterDTO[];
|
||||
}
|
||||
@@ -12,4 +12,5 @@ export interface AllRacesListItemDTO {
|
||||
status: string;
|
||||
leagueId: string;
|
||||
leagueName: string;
|
||||
strengthOfField?: number;
|
||||
}
|
||||
|
||||
13
apps/website/lib/types/generated/AllRacesPageDTO.ts
Normal file
13
apps/website/lib/types/generated/AllRacesPageDTO.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { AllRacesListItemDTO } from './AllRacesListItemDTO';
|
||||
import type { AllRacesFilterOptionsDTO } from './AllRacesFilterOptionsDTO';
|
||||
|
||||
export interface AllRacesPageDTO {
|
||||
races: AllRacesListItemDTO[];
|
||||
filters: AllRacesFilterOptionsDTO;
|
||||
}
|
||||
@@ -9,4 +9,9 @@ export interface ApplyPenaltyCommandDTO {
|
||||
driverId: string;
|
||||
stewardId: string;
|
||||
enum: string;
|
||||
type: string;
|
||||
value?: number;
|
||||
reason: string;
|
||||
protestId?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@
|
||||
|
||||
export interface ApproveJoinRequestOutputDTO {
|
||||
success: boolean;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,16 @@ export interface AvailableLeagueDTO {
|
||||
id: string;
|
||||
name: string;
|
||||
game: string;
|
||||
drivers: string;
|
||||
avgViewsPerRace: string;
|
||||
drivers: number;
|
||||
avgViewsPerRace: number;
|
||||
mainSponsorSlot: Record<string, unknown>;
|
||||
available: number;
|
||||
price: number;
|
||||
secondarySlots: Record<string, unknown>;
|
||||
total: number;
|
||||
rating: number;
|
||||
tier: string;
|
||||
nextRace?: string;
|
||||
seasonStatus: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
11
apps/website/lib/types/generated/AwardPrizeResultDTO.ts
Normal file
11
apps/website/lib/types/generated/AwardPrizeResultDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { PrizeDTO } from './PrizeDTO';
|
||||
|
||||
export interface AwardPrizeResultDTO {
|
||||
prize: PrizeDTO;
|
||||
}
|
||||
@@ -5,10 +5,10 @@
|
||||
*/
|
||||
|
||||
export interface BillingStatsDTO {
|
||||
totalSpent: string;
|
||||
pendingAmount: string;
|
||||
totalSpent: number;
|
||||
pendingAmount: number;
|
||||
nextPaymentDate: string;
|
||||
nextPaymentAmount: string;
|
||||
activeSponsorships: string;
|
||||
averageMonthlySpend: string;
|
||||
nextPaymentAmount: number;
|
||||
activeSponsorships: number;
|
||||
averageMonthlySpend: number;
|
||||
}
|
||||
|
||||
@@ -9,4 +9,6 @@ export interface CompleteOnboardingInputDTO {
|
||||
lastName: string;
|
||||
displayName: string;
|
||||
country: string;
|
||||
timezone?: string;
|
||||
bio?: string;
|
||||
}
|
||||
|
||||
@@ -6,4 +6,6 @@
|
||||
|
||||
export interface CompleteOnboardingOutputDTO {
|
||||
success: boolean;
|
||||
driverId?: string;
|
||||
errorMessage?: string;
|
||||
}
|
||||
|
||||
@@ -7,4 +7,6 @@
|
||||
export interface CreateLeagueInputDTO {
|
||||
name: string;
|
||||
description: string;
|
||||
visibility: string;
|
||||
ownerId: string;
|
||||
}
|
||||
|
||||
14
apps/website/lib/types/generated/CreatePaymentInputDTO.ts
Normal file
14
apps/website/lib/types/generated/CreatePaymentInputDTO.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
export interface CreatePaymentInputDTO {
|
||||
type: string;
|
||||
amount: number;
|
||||
payerId: string;
|
||||
payerType: string;
|
||||
leagueId: string;
|
||||
seasonId?: string;
|
||||
}
|
||||
11
apps/website/lib/types/generated/CreatePaymentOutputDTO.ts
Normal file
11
apps/website/lib/types/generated/CreatePaymentOutputDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { PaymentDTO } from './PaymentDTO';
|
||||
|
||||
export interface CreatePaymentOutputDTO {
|
||||
payment: PaymentDTO;
|
||||
}
|
||||
11
apps/website/lib/types/generated/CreatePrizeResultDTO.ts
Normal file
11
apps/website/lib/types/generated/CreatePrizeResultDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { PrizeDTO } from './PrizeDTO';
|
||||
|
||||
export interface CreatePrizeResultDTO {
|
||||
prize: PrizeDTO;
|
||||
}
|
||||
@@ -7,4 +7,6 @@
|
||||
export interface CreateSponsorInputDTO {
|
||||
name: string;
|
||||
contactEmail: string;
|
||||
websiteUrl?: string;
|
||||
logoUrl?: string;
|
||||
}
|
||||
|
||||
11
apps/website/lib/types/generated/CreateSponsorOutputDTO.ts
Normal file
11
apps/website/lib/types/generated/CreateSponsorOutputDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { SponsorDTO } from './SponsorDTO';
|
||||
|
||||
export interface CreateSponsorOutputDTO {
|
||||
sponsor: SponsorDTO;
|
||||
}
|
||||
@@ -7,4 +7,5 @@
|
||||
export interface CreateTeamInputDTO {
|
||||
name: string;
|
||||
tag: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
@@ -9,4 +9,10 @@ export interface DashboardDriverSummaryDTO {
|
||||
name: string;
|
||||
country: string;
|
||||
avatarUrl: string;
|
||||
rating?: number;
|
||||
globalRank?: number;
|
||||
totalRaces: number;
|
||||
wins: number;
|
||||
podiums: number;
|
||||
consistency?: number;
|
||||
}
|
||||
|
||||
@@ -7,4 +7,10 @@
|
||||
export interface DashboardFeedItemSummaryDTO {
|
||||
id: string;
|
||||
enum: string;
|
||||
type: string;
|
||||
headline: string;
|
||||
body?: string;
|
||||
timestamp: string;
|
||||
ctaLabel?: string;
|
||||
ctaHref?: string;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DashboardFeedItemSummaryDTO } from './DashboardFeedItemSummaryDTO';
|
||||
|
||||
export interface DashboardFeedSummaryDTO {
|
||||
notificationCount: number;
|
||||
items: DashboardFeedItemSummaryDTO[];
|
||||
}
|
||||
|
||||
25
apps/website/lib/types/generated/DashboardOverviewDTO.ts
Normal file
25
apps/website/lib/types/generated/DashboardOverviewDTO.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DashboardDriverSummaryDTO } from './DashboardDriverSummaryDTO';
|
||||
import type { DashboardRaceSummaryDTO } from './DashboardRaceSummaryDTO';
|
||||
import type { DashboardRecentResultDTO } from './DashboardRecentResultDTO';
|
||||
import type { DashboardLeagueStandingSummaryDTO } from './DashboardLeagueStandingSummaryDTO';
|
||||
import type { DashboardFeedSummaryDTO } from './DashboardFeedSummaryDTO';
|
||||
import type { DashboardFriendSummaryDTO } from './DashboardFriendSummaryDTO';
|
||||
|
||||
export interface DashboardOverviewDTO {
|
||||
currentDriver?: DashboardDriverSummaryDTO;
|
||||
myUpcomingRaces: DashboardRaceSummaryDTO[];
|
||||
otherUpcomingRaces: DashboardRaceSummaryDTO[];
|
||||
upcomingRaces: DashboardRaceSummaryDTO[];
|
||||
activeLeaguesCount: number;
|
||||
nextRace?: DashboardRaceSummaryDTO;
|
||||
recentResults: DashboardRecentResultDTO[];
|
||||
leagueStandingsSummaries: DashboardLeagueStandingSummaryDTO[];
|
||||
feedSummary: DashboardFeedSummaryDTO;
|
||||
friends: DashboardFriendSummaryDTO[];
|
||||
}
|
||||
@@ -11,4 +11,6 @@ export interface DashboardRaceSummaryDTO {
|
||||
track: string;
|
||||
car: string;
|
||||
scheduledAt: string;
|
||||
status: string;
|
||||
isMyLeague: boolean;
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
*/
|
||||
|
||||
export interface DeleteMediaOutputDTO {
|
||||
success: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
|
||||
export interface DriverDTO {
|
||||
id: string;
|
||||
iracingId: string;
|
||||
name: string;
|
||||
country: string;
|
||||
position: string;
|
||||
races: string;
|
||||
impressions: string;
|
||||
team: string;
|
||||
bio?: string;
|
||||
joinedAt: string;
|
||||
}
|
||||
|
||||
@@ -15,4 +15,5 @@ export interface DriverLeaderboardItemDTO {
|
||||
podiums: number;
|
||||
isActive: boolean;
|
||||
rank: number;
|
||||
avatarUrl?: string;
|
||||
}
|
||||
|
||||
@@ -8,4 +8,7 @@ export interface DriverProfileAchievementDTO {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
rarity: string;
|
||||
earnedAt: string;
|
||||
}
|
||||
|
||||
@@ -9,4 +9,11 @@ export interface DriverProfileDriverSummaryDTO {
|
||||
name: string;
|
||||
country: string;
|
||||
avatarUrl: string;
|
||||
iracingId?: string;
|
||||
joinedAt: string;
|
||||
rating?: number;
|
||||
globalRank?: number;
|
||||
consistency?: number;
|
||||
bio?: string;
|
||||
totalDrivers?: number;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DriverProfileSocialHandleDTO } from './DriverProfileSocialHandleDTO';
|
||||
import type { DriverProfileAchievementDTO } from './DriverProfileAchievementDTO';
|
||||
|
||||
export interface DriverProfileExtendedProfileDTO {
|
||||
socialHandles: DriverProfileSocialHandleDTO[];
|
||||
achievements: DriverProfileAchievementDTO[];
|
||||
racingStyle: string;
|
||||
favoriteTrack: string;
|
||||
favoriteCar: string;
|
||||
timezone: string;
|
||||
availableHours: string;
|
||||
lookingForTeam: boolean;
|
||||
openToRequests: boolean;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
export interface DriverProfileSocialHandleDTO {
|
||||
platform: string;
|
||||
handle: string;
|
||||
url: string;
|
||||
}
|
||||
@@ -4,6 +4,9 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DriverProfileSocialFriendSummaryDTO } from './DriverProfileSocialFriendSummaryDTO';
|
||||
|
||||
export interface DriverProfileSocialSummaryDTO {
|
||||
friendsCount: number;
|
||||
friends: DriverProfileSocialFriendSummaryDTO[];
|
||||
}
|
||||
|
||||
@@ -9,4 +9,14 @@ export interface DriverProfileStatsDTO {
|
||||
wins: number;
|
||||
podiums: number;
|
||||
dnfs: number;
|
||||
avgFinish?: number;
|
||||
bestFinish?: number;
|
||||
worstFinish?: number;
|
||||
finishRate?: number;
|
||||
winRate?: number;
|
||||
podiumRate?: number;
|
||||
percentile?: number;
|
||||
rating?: number;
|
||||
consistency?: number;
|
||||
overallRank?: number;
|
||||
}
|
||||
|
||||
@@ -7,4 +7,8 @@
|
||||
export interface DriverProfileTeamMembershipDTO {
|
||||
teamId: string;
|
||||
teamName: string;
|
||||
teamTag?: string;
|
||||
role: string;
|
||||
joinedAt: string;
|
||||
isCurrent: boolean;
|
||||
}
|
||||
|
||||
14
apps/website/lib/types/generated/DriversLeaderboardDTO.ts
Normal file
14
apps/website/lib/types/generated/DriversLeaderboardDTO.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DriverLeaderboardItemDTO } from './DriverLeaderboardItemDTO';
|
||||
|
||||
export interface DriversLeaderboardDTO {
|
||||
drivers: DriverLeaderboardItemDTO[];
|
||||
totalRaces: number;
|
||||
totalWins: number;
|
||||
activeCount: number;
|
||||
}
|
||||
@@ -4,12 +4,13 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { ProtestIncidentDTO } from './ProtestIncidentDTO';
|
||||
|
||||
export interface FileProtestCommandDTO {
|
||||
raceId: string;
|
||||
protestingDriverId: string;
|
||||
accusedDriverId: string;
|
||||
incident: Record<string, unknown>;
|
||||
lap: number;
|
||||
description: string;
|
||||
timeInRace?: number;
|
||||
incident: ProtestIncidentDTO;
|
||||
comment?: string;
|
||||
proofVideoUrl?: string;
|
||||
}
|
||||
|
||||
12
apps/website/lib/types/generated/GetAllTeamsOutputDTO.ts
Normal file
12
apps/website/lib/types/generated/GetAllTeamsOutputDTO.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { TeamListItemDTO } from './TeamListItemDTO';
|
||||
|
||||
export interface GetAllTeamsOutputDTO {
|
||||
teams: TeamListItemDTO[];
|
||||
totalCount: number;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DriverProfileDriverSummaryDTO } from './DriverProfileDriverSummaryDTO';
|
||||
import type { DriverProfileStatsDTO } from './DriverProfileStatsDTO';
|
||||
import type { DriverProfileFinishDistributionDTO } from './DriverProfileFinishDistributionDTO';
|
||||
import type { DriverProfileTeamMembershipDTO } from './DriverProfileTeamMembershipDTO';
|
||||
import type { DriverProfileSocialSummaryDTO } from './DriverProfileSocialSummaryDTO';
|
||||
import type { DriverProfileExtendedProfileDTO } from './DriverProfileExtendedProfileDTO';
|
||||
|
||||
export interface GetDriverProfileOutputDTO {
|
||||
currentDriver?: DriverProfileDriverSummaryDTO;
|
||||
stats?: DriverProfileStatsDTO;
|
||||
finishDistribution?: DriverProfileFinishDistributionDTO;
|
||||
teamMemberships: DriverProfileTeamMembershipDTO[];
|
||||
socialSummary: DriverProfileSocialSummaryDTO;
|
||||
extendedProfile?: DriverProfileExtendedProfileDTO;
|
||||
}
|
||||
15
apps/website/lib/types/generated/GetDriverTeamOutputDTO.ts
Normal file
15
apps/website/lib/types/generated/GetDriverTeamOutputDTO.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { TeamDTO } from './TeamDTO';
|
||||
import type { TeamMembershipDTO } from './TeamMembershipDTO';
|
||||
|
||||
export interface GetDriverTeamOutputDTO {
|
||||
team: TeamDTO;
|
||||
membership: TeamMembershipDTO;
|
||||
isOwner: boolean;
|
||||
canManage: boolean;
|
||||
}
|
||||
@@ -4,7 +4,10 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { SponsorshipPricingItemDTO } from './SponsorshipPricingItemDTO';
|
||||
|
||||
export interface GetEntitySponsorshipPricingResultDTO {
|
||||
entityType: string;
|
||||
entityId: string;
|
||||
pricing: SponsorshipPricingItemDTO[];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueConfigFormModelDTO } from './LeagueConfigFormModelDTO';
|
||||
|
||||
export interface GetLeagueAdminConfigOutputDTO {
|
||||
form?: LeagueConfigFormModelDTO;
|
||||
}
|
||||
11
apps/website/lib/types/generated/GetLeagueRacesOutputDTO.ts
Normal file
11
apps/website/lib/types/generated/GetLeagueRacesOutputDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { RaceDTO } from './RaceDTO';
|
||||
|
||||
export interface GetLeagueRacesOutputDTO {
|
||||
races: RaceDTO[];
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { WalletTransactionDTO } from './WalletTransactionDTO';
|
||||
|
||||
export interface GetLeagueWalletOutputDTO {
|
||||
balance: number;
|
||||
currency: string;
|
||||
@@ -12,4 +14,6 @@ export interface GetLeagueWalletOutputDTO {
|
||||
totalWithdrawals: number;
|
||||
pendingPayouts: number;
|
||||
canWithdraw: boolean;
|
||||
withdrawalBlockReason?: string;
|
||||
transactions: WalletTransactionDTO[];
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface GetMediaOutputDTO {
|
||||
url: string;
|
||||
type: string;
|
||||
category?: string;
|
||||
/** Format: date-time */
|
||||
uploadedAt: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { MembershipFeeDTO } from './MembershipFeeDTO';
|
||||
import type { MemberPaymentDTO } from './MemberPaymentDTO';
|
||||
|
||||
export interface GetMembershipFeesResultDTO {
|
||||
fee?: MembershipFeeDTO;
|
||||
payments: MemberPaymentDTO[];
|
||||
}
|
||||
@@ -4,7 +4,11 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { SponsorshipRequestDTO } from './SponsorshipRequestDTO';
|
||||
|
||||
export interface GetPendingSponsorshipRequestsOutputDTO {
|
||||
entityType: string;
|
||||
entityId: string;
|
||||
requests: SponsorshipRequestDTO[];
|
||||
totalCount: number;
|
||||
}
|
||||
|
||||
11
apps/website/lib/types/generated/GetPrizesResultDTO.ts
Normal file
11
apps/website/lib/types/generated/GetPrizesResultDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { PrizeDTO } from './PrizeDTO';
|
||||
|
||||
export interface GetPrizesResultDTO {
|
||||
prizes: PrizeDTO[];
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { SponsorshipDetailDTO } from './SponsorshipDetailDTO';
|
||||
|
||||
export interface GetSeasonSponsorshipsOutputDTO {
|
||||
sponsorships: SponsorshipDetailDTO[];
|
||||
}
|
||||
11
apps/website/lib/types/generated/GetSponsorOutputDTO.ts
Normal file
11
apps/website/lib/types/generated/GetSponsorOutputDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { SponsorDTO } from './SponsorDTO';
|
||||
|
||||
export interface GetSponsorOutputDTO {
|
||||
sponsor: SponsorDTO;
|
||||
}
|
||||
11
apps/website/lib/types/generated/GetSponsorsOutputDTO.ts
Normal file
11
apps/website/lib/types/generated/GetSponsorsOutputDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { SponsorDTO } from './SponsorDTO';
|
||||
|
||||
export interface GetSponsorsOutputDTO {
|
||||
sponsors: SponsorDTO[];
|
||||
}
|
||||
14
apps/website/lib/types/generated/GetTeamDetailsOutputDTO.ts
Normal file
14
apps/website/lib/types/generated/GetTeamDetailsOutputDTO.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { TeamDTO } from './TeamDTO';
|
||||
import type { TeamMembershipDTO } from './TeamMembershipDTO';
|
||||
|
||||
export interface GetTeamDetailsOutputDTO {
|
||||
team: TeamDTO;
|
||||
membership?: TeamMembershipDTO;
|
||||
canManage: boolean;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { TeamJoinRequestDTO } from './TeamJoinRequestDTO';
|
||||
|
||||
export interface GetTeamJoinRequestsOutputDTO {
|
||||
requests: TeamJoinRequestDTO[];
|
||||
pendingCount: number;
|
||||
totalCount: number;
|
||||
}
|
||||
15
apps/website/lib/types/generated/GetTeamMembersOutputDTO.ts
Normal file
15
apps/website/lib/types/generated/GetTeamMembersOutputDTO.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { TeamMemberDTO } from './TeamMemberDTO';
|
||||
|
||||
export interface GetTeamMembersOutputDTO {
|
||||
members: TeamMemberDTO[];
|
||||
totalCount: number;
|
||||
ownerCount: number;
|
||||
managerCount: number;
|
||||
memberCount: number;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { TeamLeaderboardItemDTO } from './TeamLeaderboardItemDTO';
|
||||
|
||||
export interface GetTeamsLeaderboardOutputDTO {
|
||||
teams: TeamLeaderboardItemDTO[];
|
||||
recruitingCount: number;
|
||||
groupsBySkillLevel: string;
|
||||
topTeams: TeamLeaderboardItemDTO[];
|
||||
}
|
||||
13
apps/website/lib/types/generated/GetWalletResultDTO.ts
Normal file
13
apps/website/lib/types/generated/GetWalletResultDTO.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { WalletDTO } from './WalletDTO';
|
||||
import type { TransactionDTO } from './TransactionDTO';
|
||||
|
||||
export interface GetWalletResultDTO {
|
||||
wallet: WalletDTO;
|
||||
transactions: TransactionDTO[];
|
||||
}
|
||||
@@ -9,4 +9,5 @@ export interface ImportRaceResultsSummaryDTO {
|
||||
raceId: string;
|
||||
driversProcessed: number;
|
||||
resultsRecorded: number;
|
||||
errors?: string[];
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ export interface InvoiceDTO {
|
||||
invoiceNumber: string;
|
||||
date: string;
|
||||
dueDate: string;
|
||||
amount: string;
|
||||
vatAmount: string;
|
||||
totalAmount: string;
|
||||
amount: number;
|
||||
vatAmount: number;
|
||||
totalAmount: number;
|
||||
status: string;
|
||||
description: string;
|
||||
sponsorshipType: string;
|
||||
pdfUrl: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
export interface IracingAuthRedirectResultDTO {
|
||||
redirectUrl: string;
|
||||
state: string;
|
||||
}
|
||||
11
apps/website/lib/types/generated/LeagueAdminConfigDTO.ts
Normal file
11
apps/website/lib/types/generated/LeagueAdminConfigDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueConfigFormModelDTO } from './LeagueConfigFormModelDTO';
|
||||
|
||||
export interface LeagueAdminConfigDTO {
|
||||
form?: LeagueConfigFormModelDTO;
|
||||
}
|
||||
19
apps/website/lib/types/generated/LeagueAdminDTO.ts
Normal file
19
apps/website/lib/types/generated/LeagueAdminDTO.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueJoinRequestDTO } from './LeagueJoinRequestDTO';
|
||||
import type { LeagueOwnerSummaryDTO } from './LeagueOwnerSummaryDTO';
|
||||
import type { LeagueAdminConfigDTO } from './LeagueAdminConfigDTO';
|
||||
import type { LeagueAdminProtestsDTO } from './LeagueAdminProtestsDTO';
|
||||
import type { LeagueSeasonSummaryDTO } from './LeagueSeasonSummaryDTO';
|
||||
|
||||
export interface LeagueAdminDTO {
|
||||
joinRequests: LeagueJoinRequestDTO[];
|
||||
ownerSummary?: LeagueOwnerSummaryDTO;
|
||||
config: LeagueAdminConfigDTO;
|
||||
protests: LeagueAdminProtestsDTO;
|
||||
seasons: LeagueSeasonSummaryDTO[];
|
||||
}
|
||||
15
apps/website/lib/types/generated/LeagueAdminProtestsDTO.ts
Normal file
15
apps/website/lib/types/generated/LeagueAdminProtestsDTO.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { ProtestDTO } from './ProtestDTO';
|
||||
import type { RaceDTO } from './RaceDTO';
|
||||
import type { DriverDTO } from './DriverDTO';
|
||||
|
||||
export interface LeagueAdminProtestsDTO {
|
||||
protests: ProtestDTO[];
|
||||
racesById: RaceDTO;
|
||||
driversById: DriverDTO;
|
||||
}
|
||||
@@ -7,4 +7,5 @@
|
||||
export interface LeagueConfigFormModelBasicsDTO {
|
||||
name: string;
|
||||
description: string;
|
||||
visibility: string;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,20 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueConfigFormModelBasicsDTO } from './LeagueConfigFormModelBasicsDTO';
|
||||
import type { LeagueConfigFormModelStructureDTO } from './LeagueConfigFormModelStructureDTO';
|
||||
import type { LeagueConfigFormModelScoringDTO } from './LeagueConfigFormModelScoringDTO';
|
||||
import type { LeagueConfigFormModelDropPolicyDTO } from './LeagueConfigFormModelDropPolicyDTO';
|
||||
import type { LeagueConfigFormModelTimingsDTO } from './LeagueConfigFormModelTimingsDTO';
|
||||
import type { LeagueConfigFormModelStewardingDTO } from './LeagueConfigFormModelStewardingDTO';
|
||||
|
||||
export interface LeagueConfigFormModelDTO {
|
||||
leagueId: string;
|
||||
basics: LeagueConfigFormModelBasicsDTO;
|
||||
structure: LeagueConfigFormModelStructureDTO;
|
||||
championships: Record<string, unknown>[];
|
||||
scoring: LeagueConfigFormModelScoringDTO;
|
||||
dropPolicy: LeagueConfigFormModelDropPolicyDTO;
|
||||
timings: LeagueConfigFormModelTimingsDTO;
|
||||
stewarding: LeagueConfigFormModelStewardingDTO;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
export interface LeagueConfigFormModelDropPolicyDTO {
|
||||
strategy: string;
|
||||
n?: number;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
export interface LeagueConfigFormModelStewardingDTO {
|
||||
decisionMode: string;
|
||||
requiredVotes?: number;
|
||||
requireDefense: boolean;
|
||||
defenseTimeLimit: number;
|
||||
voteTimeLimit: number;
|
||||
protestDeadlineHours: number;
|
||||
stewardingClosesHours: number;
|
||||
notifyAccusedOnProtest: boolean;
|
||||
notifyOnVoteRequired: boolean;
|
||||
}
|
||||
@@ -8,4 +8,27 @@ export interface LeagueDetailDTO {
|
||||
id: string;
|
||||
name: string;
|
||||
game: string;
|
||||
tier: string;
|
||||
season: string;
|
||||
description: string;
|
||||
drivers: number;
|
||||
races: number;
|
||||
completedRaces: number;
|
||||
totalImpressions: number;
|
||||
avgViewsPerRace: number;
|
||||
engagement: number;
|
||||
rating: number;
|
||||
seasonStatus: string;
|
||||
seasonDates: Record<string, unknown>;
|
||||
start: string;
|
||||
end: string;
|
||||
nextRace?: Record<string, unknown>;
|
||||
date: string;
|
||||
sponsorSlots: Record<string, unknown>;
|
||||
main: Record<string, unknown>;
|
||||
available: number;
|
||||
price: number;
|
||||
benefits: string[];
|
||||
secondary: Record<string, unknown>;
|
||||
total: number;
|
||||
}
|
||||
|
||||
@@ -10,4 +10,8 @@ export interface LeagueJoinRequestDTO {
|
||||
driverId: string;
|
||||
/** Format: date-time */
|
||||
requestedAt: string;
|
||||
message?: string;
|
||||
required: string;
|
||||
type: string;
|
||||
driver?: string;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DriverDTO } from './DriverDTO';
|
||||
|
||||
export interface LeagueMemberDTO {
|
||||
driverId: string;
|
||||
driver: DriverDTO;
|
||||
role: string;
|
||||
/** Format: date-time */
|
||||
joinedAt: string;
|
||||
}
|
||||
|
||||
@@ -8,4 +8,7 @@ export interface LeagueMembershipDTO {
|
||||
id: string;
|
||||
leagueId: string;
|
||||
driverId: string;
|
||||
role: string;
|
||||
status: string;
|
||||
joinedAt: string;
|
||||
}
|
||||
|
||||
11
apps/website/lib/types/generated/LeagueMembershipsDTO.ts
Normal file
11
apps/website/lib/types/generated/LeagueMembershipsDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueMemberDTO } from './LeagueMemberDTO';
|
||||
|
||||
export interface LeagueMembershipsDTO {
|
||||
members: LeagueMemberDTO[];
|
||||
}
|
||||
13
apps/website/lib/types/generated/LeagueOwnerSummaryDTO.ts
Normal file
13
apps/website/lib/types/generated/LeagueOwnerSummaryDTO.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { DriverDTO } from './DriverDTO';
|
||||
|
||||
export interface LeagueOwnerSummaryDTO {
|
||||
driver: DriverDTO;
|
||||
rating?: number;
|
||||
rank?: number;
|
||||
}
|
||||
9
apps/website/lib/types/generated/LeagueRoleDTO.ts
Normal file
9
apps/website/lib/types/generated/LeagueRoleDTO.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
export interface LeagueRoleDTO {
|
||||
value: string;
|
||||
}
|
||||
11
apps/website/lib/types/generated/LeagueScheduleDTO.ts
Normal file
11
apps/website/lib/types/generated/LeagueScheduleDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Auto-generated DTO from OpenAPI spec
|
||||
* This file is generated by scripts/generate-api-types.ts
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { RaceDTO } from './RaceDTO';
|
||||
|
||||
export interface LeagueScheduleDTO {
|
||||
races: RaceDTO[];
|
||||
}
|
||||
@@ -9,5 +9,7 @@ export interface LeagueScoringChampionshipDTO {
|
||||
name: string;
|
||||
type: string;
|
||||
sessionTypes: string[];
|
||||
pointsPreview: string;
|
||||
pointsPreview: Record<string, unknown>[];
|
||||
bonusSummary: string[];
|
||||
dropPolicyDescription: string;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,15 @@
|
||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||
*/
|
||||
|
||||
import type { LeagueScoringChampionshipDTO } from './LeagueScoringChampionshipDTO';
|
||||
|
||||
export interface LeagueScoringConfigDTO {
|
||||
leagueId: string;
|
||||
seasonId: string;
|
||||
gameId: string;
|
||||
gameName: string;
|
||||
scoringPresetId?: string;
|
||||
scoringPresetName?: string;
|
||||
dropPolicySummary: string;
|
||||
championships: LeagueScoringChampionshipDTO[];
|
||||
}
|
||||
|
||||
@@ -8,4 +8,8 @@ export interface LeagueScoringPresetDTO {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
primaryChampionshipType: string;
|
||||
sessionSummary: string;
|
||||
bonusSummary: string;
|
||||
dropPolicySummary: string;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user