import { useState, useEffect } from 'react' import { useParams, useNavigate, Link } from 'react-router-dom' import { marathonsApi } from '@/api' import type { MarathonPublicInfo } from '@/types' import { useAuthStore } from '@/store/auth' import { NeonButton, GlassCard } from '@/components/ui' import { Users, Loader2, Trophy, UserPlus, LogIn, Gamepad2, AlertCircle, Sparkles, Crown } from 'lucide-react' export function InvitePage() { const { code } = useParams<{ code: string }>() const navigate = useNavigate() const { isAuthenticated, setPendingInviteCode } = useAuthStore() const [marathon, setMarathon] = useState(null) const [isLoading, setIsLoading] = useState(true) const [isJoining, setIsJoining] = useState(false) const [error, setError] = useState(null) useEffect(() => { loadMarathon() }, [code]) const loadMarathon = async () => { if (!code) return try { const data = await marathonsApi.getByCode(code) setMarathon(data) } catch { setError('Марафон не найден или ссылка недействительна') } finally { setIsLoading(false) } } const handleJoin = async () => { if (!code) return setIsJoining(true) try { const joined = await marathonsApi.join(code) navigate(`/marathons/${joined.id}`) } catch (err: unknown) { const apiError = err as { response?: { data?: { detail?: string } } } const detail = apiError.response?.data?.detail if (detail === 'Already joined this marathon') { // Already a member, just redirect navigate(`/marathons/${marathon?.id}`) } else { setError(detail || 'Не удалось присоединиться') } } finally { setIsJoining(false) } } const handleAuthRedirect = (path: string) => { if (code) { setPendingInviteCode(code) } navigate(path) } if (isLoading) { return (

Загрузка приглашения...

) } if (error || !marathon) { return (

Ошибка

{error || 'Марафон не найден'}

К списку марафонов
) } 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', } } } const status = getStatusConfig(marathon.status) return (
{/* Background effects */}
{/* Header */}

Приглашение в марафон

Вас пригласили присоединиться

{/* Marathon info */}

{marathon.title}

{marathon.description && (

{marathon.description}

)}
{status.text} {marathon.participants_count}
{/* Organizer */}
Организатор: {marathon.creator_nickname}
{/* Actions */} {marathon.status === 'finished' ? (

Этот марафон уже завершён

К списку марафонов
) : isAuthenticated ? ( } > Присоединиться ) : (

Чтобы присоединиться, войдите или зарегистрируйтесь

handleAuthRedirect('/login')} icon={} > Войти handleAuthRedirect('/register')} icon={} > Зарегистрироваться
)}
{/* Decorative elements */}
) }