Files
gridpilot.gg/apps/website/lib/view-models/AvailableLeaguesViewModel.ts
2026-01-16 01:00:03 +01:00

78 lines
2.4 KiB
TypeScript

/**
* Available Leagues View Model
*
* View model for leagues available for sponsorship.
*/
export class AvailableLeaguesViewModel {
leagues: AvailableLeagueViewModel[];
constructor(leagues: unknown[]) {
this.leagues = leagues.map(league => new AvailableLeagueViewModel(league));
}
}
export class AvailableLeagueViewModel {
id: string;
name: string;
game: string;
drivers: number;
avgViewsPerRace: number;
mainSponsorSlot: { available: boolean; price: number };
secondarySlots: { available: number; total: number; price: number };
rating: number;
tier: 'premium' | 'standard' | 'starter';
nextRace?: string;
seasonStatus: 'active' | 'upcoming' | 'completed';
description: string;
constructor(data: unknown) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const d = data as any;
this.id = d.id;
this.name = d.name;
this.game = d.game;
this.drivers = d.drivers;
this.avgViewsPerRace = d.avgViewsPerRace;
this.mainSponsorSlot = d.mainSponsorSlot;
this.secondarySlots = d.secondarySlots;
this.rating = d.rating;
this.tier = d.tier;
this.nextRace = d.nextRace;
this.seasonStatus = d.seasonStatus;
this.description = d.description;
}
get formattedAvgViews(): string {
return `${(this.avgViewsPerRace / 1000).toFixed(1)}k`;
}
get cpm(): number {
return Math.round((this.mainSponsorSlot.price / this.avgViewsPerRace) * 1000);
}
get formattedCpm(): string {
return `$${this.cpm}`;
}
get hasAvailableSlots(): boolean {
return this.mainSponsorSlot.available || this.secondarySlots.available > 0;
}
get tierConfig() {
const configs = {
premium: { color: 'text-yellow-400', bgColor: 'bg-yellow-500/10', border: 'border-yellow-500/30', icon: '⭐' },
standard: { color: 'text-primary-blue', bgColor: 'bg-primary-blue/10', border: 'border-primary-blue/30', icon: '🏆' },
starter: { color: 'text-gray-400', bgColor: 'bg-gray-500/10', border: 'border-gray-500/30', icon: '🚀' },
};
return configs[this.tier];
}
get statusConfig() {
const configs = {
active: { color: 'text-performance-green', bg: 'bg-performance-green/10', label: 'Active Season' },
upcoming: { color: 'text-warning-amber', bg: 'bg-warning-amber/10', label: 'Starting Soon' },
completed: { color: 'text-gray-400', bg: 'bg-gray-400/10', label: 'Season Ended' },
};
return configs[this.seasonStatus];
}
}