import { useState, useEffect } from 'react' import { Link } from 'react-router-dom' import { marathonsApi } from '@/api' import type { MarathonListItem } from '@/types' import { NeonButton, GlassCard, StatsCard } from '@/components/ui' import { Plus, Users, Calendar, Loader2, Trophy, Gamepad2, ChevronRight, Hash, Sparkles } from 'lucide-react' import { format } from 'date-fns' import { ru } from 'date-fns/locale' export function MarathonsPage() { const [marathons, setMarathons] = useState([]) const [isLoading, setIsLoading] = useState(true) const [joinCode, setJoinCode] = useState('') const [joinError, setJoinError] = useState(null) const [isJoining, setIsJoining] = useState(false) const [showJoinSection, setShowJoinSection] = useState(false) useEffect(() => { loadMarathons() }, []) const loadMarathons = async () => { try { const data = await marathonsApi.list() setMarathons(data) } catch (error) { console.error('Failed to load marathons:', error) } finally { setIsLoading(false) } } const handleJoin = async () => { if (!joinCode.trim()) return setJoinError(null) setIsJoining(true) try { await marathonsApi.join(joinCode.trim()) setJoinCode('') setShowJoinSection(false) await loadMarathons() } catch (err: unknown) { const error = err as { response?: { data?: { detail?: string } } } setJoinError(error.response?.data?.detail || 'Не удалось присоединиться') } finally { setIsJoining(false) } } const getStatusConfig = (status: string) => { switch (status) { case 'preparing': return { color: 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30', text: 'Подготовка', dot: 'bg-yellow-500', } case 'active': return { color: 'bg-neon-500/20 text-neon-400 border-neon-500/30', text: 'Активен', dot: 'bg-neon-500 animate-pulse', } case 'finished': return { color: 'bg-gray-500/20 text-gray-400 border-gray-500/30', text: 'Завершён', dot: 'bg-gray-500', } default: return { color: 'bg-gray-500/20 text-gray-400 border-gray-500/30', text: status, dot: 'bg-gray-500', } } } // Stats const activeCount = marathons.filter(m => m.status === 'active').length const completedCount = marathons.filter(m => m.status === 'finished').length const totalParticipants = marathons.reduce((acc, m) => acc + m.participants_count, 0) if (isLoading) { return (

Загрузка марафонов...

) } return (
{/* Header */}

Мои марафоны

Управляйте своими игровыми соревнованиями

setShowJoinSection(!showJoinSection)} icon={} > По коду }> Создать
{/* Stats */} {marathons.length > 0 && (
} color="default" /> } color="neon" /> } color="purple" /> } color="pink" />
)} {/* Join marathon */} {showJoinSection && (

Присоединиться к марафону

Введите код приглашения

setJoinCode(e.target.value.toUpperCase())} onKeyDown={(e) => e.key === 'Enter' && handleJoin()} placeholder="XXXXXX" className="input flex-1 font-mono text-center tracking-widest uppercase" maxLength={10} /> Присоединиться
{joinError && (

{joinError}

)}
)} {/* Marathon list */} {marathons.length === 0 ? (

Нет марафонов

Создайте свой первый марафон или присоединитесь к существующему по коду

setShowJoinSection(true)} icon={} > Ввести код }> Создать марафон
) : (
{marathons.map((marathon, index) => { const status = getStatusConfig(marathon.status) return (
{/* Icon */}
{/* Info */}

{marathon.title}

{marathon.participants_count} {marathon.start_date && ( {format(new Date(marathon.start_date), 'd MMM yyyy', { locale: ru })} )}
{/* Status & Arrow */}
{status.text}
) })}
)}
) }