import { useState, useEffect } from 'react' import { useParams, useNavigate, Link } from 'react-router-dom' import { marathonsApi } from '@/api' import type { Marathon } from '@/types' import { Button, Card, CardContent } from '@/components/ui' import { useAuthStore } from '@/store/auth' import { Users, Calendar, Trophy, Play, Settings, Copy, Check, Loader2, Trash2, Globe, Lock, CalendarCheck, UserPlus, Gamepad2, ArrowLeft } from 'lucide-react' import { format } from 'date-fns' export function MarathonPage() { const { id } = useParams<{ id: string }>() const navigate = useNavigate() const user = useAuthStore((state) => state.user) const [marathon, setMarathon] = useState(null) const [isLoading, setIsLoading] = useState(true) const [copied, setCopied] = useState(false) const [isDeleting, setIsDeleting] = useState(false) const [isJoining, setIsJoining] = useState(false) useEffect(() => { loadMarathon() }, [id]) const loadMarathon = async () => { if (!id) return try { const data = await marathonsApi.get(parseInt(id)) setMarathon(data) } catch (error) { console.error('Failed to load marathon:', error) navigate('/marathons') } finally { setIsLoading(false) } } const copyInviteCode = () => { if (marathon) { navigator.clipboard.writeText(marathon.invite_code) setCopied(true) setTimeout(() => setCopied(false), 2000) } } const handleDelete = async () => { if (!marathon || !confirm('Вы уверены, что хотите удалить этот марафон? Это действие нельзя отменить.')) return setIsDeleting(true) try { await marathonsApi.delete(marathon.id) navigate('/marathons') } catch (error) { console.error('Failed to delete marathon:', error) alert('Не удалось удалить марафон') } finally { setIsDeleting(false) } } const handleJoinPublic = async () => { if (!marathon) return setIsJoining(true) try { const updated = await marathonsApi.joinPublic(marathon.id) setMarathon(updated) } catch (err: unknown) { const error = err as { response?: { data?: { detail?: string } } } alert(error.response?.data?.detail || 'Не удалось присоединиться') } finally { setIsJoining(false) } } if (isLoading || !marathon) { return (
) } const isOrganizer = marathon.my_participation?.role === 'organizer' || user?.role === 'admin' const isParticipant = !!marathon.my_participation const isCreator = marathon.creator.id === user?.id const canDelete = isCreator || user?.role === 'admin' return (
{/* Back button */} К списку марафонов {/* Header */}

{marathon.title}

{marathon.is_public ? ( <> Открытый ) : ( <> Закрытый )}
{marathon.description && (

{marathon.description}

)}
{/* Кнопка присоединиться для открытых марафонов */} {marathon.is_public && !isParticipant && marathon.status !== 'finished' && ( )} {/* Настройка для организаторов */} {marathon.status === 'preparing' && isOrganizer && ( )} {/* Предложить игру для участников (не организаторов) если разрешено */} {marathon.status === 'preparing' && isParticipant && !isOrganizer && marathon.game_proposal_mode === 'all_participants' && ( )} {marathon.status === 'active' && isParticipant && ( )} {canDelete && ( )}
{/* Stats */}
{marathon.participants_count}
Участников
{marathon.games_count}
Игр
{marathon.start_date ? format(new Date(marathon.start_date), 'd MMM') : '-'}
Начало
{marathon.end_date ? format(new Date(marathon.end_date), 'd MMM') : '-'}
Конец
{marathon.status === 'active' ? 'Активен' : marathon.status === 'preparing' ? 'Подготовка' : 'Завершён'}
Статус
{/* Invite code */} {marathon.status !== 'finished' && (

Код приглашения

{marathon.invite_code}

Поделитесь этим кодом с друзьями, чтобы они могли присоединиться к марафону

)} {/* My stats */} {marathon.my_participation && (

Ваша статистика

{marathon.my_participation.total_points}
Очков
{marathon.my_participation.current_streak}
Серия
{marathon.my_participation.drop_count}
Пропусков
)}
) }