website refactor
This commit is contained in:
@@ -19,6 +19,8 @@ export class LeaguesViewDataBuilder {
|
||||
createdAt: league.createdAt,
|
||||
maxDrivers: league.settings.maxDrivers,
|
||||
usedDriverSlots: league.usedSlots,
|
||||
activeDriversCount: (league as any).activeDriversCount,
|
||||
nextRaceAt: (league as any).nextRaceAt,
|
||||
maxTeams: undefined, // Not provided in DTO
|
||||
usedTeamSlots: undefined, // Not provided in DTO
|
||||
structureSummary: league.settings.qualifyingFormat || '',
|
||||
|
||||
101
apps/website/lib/config/leagueCategories.ts
Normal file
101
apps/website/lib/config/leagueCategories.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import {
|
||||
Trophy,
|
||||
Users,
|
||||
Flag,
|
||||
Award,
|
||||
Sparkles,
|
||||
Zap,
|
||||
Clock,
|
||||
Layout,
|
||||
type LucideIcon
|
||||
} from 'lucide-react';
|
||||
|
||||
export type CategoryId =
|
||||
| 'all'
|
||||
| 'driver'
|
||||
| 'team'
|
||||
| 'nations'
|
||||
| 'trophy'
|
||||
| 'new'
|
||||
| 'popular'
|
||||
| 'openSlots'
|
||||
| 'endurance'
|
||||
| 'sprint';
|
||||
|
||||
export interface LeagueCategory {
|
||||
id: CategoryId;
|
||||
label: string;
|
||||
icon: LucideIcon;
|
||||
description: string;
|
||||
color?: string;
|
||||
filter: (league: any) => boolean;
|
||||
}
|
||||
|
||||
export const LEAGUE_CATEGORIES: LeagueCategory[] = [
|
||||
{
|
||||
id: 'all',
|
||||
label: 'All',
|
||||
icon: Layout,
|
||||
description: 'All available competition infrastructure.',
|
||||
filter: () => true,
|
||||
},
|
||||
{
|
||||
id: 'popular',
|
||||
label: 'Popular',
|
||||
icon: Zap,
|
||||
description: 'High utilization infrastructure.',
|
||||
filter: (league) => {
|
||||
const fillRate = (league.usedDriverSlots ?? 0) / (league.maxDrivers ?? 1);
|
||||
return fillRate > 0.7;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'new',
|
||||
label: 'New',
|
||||
icon: Sparkles,
|
||||
description: 'Recently deployed infrastructure.',
|
||||
filter: (league) => {
|
||||
const oneWeekAgo = new Date();
|
||||
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
|
||||
return new Date(league.createdAt) > oneWeekAgo;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'driver',
|
||||
label: 'Driver',
|
||||
icon: Trophy,
|
||||
description: 'Individual competition format.',
|
||||
filter: (league) => league.scoring?.primaryChampionshipType === 'driver',
|
||||
},
|
||||
{
|
||||
id: 'team',
|
||||
label: 'Team',
|
||||
icon: Users,
|
||||
description: 'Team-based competition format.',
|
||||
filter: (league) => league.scoring?.primaryChampionshipType === 'team',
|
||||
},
|
||||
{
|
||||
id: 'nations',
|
||||
label: 'Nations',
|
||||
icon: Flag,
|
||||
description: 'National representation format.',
|
||||
filter: (league) => league.scoring?.primaryChampionshipType === 'nations',
|
||||
},
|
||||
{
|
||||
id: 'trophy',
|
||||
label: 'Trophy',
|
||||
icon: Award,
|
||||
description: 'Special event infrastructure.',
|
||||
filter: (league) => league.scoring?.primaryChampionshipType === 'trophy',
|
||||
},
|
||||
{
|
||||
id: 'endurance',
|
||||
label: 'Endurance',
|
||||
icon: Clock,
|
||||
description: 'Long-duration competition.',
|
||||
filter: (league) =>
|
||||
league.scoring?.scoringPresetId?.includes('endurance') ??
|
||||
league.timingSummary?.includes('h Race') ??
|
||||
false,
|
||||
},
|
||||
];
|
||||
@@ -16,6 +16,8 @@ export interface LeaguesViewData {
|
||||
createdAt: string; // ISO string
|
||||
maxDrivers: number;
|
||||
usedDriverSlots: number;
|
||||
activeDriversCount?: number;
|
||||
nextRaceAt?: string;
|
||||
maxTeams: number | undefined;
|
||||
usedTeamSlots: number | undefined;
|
||||
structureSummary: string;
|
||||
|
||||
@@ -7,6 +7,8 @@ export interface LeagueSummaryViewModel {
|
||||
createdAt: string;
|
||||
maxDrivers: number;
|
||||
usedDriverSlots: number;
|
||||
activeDriversCount?: number;
|
||||
nextRaceAt?: string;
|
||||
maxTeams?: number;
|
||||
usedTeamSlots?: number;
|
||||
structureSummary: string;
|
||||
|
||||
Reference in New Issue
Block a user