import { useState, useEffect } from 'react' import { useParams, Link } from 'react-router-dom' import { marathonsApi } from '@/api' import type { LeaderboardEntry } from '@/types' import { GlassCard } from '@/components/ui' import { useAuthStore } from '@/store/auth' import { Trophy, Flame, ArrowLeft, Loader2, Crown, Medal, Award, Star, Zap, Target } from 'lucide-react' export function LeaderboardPage() { const { id } = useParams<{ id: string }>() const user = useAuthStore((state) => state.user) const [leaderboard, setLeaderboard] = useState([]) const [isLoading, setIsLoading] = useState(true) useEffect(() => { loadLeaderboard() }, [id]) const loadLeaderboard = async () => { if (!id) return try { const data = await marathonsApi.getLeaderboard(parseInt(id)) setLeaderboard(data) } catch (error) { console.error('Failed to load leaderboard:', error) } finally { setIsLoading(false) } } const getRankConfig = (rank: number) => { switch (rank) { case 1: return { icon: , color: 'text-yellow-400', bg: 'bg-yellow-500/20', border: 'border-yellow-500/30', glow: 'shadow-[0_0_20px_rgba(234,179,8,0.3)]', gradient: 'from-yellow-500/20 via-transparent to-transparent', } case 2: return { icon: , color: 'text-gray-300', bg: 'bg-gray-400/20', border: 'border-gray-400/30', glow: 'shadow-[0_0_15px_rgba(156,163,175,0.2)]', gradient: 'from-gray-400/10 via-transparent to-transparent', } case 3: return { icon: , color: 'text-amber-600', bg: 'bg-amber-600/20', border: 'border-amber-600/30', glow: 'shadow-[0_0_15px_rgba(217,119,6,0.2)]', gradient: 'from-amber-600/10 via-transparent to-transparent', } default: return { icon: {rank}, color: 'text-gray-500', bg: 'bg-dark-700', border: 'border-dark-600', glow: '', gradient: '', } } } // Top 3 for podium const topThree = leaderboard.slice(0, 3) // Calculate stats const totalPoints = leaderboard.reduce((acc, e) => acc + e.total_points, 0) const maxStreak = Math.max(...leaderboard.map(e => e.current_streak), 0) if (isLoading) { return (

Загрузка рейтинга...

) } return (
{/* Header */}

Таблица лидеров

Рейтинг участников марафона

{leaderboard.length === 0 ? (

Пока нет участников

Станьте первым в рейтинге!

) : ( <> {/* Podium for top 3 */} {topThree.length >= 3 && (
{/* 2nd place */}
2

{topThree[1].user.nickname}

{topThree[1].total_points} очков

{/* 1st place */}

{topThree[0].user.nickname}

{topThree[0].total_points} очков

{/* 3rd place */}
3

{topThree[2].user.nickname}

{topThree[2].total_points} очков

)} {/* Stats row */}

{leaderboard.length}

Участников

{totalPoints}

Всего очков

{maxStreak}

Макс. серия

{/* Full leaderboard */}

Полный рейтинг

Все участники марафона

{leaderboard.map((entry, index) => { const isCurrentUser = entry.user.id === user?.id const rankConfig = getRankConfig(entry.rank) return (
{/* Gradient overlay for top 3 */} {entry.rank <= 3 && (
)} {/* Rank */}
{rankConfig.icon}
{/* User info */}
{entry.user.nickname} {isCurrentUser && ( Вы )}
{entry.completed_count} выполнено {entry.dropped_count > 0 && ( {entry.dropped_count} пропущено )}
{/* Streak */} {entry.current_streak > 0 && (
{entry.current_streak}
)} {/* Points */}
{entry.total_points}
очков
) })}
)}
) }