57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
import { ViewModel } from "../contracts/view-models/ViewModel";
|
|
import { FinishFormatter } from "../formatters/FinishFormatter";
|
|
import type { StandingEntryViewData } from "../view-data/StandingEntryViewData";
|
|
|
|
export class StandingEntryViewModel extends ViewModel {
|
|
private readonly data: StandingEntryViewData;
|
|
|
|
constructor(data: StandingEntryViewData) {
|
|
super();
|
|
this.data = data;
|
|
}
|
|
|
|
get driverId(): string { return this.data.driverId; }
|
|
get position(): number { return this.data.position; }
|
|
get points(): number { return this.data.points; }
|
|
get wins(): number { return this.data.wins; }
|
|
get podiums(): number { return this.data.podiums; }
|
|
get races(): number { return this.data.races; }
|
|
get driver(): any { return this.data.driver; }
|
|
|
|
/** UI-specific: Badge for position display */
|
|
get positionBadge(): string {
|
|
return FinishFormatter.format(this.position);
|
|
}
|
|
|
|
/** UI-specific: Points difference to leader */
|
|
get pointsGapToLeader(): number {
|
|
return this.points - this.data.leaderPoints;
|
|
}
|
|
|
|
/** UI-specific: Points difference to next position */
|
|
get pointsGapToNext(): number {
|
|
return this.points - this.data.nextPoints;
|
|
}
|
|
|
|
/** UI-specific: Whether this entry is the current user */
|
|
get isCurrentUser(): boolean {
|
|
return this.driverId === this.data.currentUserId;
|
|
}
|
|
|
|
/** UI-specific: Trend compared to previous */
|
|
get trend(): 'up' | 'down' | 'same' {
|
|
if (!this.data.previousPosition) return 'same';
|
|
if (this.position < this.data.previousPosition) return 'up';
|
|
if (this.position > this.data.previousPosition) return 'down';
|
|
return 'same';
|
|
}
|
|
|
|
/** UI-specific: Arrow for trend */
|
|
get trendArrow(): string {
|
|
switch (this.trend) {
|
|
case 'up': return '↑';
|
|
case 'down': return '↓';
|
|
default: return '-';
|
|
}
|
|
}
|
|
} |