refactor page to use services
This commit is contained in:
71
apps/website/lib/api/dashboard/DashboardApiClient.ts
Normal file
71
apps/website/lib/api/dashboard/DashboardApiClient.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
|
||||
// DTOs
|
||||
export type DriverDto = {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
country: string;
|
||||
totalRaces: number;
|
||||
wins: number;
|
||||
podiums: number;
|
||||
rating: number;
|
||||
globalRank: number;
|
||||
consistency: number;
|
||||
};
|
||||
|
||||
export type RaceDto = {
|
||||
id: string;
|
||||
track: string;
|
||||
car: string;
|
||||
scheduledAt: string; // ISO date string
|
||||
isMyLeague: boolean;
|
||||
leagueName?: string;
|
||||
};
|
||||
|
||||
export type LeagueStandingDto = {
|
||||
leagueId: string;
|
||||
leagueName: string;
|
||||
position: number;
|
||||
points: number;
|
||||
totalDrivers: number;
|
||||
};
|
||||
|
||||
export type FeedItemDto = {
|
||||
id: string;
|
||||
type: string;
|
||||
headline: string;
|
||||
body: string | null;
|
||||
timestamp: string; // ISO date string
|
||||
ctaHref?: string;
|
||||
ctaLabel?: string;
|
||||
};
|
||||
|
||||
export type FriendDto = {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
country: string;
|
||||
};
|
||||
|
||||
export type DashboardOverviewDto = {
|
||||
currentDriver: DriverDto;
|
||||
nextRace: RaceDto | null;
|
||||
upcomingRaces: RaceDto[];
|
||||
leagueStandings: LeagueStandingDto[];
|
||||
feedItems: FeedItemDto[];
|
||||
friends: FriendDto[];
|
||||
activeLeaguesCount: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dashboard API Client
|
||||
*
|
||||
* Handles dashboard overview data aggregation.
|
||||
*/
|
||||
export class DashboardApiClient extends BaseApiClient {
|
||||
/** Get dashboard overview data */
|
||||
getDashboardOverview(): Promise<DashboardOverviewDto> {
|
||||
return this.get<DashboardOverviewDto>('/dashboard/overview');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
// Import generated types
|
||||
import type { CompleteOnboardingInputDTO, CompleteOnboardingOutputDTO, DriverRegistrationStatusDTO, DriverLeaderboardItemDTO } from '../../types/generated';
|
||||
import type { CompleteOnboardingInputDTO, CompleteOnboardingOutputDTO, DriverRegistrationStatusDTO, DriverLeaderboardItemDTO, DriverProfileDTO } from '../../types/generated';
|
||||
|
||||
// TODO: Create proper DriverDTO in generated types
|
||||
type DriverDTO = {
|
||||
@@ -40,4 +40,14 @@ export class DriversApiClient extends BaseApiClient {
|
||||
getRegistrationStatus(driverId: string, raceId: string): Promise<DriverRegistrationStatusDTO> {
|
||||
return this.get<DriverRegistrationStatusDTO>(`/drivers/${driverId}/races/${raceId}/registration-status`);
|
||||
}
|
||||
|
||||
/** Get driver by ID */
|
||||
getDriver(driverId: string): Promise<DriverDTO | null> {
|
||||
return this.get<DriverDTO | null>(`/drivers/${driverId}`);
|
||||
}
|
||||
|
||||
/** Get driver profile with full details */
|
||||
getDriverProfile(driverId: string): Promise<DriverProfileDTO> {
|
||||
return this.get<DriverProfileDTO>(`/drivers/${driverId}/profile`);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { MediaApiClient } from './media/MediaApiClient';
|
||||
import { AnalyticsApiClient } from './analytics/AnalyticsApiClient';
|
||||
import { AuthApiClient } from './auth/AuthApiClient';
|
||||
import { PaymentsApiClient } from './payments/PaymentsApiClient';
|
||||
import { DashboardApiClient } from './dashboard/DashboardApiClient';
|
||||
|
||||
/**
|
||||
* Main API Client
|
||||
@@ -23,6 +24,7 @@ export class ApiClient {
|
||||
public readonly analytics: AnalyticsApiClient;
|
||||
public readonly auth: AuthApiClient;
|
||||
public readonly payments: PaymentsApiClient;
|
||||
public readonly dashboard: DashboardApiClient;
|
||||
|
||||
constructor(baseUrl: string) {
|
||||
this.leagues = new LeaguesApiClient(baseUrl);
|
||||
@@ -34,6 +36,7 @@ export class ApiClient {
|
||||
this.analytics = new AnalyticsApiClient(baseUrl);
|
||||
this.auth = new AuthApiClient(baseUrl);
|
||||
this.payments = new PaymentsApiClient(baseUrl);
|
||||
this.dashboard = new DashboardApiClient(baseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,4 +49,32 @@ export class LeaguesApiClient extends BaseApiClient {
|
||||
removeMember(leagueId: string, performerDriverId: string, targetDriverId: string): Promise<{ success: boolean }> {
|
||||
return this.patch<{ success: boolean }>(`/leagues/${leagueId}/members/${targetDriverId}/remove`, { performerDriverId });
|
||||
}
|
||||
|
||||
/** 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`);
|
||||
}
|
||||
|
||||
/** Get season sponsorships */
|
||||
getSeasonSponsorships(seasonId: string): Promise<{ sponsorships: Array<{ sponsorId: string; tier: string; status: string }> }> {
|
||||
return this.get<{ sponsorships: Array<{ sponsorId: string; tier: string; status: string }> }>(`/seasons/${seasonId}/sponsorships`);
|
||||
}
|
||||
|
||||
/** Get league config */
|
||||
getLeagueConfig(leagueId: string): Promise<{ config: any }> {
|
||||
return this.get<{ config: any }>(`/leagues/${leagueId}/config`);
|
||||
}
|
||||
|
||||
/** Get league scoring presets */
|
||||
getScoringPresets(): Promise<{ presets: any[] }> {
|
||||
return this.get<{ presets: any[] }>(`/leagues/scoring-presets`);
|
||||
}
|
||||
|
||||
/** Transfer league ownership */
|
||||
transferOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<{ success: boolean }> {
|
||||
return this.post<{ success: boolean }>(`/leagues/${leagueId}/transfer-ownership`, {
|
||||
currentOwnerId,
|
||||
newOwnerId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import type {
|
||||
RequestAvatarGenerationInputDto,
|
||||
RequestAvatarGenerationOutputDto,
|
||||
UploadMediaInputDto,
|
||||
UploadMediaOutputDto,
|
||||
GetMediaOutputDto,
|
||||
DeleteMediaOutputDto,
|
||||
GetAvatarOutputDto,
|
||||
UpdateAvatarInputDto,
|
||||
UpdateAvatarOutputDto,
|
||||
DeleteMediaOutputDto,
|
||||
GetMediaOutputDto,
|
||||
RequestAvatarGenerationInputDto,
|
||||
RequestAvatarGenerationOutputDto,
|
||||
UpdateAvatarInputDto,
|
||||
UpdateAvatarOutputDto,
|
||||
UploadMediaInputDto,
|
||||
UploadMediaOutputDto,
|
||||
} from '../../dtos';
|
||||
import type { GetAvatarOutputDto } from '../../types/GetAvatarOutputDto';
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
|
||||
/**
|
||||
* Media API Client
|
||||
|
||||
33
apps/website/lib/api/protests/ProtestsApiClient.ts
Normal file
33
apps/website/lib/api/protests/ProtestsApiClient.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import type {
|
||||
LeagueAdminProtestsDTO,
|
||||
ApplyPenaltyCommandDTO,
|
||||
RequestProtestDefenseCommandDTO,
|
||||
} from '../../types';
|
||||
|
||||
/**
|
||||
* Protests API Client
|
||||
*
|
||||
* Handles all protest-related API operations.
|
||||
*/
|
||||
export class ProtestsApiClient extends BaseApiClient {
|
||||
/** Get protests for a league */
|
||||
getLeagueProtests(leagueId: string): Promise<LeagueAdminProtestsDTO> {
|
||||
return this.get<LeagueAdminProtestsDTO>(`/leagues/${leagueId}/protests`);
|
||||
}
|
||||
|
||||
/** Get a specific protest for a league */
|
||||
getLeagueProtest(leagueId: string, protestId: string): Promise<LeagueAdminProtestsDTO> {
|
||||
return this.get<LeagueAdminProtestsDTO>(`/leagues/${leagueId}/protests/${protestId}`);
|
||||
}
|
||||
|
||||
/** Apply a penalty */
|
||||
applyPenalty(input: ApplyPenaltyCommandDTO): Promise<void> {
|
||||
return this.post<void>('/races/penalties/apply', input);
|
||||
}
|
||||
|
||||
/** Request protest defense */
|
||||
requestDefense(input: RequestProtestDefenseCommandDTO): Promise<void> {
|
||||
return this.post<void>('/races/protests/defense/request', input);
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,9 @@ export class SponsorsApiClient extends BaseApiClient {
|
||||
getSponsorships(sponsorId: string): Promise<SponsorSponsorshipsDTO | null> {
|
||||
return this.get<SponsorSponsorshipsDTO | null>(`/sponsors/${sponsorId}/sponsorships`);
|
||||
}
|
||||
|
||||
/** Get sponsor by ID */
|
||||
getSponsor(sponsorId: string): Promise<SponsorDTO | null> {
|
||||
return this.get<SponsorDTO | null>(`/sponsors/${sponsorId}`);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
import { LeagueMemberDTO } from '@/lib/types/generated/LeagueMemberDTO';
|
||||
import type {
|
||||
AllTeamsDto,
|
||||
TeamDetailsDto,
|
||||
TeamMembersDto,
|
||||
TeamJoinRequestsDto,
|
||||
CreateTeamInputDto,
|
||||
CreateTeamOutputDto,
|
||||
DriverTeamDto,
|
||||
TeamDetailsDto,
|
||||
TeamJoinRequestsDto,
|
||||
TeamMembersDto,
|
||||
UpdateTeamInputDto,
|
||||
UpdateTeamOutputDto,
|
||||
DriverTeamDto,
|
||||
} from '../../dtos';
|
||||
import { BaseApiClient } from '../base/BaseApiClient';
|
||||
|
||||
/**
|
||||
* Teams API Client
|
||||
@@ -51,4 +52,9 @@ export class TeamsApiClient extends BaseApiClient {
|
||||
getDriverTeam(driverId: string): Promise<DriverTeamDto | null> {
|
||||
return this.get<DriverTeamDto | null>(`/teams/driver/${driverId}`);
|
||||
}
|
||||
|
||||
/** Get membership for a driver in a team */
|
||||
getMembership(teamId: string, driverId: string): Promise<LeagueMemberDTO | null> {
|
||||
return this.get<LeagueMemberDTO | null>(`/teams/${teamId}/members/${driverId}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user