'use client'; import React, { useState } from 'react'; import { LeagueCard } from '@/components/leagues/LeagueCardWrapper'; import { LeagueSummaryViewModel } from '@/lib/view-models/LeagueSummaryViewModel'; import { routes } from '@/lib/routing/RouteConfig'; import type { LeaguesViewData } from '@/lib/view-data/LeaguesViewData'; import { Box } from '@/ui/Box'; import { Stack } from '@/ui/Stack'; import { Text } from '@/ui/Text'; import { Heading } from '@/ui/Heading'; import { Button } from '@/ui/Button'; import { Input } from '@/ui/Input'; import { Flame, Globe, Plus, Search, Sparkles, Target, Trophy, Users, Flag, Award, Timer, Clock, type LucideIcon, } from 'lucide-react'; import { useRouter } from 'next/navigation'; // ============================================================================ // TYPES // ============================================================================ type CategoryId = | 'all' | 'driver' | 'team' | 'nations' | 'trophy' | 'new' | 'popular' | 'openSlots' | 'endurance' | 'sprint'; interface Category { id: CategoryId; label: string; icon: LucideIcon; description: string; filter: (league: LeaguesViewData['leagues'][number]) => boolean; color?: string; } interface LeaguesTemplateProps { viewData: LeaguesViewData; } // ============================================================================ // CATEGORIES // ============================================================================ const CATEGORIES: Category[] = [ { id: 'all', label: 'All', icon: Globe, description: 'Browse all available leagues', filter: () => true, }, { id: 'popular', label: 'Popular', icon: Flame, description: 'Most active leagues right now', filter: (league) => { const fillRate = (league.usedDriverSlots ?? 0) / (league.maxDrivers ?? 1); return fillRate > 0.7; }, color: 'text-orange-400', }, { id: 'new', label: 'New', icon: Sparkles, description: 'Fresh leagues looking for members', filter: (league) => { const oneWeekAgo = new Date(); oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); return new Date(league.createdAt) > oneWeekAgo; }, color: 'text-green-500', }, { id: 'openSlots', label: 'Open Slots', icon: Target, description: 'Leagues with available spots', filter: (league) => { if (league.maxTeams && league.maxTeams > 0) { const usedTeams = league.usedTeamSlots ?? 0; return usedTeams < league.maxTeams; } const used = league.usedDriverSlots ?? 0; const max = league.maxDrivers ?? 0; return max > 0 && used < max; }, color: 'text-cyan-400', }, { id: 'driver', label: 'Driver', icon: Trophy, description: 'Compete as an individual', filter: (league) => league.scoring?.primaryChampionshipType === 'driver', }, { id: 'team', label: 'Team', icon: Users, description: 'Race together as a team', filter: (league) => league.scoring?.primaryChampionshipType === 'team', }, { id: 'nations', label: 'Nations', icon: Flag, description: 'Represent your country', filter: (league) => league.scoring?.primaryChampionshipType === 'nations', }, { id: 'trophy', label: 'Trophy', icon: Award, description: 'Special championship events', filter: (league) => league.scoring?.primaryChampionshipType === 'trophy', }, { id: 'endurance', label: 'Endurance', icon: Timer, description: 'Long-distance racing', filter: (league) => league.scoring?.scoringPresetId?.includes('endurance') ?? league.timingSummary?.includes('h Race') ?? false, }, { id: 'sprint', label: 'Sprint', icon: Clock, description: 'Quick, intense races', filter: (league) => (league.scoring?.scoringPresetId?.includes('sprint') ?? false) && !(league.scoring?.scoringPresetId?.includes('endurance') ?? false), }, ]; export function LeaguesPageClient({ viewData }: LeaguesTemplateProps) { const router = useRouter(); const [searchQuery, setSearchQuery] = useState(''); const [activeCategory, setActiveCategory] = useState('all'); const filteredLeagues = viewData.leagues.filter((league) => { const matchesSearch = !searchQuery || league.name.toLowerCase().includes(searchQuery.toLowerCase()) || (league.description ?? '').toLowerCase().includes(searchQuery.toLowerCase()); const category = CATEGORIES.find(c => c.id === activeCategory); const matchesCategory = !category || category.filter(league); return matchesSearch && matchesCategory; }); return ( {/* Hero */} Competition Hub Find Your Grid From casual sprints to epic endurance battles — discover the perfect league for your racing style. {viewData.leagues.length} Active Leagues {/* Search & Filters */} ) => setSearchQuery(e.target.value)} icon={} /> {CATEGORIES.map((category) => { const isActive = activeCategory === category.id; const CategoryIcon = category.icon; return ( ); })} {/* Grid */} {filteredLeagues.length > 0 ? ( {filteredLeagues.map((league) => ( router.push(routes.league.detail(league.id))} /> ))} ) : ( No Leagues Found Try adjusting your search or filters )} ); }