Files
gridpilot.gg/apps/website/components/leagues/LeagueCardWrapper.tsx
2026-01-21 01:35:36 +01:00

181 lines
4.8 KiB
TypeScript

import React from 'react';
import {
Trophy,
Users,
Flag,
Award,
Sparkles,
Gamepad2,
Layers,
} from 'lucide-react';
import type { LeagueSummaryViewModel } from '@/lib/view-models/LeagueSummaryViewModel';
import { getMediaUrl } from '@/lib/utilities/media';
import { Badge } from '@/ui/Badge';
import { LeagueCard as UiLeagueCard } from '@/ui/LeagueCard';
interface LeagueCardProps {
league: LeagueSummaryViewModel;
onClick?: () => void;
}
function getChampionshipIcon(type?: string) {
switch (type) {
case 'driver':
return Trophy;
case 'team':
return Users;
case 'nations':
return Flag;
case 'trophy':
return Award;
default:
return Trophy;
}
}
function getChampionshipLabel(type?: string) {
switch (type) {
case 'driver':
return 'Driver';
case 'team':
return 'Team';
case 'nations':
return 'Nations';
case 'trophy':
return 'Trophy';
default:
return 'Championship';
}
}
function getCategoryLabel(category?: string): string {
if (!category) return '';
switch (category) {
case 'driver':
return 'Driver';
case 'team':
return 'Team';
case 'nations':
return 'Nations';
case 'trophy':
return 'Trophy';
case 'endurance':
return 'Endurance';
case 'sprint':
return 'Sprint';
default:
return category.charAt(0).toUpperCase() + category.slice(1);
}
}
function getCategoryVariant(category?: string): 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info' {
if (!category) return 'default';
switch (category) {
case 'driver':
return 'primary';
case 'team':
return 'info';
case 'nations':
return 'success';
case 'trophy':
return 'warning';
case 'endurance':
return 'warning';
case 'sprint':
return 'danger';
default:
return 'default';
}
}
function getGameVariant(gameId?: string): 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info' {
switch (gameId) {
case 'iracing':
return 'warning';
case 'acc':
return 'success';
case 'f1-23':
case 'f1-24':
return 'danger';
default:
return 'primary';
}
}
function isNewLeague(createdAt: string | Date): boolean {
const oneWeekAgo = new Date();
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
return new Date(createdAt) > oneWeekAgo;
}
export function LeagueCard({ league, onClick }: LeagueCardProps) {
const coverUrl = getMediaUrl('league-cover', league.id);
const logoUrl = league.logoUrl;
const ChampionshipIcon = getChampionshipIcon(league.scoring?.primaryChampionshipType);
const championshipLabel = getChampionshipLabel(league.scoring?.primaryChampionshipType);
const gameVariant = getGameVariant(league.scoring?.gameId);
const isNew = isNewLeague(league.createdAt);
const isTeamLeague = league.maxTeams && league.maxTeams > 0;
const categoryLabel = getCategoryLabel(league.category || undefined);
const categoryVariant = getCategoryVariant(league.category || undefined);
const usedSlots = isTeamLeague ? (league.usedTeamSlots ?? 0) : (league.usedDriverSlots ?? 0);
const maxSlots = isTeamLeague ? (league.maxTeams ?? 0) : (league.maxDrivers ?? 0);
const fillPercentage = maxSlots > 0 ? (usedSlots / maxSlots) * 100 : 0;
const hasOpenSlots = maxSlots > 0 && usedSlots < maxSlots;
const getSlotLabel = () => {
if (isTeamLeague) return 'Teams';
if (league.scoring?.primaryChampionshipType === 'nations') return 'Nations';
return 'Drivers';
};
const slotLabel = getSlotLabel();
return (
<UiLeagueCard
name={league.name}
description={league.description || undefined}
coverUrl={coverUrl}
logoUrl={logoUrl || undefined}
slotLabel={slotLabel}
usedSlots={usedSlots}
maxSlots={maxSlots || '∞'}
fillPercentage={fillPercentage}
hasOpenSlots={hasOpenSlots}
openSlotsCount={maxSlots > 0 ? (maxSlots as number) - usedSlots : 0}
isTeamLeague={!!isTeamLeague}
usedDriverSlots={league.usedDriverSlots}
maxDrivers={league.maxDrivers}
timingSummary={league.timingSummary}
onClick={onClick}
badges={
<>
{isNew && (
<Badge variant="success" icon={Sparkles} size="sm">
NEW
</Badge>
)}
{league.scoring?.gameName && (
<Badge variant={gameVariant} icon={Gamepad2} size="sm">
{league.scoring.gameName}
</Badge>
)}
{league.category && (
<Badge variant={categoryVariant} icon={Layers} size="sm">
{categoryLabel}
</Badge>
)}
</>
}
championshipBadge={
<Badge variant="outline" icon={ChampionshipIcon} size="sm">
{championshipLabel}
</Badge>
}
/>
);
}