Files
gridpilot.gg/apps/website/lib/view-models/RaceListItemViewModel.ts
2025-12-17 18:01:47 +01:00

55 lines
1.5 KiB
TypeScript

import { RaceListItemDto } from '../dtos';
export class RaceListItemViewModel implements RaceListItemDto {
id: string;
name: string;
leagueId: string;
leagueName: string;
scheduledTime: string;
status: string;
trackName?: string;
constructor(dto: RaceListItemDto) {
Object.assign(this, dto);
}
/** UI-specific: Formatted scheduled time */
get formattedScheduledTime(): string {
return new Date(this.scheduledTime).toLocaleString();
}
/** UI-specific: Badge variant for status */
get statusBadgeVariant(): string {
switch (this.status) {
case 'upcoming': return 'info';
case 'live': return 'success';
case 'finished': return 'secondary';
default: return 'default';
}
}
/** UI-specific: Whether race is upcoming */
get isUpcoming(): boolean {
return this.status === 'upcoming';
}
/** UI-specific: Whether race is live */
get isLive(): boolean {
return this.status === 'live';
}
/** UI-specific: Time until start in minutes */
get timeUntilStart(): number {
const now = new Date();
const scheduled = new Date(this.scheduledTime);
return Math.max(0, Math.floor((scheduled.getTime() - now.getTime()) / (1000 * 60)));
}
/** UI-specific: Display for time until start */
get timeUntilStartDisplay(): string {
const minutes = this.timeUntilStart;
if (minutes < 60) return `${minutes}m`;
const hours = Math.floor(minutes / 60);
return `${hours}h ${minutes % 60}m`;
}
}