harden media

This commit is contained in:
2025-12-31 15:39:28 +01:00
parent 92226800df
commit 8260bf7baf
413 changed files with 8361 additions and 1544 deletions

View File

@@ -41,7 +41,7 @@ export class DriverService {
if (!dto) {
return null;
}
return new DriverViewModel(dto);
return new DriverViewModel({ ...dto, avatarUrl: (dto as any).avatarUrl ?? null });
}
/**
@@ -55,7 +55,7 @@ export class DriverService {
id: dto.currentDriver.id,
name: dto.currentDriver.name,
country: dto.currentDriver.country,
avatarUrl: dto.currentDriver.avatarUrl,
avatarUrl: dto.currentDriver.avatarUrl || '',
iracingId: dto.currentDriver.iracingId ?? null,
joinedAt: dto.currentDriver.joinedAt,
rating: dto.currentDriver.rating ?? null,
@@ -107,7 +107,7 @@ export class DriverService {
id: f.id,
name: f.name,
country: f.country,
avatarUrl: f.avatarUrl,
avatarUrl: f.avatarUrl || '',
})),
},
extendedProfile: dto.extendedProfile

View File

@@ -33,7 +33,7 @@ export class LandingService {
const racesVm = new RacesPageViewModel(racesDto);
const topLeagues = leaguesDto.leagues.slice(0, 4).map(
const topLeagues = (leaguesDto?.leagues || []).slice(0, 4).map(
(league: LeagueWithCapacityDTO) => new LeagueCardViewModel({
id: league.id,
name: league.name,
@@ -41,13 +41,14 @@ export class LandingService {
}),
);
const teams = teamsDto.teams.slice(0, 4).map(
const teams = (teamsDto?.teams || []).slice(0, 4).map(
(team: TeamListItemDTO) =>
new TeamCardViewModel({
id: team.id,
name: team.name,
tag: team.tag,
description: team.description,
logoUrl: team.logoUrl,
}),
);

View File

@@ -114,6 +114,7 @@ export class LeagueService {
id: league.id,
name: league.name,
description: league.description,
logoUrl: league.logoUrl ?? null, // Use API-provided logo URL
ownerId: league.ownerId,
createdAt: league.createdAt,
maxDrivers: league.settings?.maxDrivers ?? 0,
@@ -611,4 +612,4 @@ export class LeagueService {
const result = await this.apiClient.getScoringPresets();
return result.presets;
}
}
}

View File

@@ -2,7 +2,6 @@ import { DeleteMediaViewModel } from '@/lib/view-models/DeleteMediaViewModel';
import { MediaViewModel } from '@/lib/view-models/MediaViewModel';
import { UploadMediaViewModel } from '@/lib/view-models/UploadMediaViewModel';
import type { MediaApiClient } from '../../api/media/MediaApiClient';
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
// Local request shape mirroring the media upload API contract until a generated type is available
type UploadMediaRequest = { file: File; type: string; category?: string };
@@ -42,35 +41,4 @@ export class MediaService {
return new DeleteMediaViewModel(dto);
}
/**
* Get team logo URL
* Returns relative URL for proxying through Next.js rewrites
*/
getTeamLogo(teamId: string): string {
return `/api/media/teams/${teamId}/logo`;
}
/**
* Get driver avatar URL
* Returns relative URL for proxying through Next.js rewrites
*/
getDriverAvatar(driverId: string): string {
return `/api/media/avatar/${driverId}`;
}
/**
* Get league cover URL
* Returns relative URL for proxying through Next.js rewrites
*/
getLeagueCover(leagueId: string): string {
return `/api/media/leagues/${leagueId}/cover`;
}
/**
* Get league logo URL
* Returns relative URL for proxying through Next.js rewrites
*/
getLeagueLogo(leagueId: string): string {
return `/api/media/leagues/${leagueId}/logo`;
}
}

View File

@@ -34,7 +34,7 @@ export class PaymentService {
async getPayments(leagueId?: string, payerId?: string): Promise<PaymentViewModel[]> {
const query = (leagueId || payerId) ? { ...(leagueId && { leagueId }), ...(payerId && { payerId }) } : undefined;
const dto = await this.apiClient.getPayments(query);
return dto.payments.map((payment: PaymentDTO) => new PaymentViewModel(payment));
return (dto?.payments || []).map((payment: PaymentDTO) => new PaymentViewModel(payment));
}
/**
@@ -43,7 +43,7 @@ export class PaymentService {
async getPayment(paymentId: string): Promise<PaymentViewModel> {
// Note: Assuming the API returns a single payment from the list
const dto = await this.apiClient.getPayments();
const payment = dto.payments.find((p: PaymentDTO) => p.id === paymentId);
const payment = (dto?.payments || []).find((p: PaymentDTO) => p.id === paymentId);
if (!payment) {
throw new Error(`Payment with ID ${paymentId} not found`);
}
@@ -72,7 +72,7 @@ export class PaymentService {
async getPrizes(leagueId?: string, seasonId?: string): Promise<PrizeViewModel[]> {
const query = (leagueId || seasonId) ? { ...(leagueId && { leagueId }), ...(seasonId && { seasonId }) } : undefined;
const dto = await this.apiClient.getPrizes(query);
return dto.prizes.map((prize: PrizeDTO) => new PrizeViewModel(prize));
return (dto?.prizes || []).map((prize: PrizeDTO) => new PrizeViewModel(prize));
}
/**

View File

@@ -21,7 +21,7 @@ export class SponsorService {
*/
async getAllSponsors(): Promise<SponsorViewModel[]> {
const dto = await this.apiClient.getAll();
return dto.sponsors.map((sponsor: SponsorDTO) => new SponsorViewModel(sponsor));
return (dto?.sponsors || []).map((sponsor: SponsorDTO) => new SponsorViewModel(sponsor));
}
/**

View File

@@ -23,8 +23,8 @@ export class TeamJoinService {
* Get team join requests with view model transformation
*/
async getJoinRequests(teamId: string, currentUserId: string, isOwner: boolean): Promise<TeamJoinRequestViewModel[]> {
const dto = await this.apiClient.getJoinRequests(teamId) as TeamJoinRequestsDto;
return dto.requests.map((r: TeamJoinRequestDTO) => new TeamJoinRequestViewModel(r, currentUserId, isOwner));
const dto = await this.apiClient.getJoinRequests(teamId) as TeamJoinRequestsDto | null;
return (dto?.requests || []).map((r: TeamJoinRequestDTO) => new TeamJoinRequestViewModel(r, currentUserId, isOwner));
}
/**

View File

@@ -32,8 +32,8 @@ export class TeamService {
* Get all teams with view model transformation
*/
async getAllTeams(): Promise<TeamSummaryViewModel[]> {
const dto: GetAllTeamsOutputDTO = await this.apiClient.getAll();
return dto.teams.map((team: TeamListItemDTO) => new TeamSummaryViewModel(team));
const dto: GetAllTeamsOutputDTO | null = await this.apiClient.getAll();
return (dto?.teams || []).map((team: TeamListItemDTO) => new TeamSummaryViewModel(team));
}
/**