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,103 +1,30 @@
import { ProtestDTO } from '@/lib/types/generated/ProtestDTO';
import { RaceProtestDTO } from '@/lib/types/generated/RaceProtestDTO';
import { DateDisplay } from '../display-objects/DateDisplay';
import { StatusDisplay } from '../display-objects/StatusDisplay';
/**
* Protest view model
* Represents a race protest
*/
import { DateDisplay } from '@/lib/display-objects/DateDisplay';
import { StatusDisplay } from '@/lib/display-objects/StatusDisplay';
import { ViewModel } from "../contracts/view-models/ViewModel";
import type { ProtestViewData } from "@/lib/view-data/ProtestViewData";
export class ProtestViewModel extends ViewModel {
id: string;
raceId: string;
protestingDriverId: string;
accusedDriverId: string;
description: string;
submittedAt: string;
filedAt?: string;
status: string;
reviewedAt?: string;
decisionNotes?: string;
incident?: { lap?: number; description?: string } | null;
proofVideoUrl?: string | null;
comment?: string | null;
private readonly data: ProtestViewData;
constructor(dto: ProtestDTO | RaceProtestDTO) {
this.id = dto.id;
// Type narrowing for raceId
if ('raceId' in dto) {
this.raceId = dto.raceId;
} else {
this.raceId = '';
}
this.protestingDriverId = dto.protestingDriverId;
this.accusedDriverId = dto.accusedDriverId;
// Type narrowing for description
if ('description' in dto && typeof dto.description === 'string') {
this.description = dto.description;
} else {
this.description = '';
}
// Type narrowing for submittedAt and filedAt
if ('submittedAt' in dto && typeof dto.submittedAt === 'string') {
this.submittedAt = dto.submittedAt;
} else if ('filedAt' in dto && typeof dto.filedAt === 'string') {
this.submittedAt = dto.filedAt;
} else {
this.submittedAt = '';
}
if ('filedAt' in dto && typeof dto.filedAt === 'string') {
this.filedAt = dto.filedAt;
} else if ('submittedAt' in dto && typeof dto.submittedAt === 'string') {
this.filedAt = dto.submittedAt;
}
// Handle different DTO structures
if ('status' in dto && typeof dto.status === 'string') {
this.status = dto.status;
} else {
this.status = 'pending';
}
// Handle incident data
if ('incident' in dto && dto.incident) {
const incident = dto.incident as { lap?: number; description?: string };
this.incident = {
lap: typeof incident.lap === 'number' ? incident.lap : undefined,
description: typeof incident.description === 'string' ? incident.description : undefined
};
} else if (('lap' in dto && typeof (dto as { lap?: number }).lap === 'number') ||
('description' in dto && typeof (dto as { description?: string }).description === 'string')) {
this.incident = {
lap: 'lap' in dto ? (dto as { lap?: number }).lap : undefined,
description: 'description' in dto ? (dto as { description?: string }).description : undefined
};
} else {
this.incident = null;
}
if ('proofVideoUrl' in dto) {
this.proofVideoUrl = (dto as { proofVideoUrl?: string }).proofVideoUrl || null;
}
if ('comment' in dto) {
this.comment = (dto as { comment?: string }).comment || null;
}
// Status and decision metadata are not part of the protest DTO in this build; they default to a pending, unreviewed protest
if (!('status' in dto)) {
this.status = 'pending';
}
this.reviewedAt = undefined;
this.decisionNotes = undefined;
constructor(data: ProtestViewData) {
super();
this.data = data;
}
get id(): string { return this.data.id; }
get raceId(): string { return this.data.raceId; }
get protestingDriverId(): string { return this.data.protestingDriverId; }
get accusedDriverId(): string { return this.data.accusedDriverId; }
get description(): string { return this.data.description; }
get submittedAt(): string { return this.data.submittedAt; }
get filedAt(): string | undefined { return this.data.filedAt; }
get status(): string { return this.data.status; }
get reviewedAt(): string | undefined { return this.data.reviewedAt; }
get decisionNotes(): string | undefined { return this.data.decisionNotes; }
get incident(): { lap?: number; description?: string } | null | undefined { return this.data.incident; }
get proofVideoUrl(): string | null | undefined { return this.data.proofVideoUrl; }
get comment(): string | null | undefined { return this.data.comment; }
/** UI-specific: Formatted submitted date */
get formattedSubmittedAt(): string {
return DateDisplay.formatShort(this.submittedAt);