move static data

This commit is contained in:
2025-12-26 00:20:53 +01:00
parent c977defd6a
commit b6cbb81388
63 changed files with 1482 additions and 418 deletions

View File

@@ -14,7 +14,7 @@ export class DriverLeaderboardItemViewModel {
avatarUrl: string;
position: number;
private previousRating?: number;
private previousRating: number | undefined;
constructor(dto: DriverLeaderboardItemDTO, position: number, previousRating?: number) {
this.id = dto.id;

View File

@@ -1,5 +1,13 @@
import { LeagueScoringPresetDTO } from '@/lib/types/generated/LeagueScoringPresetDTO';
export type LeagueScoringPresetTimingDefaultsViewModel = {
practiceMinutes: number;
qualifyingMinutes: number;
sprintRaceMinutes: number;
mainRaceMinutes: number;
sessionCount: number;
};
/**
* LeagueScoringPresetViewModel
*
@@ -10,11 +18,13 @@ export class LeagueScoringPresetViewModel {
readonly name: string;
readonly sessionSummary: string;
readonly bonusSummary?: string;
readonly defaultTimings: LeagueScoringPresetTimingDefaultsViewModel;
constructor(dto: LeagueScoringPresetDTO) {
this.id = dto.id;
this.name = dto.name;
this.sessionSummary = dto.sessionSummary;
this.bonusSummary = dto.bonusSummary;
this.defaultTimings = dto.defaultTimings;
}
}

View File

@@ -32,4 +32,12 @@ export class RequestAvatarGenerationViewModel {
get firstAvatarUrl(): string | undefined {
return this.avatarUrls?.[0];
}
get avatarUrl(): string | undefined {
return this.firstAvatarUrl;
}
get error(): string | undefined {
return this.errorMessage;
}
}

View File

@@ -18,13 +18,13 @@ export class SponsorshipRequestViewModel {
this.id = dto.id;
this.sponsorId = dto.sponsorId;
this.sponsorName = dto.sponsorName;
this.sponsorLogo = dto.sponsorLogo;
if (dto.sponsorLogo !== undefined) this.sponsorLogo = dto.sponsorLogo;
// Backend currently returns tier as string; normalize to our supported tiers.
this.tier = dto.tier === 'main' ? 'main' : 'secondary';
this.offeredAmount = dto.offeredAmount;
this.currency = dto.currency;
this.formattedAmount = dto.formattedAmount;
this.message = dto.message;
if (dto.message !== undefined) this.message = dto.message;
this.createdAt = new Date(dto.createdAt);
this.platformFee = dto.platformFee;
this.netAmount = dto.netAmount;

View File

@@ -7,10 +7,10 @@ export class TeamDetailsViewModel {
description?: string;
ownerId!: string;
leagues!: string[];
createdAt?: string;
specialization?: string;
region?: string;
languages?: string[];
createdAt: string | undefined;
specialization: string | undefined;
region: string | undefined;
languages: string[] | undefined;
membership: { role: string; joinedAt: string; isActive: boolean } | null;
private _canManage: boolean;
private currentUserId: string;

View File

@@ -1,18 +1,21 @@
import { describe, it, expect } from 'vitest';
import { TeamJoinRequestViewModel, type TeamJoinRequestDTO } from './TeamJoinRequestViewModel';
import { TeamJoinRequestViewModel } from './TeamJoinRequestViewModel';
import type { TeamJoinRequestDTO } from '@/lib/types/generated/TeamJoinRequestDTO';
const createTeamJoinRequestDto = (overrides: Partial<TeamJoinRequestDTO> = {}): TeamJoinRequestDTO => ({
id: 'request-1',
requestId: 'request-1',
teamId: 'team-1',
driverId: 'driver-1',
driverName: 'Driver One',
status: 'pending',
requestedAt: '2024-01-01T12:00:00Z',
message: 'Please let me join',
avatarUrl: 'https://example.com/avatar.jpg',
...overrides,
});
describe('TeamJoinRequestViewModel', () => {
it('maps fields from DTO', () => {
const dto = createTeamJoinRequestDto({ id: 'req-123', driverId: 'driver-123' });
const dto = createTeamJoinRequestDto({ requestId: 'req-123', driverId: 'driver-123' });
const vm = new TeamJoinRequestViewModel(dto, 'current-user', true);
@@ -20,7 +23,6 @@ describe('TeamJoinRequestViewModel', () => {
expect(vm.teamId).toBe('team-1');
expect(vm.driverId).toBe('driver-123');
expect(vm.requestedAt).toBe('2024-01-01T12:00:00Z');
expect(vm.message).toBe('Please let me join');
});
it('allows approval only for owners', () => {
@@ -34,7 +36,7 @@ describe('TeamJoinRequestViewModel', () => {
});
it('exposes a pending status with yellow color', () => {
const dto = createTeamJoinRequestDto();
const dto = createTeamJoinRequestDto({ status: 'pending' });
const vm = new TeamJoinRequestViewModel(dto, 'owner-user', true);
expect(vm.status).toBe('Pending');

View File

@@ -24,6 +24,17 @@ export class TeamJoinRequestViewModel {
this.isOwner = isOwner;
}
get id(): string {
return this.requestId;
}
get status(): string {
if (this.requestStatus === 'pending') return 'Pending';
if (this.requestStatus === 'approved') return 'Approved';
if (this.requestStatus === 'rejected') return 'Rejected';
return this.requestStatus;
}
/** UI-specific: Whether current user can approve */
get canApprove(): boolean {
return this.isOwner;

View File

@@ -10,8 +10,8 @@ export class TeamSummaryViewModel {
totalRaces: number = 0;
performanceLevel: string = '';
isRecruiting: boolean = false;
specialization?: string;
region?: string;
specialization: string | undefined;
region: string | undefined;
languages: string[] = [];
leagues: string[] = [];