view data fixes

This commit is contained in:
2026-01-23 15:30:23 +01:00
parent e22033be38
commit f8099f04bc
213 changed files with 3466 additions and 3003 deletions

View File

@@ -1,65 +1,40 @@
// DTO matching the backend RacesPageDataRaceDTO
export interface RaceListItemDTO {
id: string;
track: string;
car: string;
scheduledAt: string;
status: string;
leagueId: string;
leagueName: string;
strengthOfField?: number | null;
isUpcoming: boolean;
isLive: boolean;
isPast: boolean;
}
import { ViewModel } from "../contracts/view-models/ViewModel";
import { RaceStatusDisplay } from "../display-objects/RaceStatusDisplay";
import { DateDisplay } from "../display-objects/DateDisplay";
import type { RaceListItemViewData } from "../view-data/RaceListItemViewData";
export class RaceListItemViewModel extends ViewModel {
id: string;
track: string;
car: string;
scheduledAt: string;
status: string;
leagueId: string;
leagueName: string;
strengthOfField: number | null;
isUpcoming: boolean;
isLive: boolean;
isPast: boolean;
private readonly data: RaceListItemViewData;
constructor(dto: RaceListItemDTO) {
this.id = dto.id;
this.track = dto.track;
this.car = dto.car;
this.scheduledAt = dto.scheduledAt;
this.status = dto.status;
this.leagueId = dto.leagueId;
this.leagueName = dto.leagueName;
this.strengthOfField = dto.strengthOfField ?? null;
this.isUpcoming = dto.isUpcoming;
this.isLive = dto.isLive;
this.isPast = dto.isPast;
constructor(data: RaceListItemViewData) {
super();
this.data = data;
}
get id(): string { return this.data.id; }
get track(): string { return this.data.track; }
get car(): string { return this.data.car; }
get scheduledAt(): string { return this.data.scheduledAt; }
get status(): string { return this.data.status; }
get leagueId(): string { return this.data.leagueId; }
get leagueName(): string { return this.data.leagueName; }
get strengthOfField(): number | null { return this.data.strengthOfField; }
get isUpcoming(): boolean { return this.data.isUpcoming; }
get isLive(): boolean { return this.data.isLive; }
get isPast(): boolean { return this.data.isPast; }
get title(): string {
return `${this.track} - ${this.car}`;
}
/** UI-specific: Formatted scheduled time */
get formattedScheduledTime(): string {
return new Date(this.scheduledAt).toLocaleString();
return DateDisplay.formatDateTime(this.scheduledAt);
}
/** UI-specific: Badge variant for status */
get statusBadgeVariant(): string {
switch (this.status) {
case 'scheduled': return 'info';
case 'running': return 'success';
case 'completed': return 'secondary';
case 'cancelled': return 'danger';
default: return 'default';
}
return RaceStatusDisplay.getVariant(this.status);
}
/** UI-specific: Time until start in minutes */