diff --git a/app/(home)/main/page.tsx b/app/(home)/main/page.tsx index f1a436f..1819ca5 100644 --- a/app/(home)/main/page.tsx +++ b/app/(home)/main/page.tsx @@ -1,280 +1,850 @@ "use client" -import { useState } from "react" +import { useState, useEffect, useRef } from "react" import { Card } from "@/components/ui/card" import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" import { - BookOpen, - Trophy, - Target, - TrendingUp, + Lock, + CheckCircle2, + Circle, + Zap, + Target, + Shield, + Code, + Database, + Globe, + X, + Search, + Filter, + Trophy, Clock, - Award, - CheckCircle2, - PlayCircle + Star, + Sparkles, + ChevronDown } from "lucide-react" +import Link from "next/link" -export default function Home() { +interface Particle { + x: number + y: number + vx: number + vy: number + size: number + opacity: number +} + +export default function MainPage() { const [activeTab, setActiveTab] = useState("main") + const [selectedQuest, setSelectedQuest] = useState(null) + const [hoveredQuest, setHoveredQuest] = useState(null) + const [mousePos, setMousePos] = useState({ x: 0, y: 0 }) + const [particles, setParticles] = useState([]) + const [searchQuery, setSearchQuery] = useState("") + const [filterDifficulty, setFilterDifficulty] = useState("all") + const [viewMode, setViewMode] = useState<"map" | "list">("map") + const canvasRef = useRef(null) + const [stats, setStats] = useState({ + xpToday: 450, + timeSpent: "2h 15m", + streak: 7, + levelProgress: 68 + }) - // Mock data для демонстрации - const stats = { - coursesInProgress: 3, - completedCourses: 12, - totalPoints: 2450, - rank: "Advanced" - } - - const recentCourses = [ - { id: 1, title: "Advanced React Patterns", progress: 65, time: "2h 30m left" }, - { id: 2, title: "System Design", progress: 40, time: "5h 15m left" }, - { id: 3, title: "TypeScript Deep Dive", progress: 85, time: "45m left" } + // Квесты/проекты + const quests = [ + { + id: 1, + name: "Registration", + status: "completed", + icon: Circle, + color: "cyan", + description: "Создайте свой аккаунт и начните путешествие в мир киберпространства", + reward: 100, + difficulty: "Easy", + estimatedTime: "5 min", + prerequisites: [] + }, + { + id: 2, + name: "Sanctum", + status: "completed", + icon: Shield, + color: "cyan", + description: "Пройдите базовую защиту системы и изучите основы безопасности", + reward: 150, + difficulty: "Easy", + estimatedTime: "15 min", + prerequisites: [1] + }, + { + id: 3, + name: "Memories", + status: "unlocked", + icon: Database, + color: "yellow", + description: "Восстановите утерянные данные из архива и раскройте секреты прошлого", + reward: 200, + difficulty: "Medium", + estimatedTime: "30 min", + prerequisites: [1, 2] + }, + { + id: 4, + name: "Cyber toy", + status: "locked", + icon: Code, + color: "red", + description: "Взломайте защищенную систему используя продвинутые техники", + reward: 250, + difficulty: "Medium", + estimatedTime: "45 min", + prerequisites: [3] + }, + { + id: 5, + name: "Flood", + status: "locked", + icon: Zap, + color: "red", + description: "Преодолейте мощные потоки данных и найдите путь через хаос", + reward: 300, + difficulty: "Hard", + estimatedTime: "1h", + prerequisites: [3] + }, + { + id: 6, + name: "Core", + status: "locked", + icon: Target, + color: "red", + description: "Проникните в самое ядро системы и получите контроль", + reward: 350, + difficulty: "Hard", + estimatedTime: "1h 30m", + prerequisites: [4, 5] + }, + { + id: 7, + name: "Access point", + status: "locked", + icon: Globe, + color: "red", + description: "Получите доступ к финальной точке и завершите миссию", + reward: 500, + difficulty: "Expert", + estimatedTime: "2h", + prerequisites: [6] + }, + { + id: 8, + name: "???", + status: "locked", + icon: Lock, + color: "gray", + description: "Секретное задание. Требования неизвестны.", + reward: 999, + difficulty: "???", + estimatedTime: "???", + prerequisites: [7] + } ] - const achievements = [ - { id: 1, title: "Fast Learner", icon: Trophy, unlocked: true }, - { id: 2, title: "Course Master", icon: Award, unlocked: true }, - { id: 3, title: "Consistency King", icon: Target, unlocked: false } + // Initialize particles + useEffect(() => { + const initParticles: Particle[] = [] + for (let i = 0; i < 50; i++) { + initParticles.push({ + x: Math.random() * window.innerWidth, + y: Math.random() * window.innerHeight, + vx: (Math.random() - 0.5) * 0.5, + vy: (Math.random() - 0.5) * 0.5, + size: Math.random() * 2 + 1, + opacity: Math.random() * 0.5 + 0.2 + }) + } + setParticles(initParticles) + }, []) + + // Animate particles + useEffect(() => { + const canvas = canvasRef.current + if (!canvas) return + + const ctx = canvas.getContext('2d') + if (!ctx) return + + canvas.width = window.innerWidth + canvas.height = window.innerHeight + + let animationFrameId: number + + const animate = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height) + + setParticles(prevParticles => { + return prevParticles.map(particle => { + let newX = particle.x + particle.vx + let newY = particle.y + particle.vy + + if (newX < 0 || newX > canvas.width) particle.vx *= -1 + if (newY < 0 || newY > canvas.height) particle.vy *= -1 + + newX = Math.max(0, Math.min(canvas.width, newX)) + newY = Math.max(0, Math.min(canvas.height, newY)) + + // Draw particle + ctx.fillStyle = `rgba(6, 182, 212, ${particle.opacity})` + ctx.beginPath() + ctx.arc(newX, newY, particle.size, 0, Math.PI * 2) + ctx.fill() + + return { ...particle, x: newX, y: newY } + }) + }) + + animationFrameId = requestAnimationFrame(animate) + } + + animate() + + return () => cancelAnimationFrame(animationFrameId) + }, []) + + // Mouse parallax + useEffect(() => { + const handleMouseMove = (e: MouseEvent) => { + setMousePos({ x: e.clientX, y: e.clientY }) + } + window.addEventListener('mousemove', handleMouseMove) + return () => window.removeEventListener('mousemove', handleMouseMove) + }, []) + + const getStatusColor = (status: string) => { + switch (status) { + case "completed": return "from-green-500 to-emerald-600" + case "unlocked": return "from-yellow-500 to-amber-600" + case "locked": return "from-red-500 to-rose-600" + default: return "from-gray-500 to-gray-600" + } + } + + const getDifficultyColor = (difficulty: string) => { + switch (difficulty) { + case "Easy": return "text-green-400" + case "Medium": return "text-yellow-400" + case "Hard": return "text-orange-400" + case "Expert": return "text-red-400" + default: return "text-gray-400" + } + } + + const filteredQuests = quests.filter(quest => { + const matchesSearch = quest.name.toLowerCase().includes(searchQuery.toLowerCase()) + const matchesDifficulty = filterDifficulty === "all" || quest.difficulty === filterDifficulty + return matchesSearch && matchesDifficulty + }) + + const questPositions = [ + { x: 150, y: 250 }, + { x: 300, y: 250 }, + { x: 450, y: 250 }, + { x: 600, y: 250 }, + { x: 750, y: 150 }, + { x: 750, y: 350 }, + { x: 900, y: 250 }, + { x: 1050, y: 250 } ] return ( -
+
+ {/* Animated particles canvas */} + + + {/* Animated background effects */} +
+
+ {/* Header */} -
+
- {/* Main Content */} -
- {/* Stats Grid */} -
- -
- - IN PROGRESS + {/* Stats Bar */} +
+
+ +
+
+ +
+
+
XP Today
+
+{stats.xpToday}
+
-
- {stats.coursesInProgress} -
-

Active Courses

- -
- - COMPLETED + +
+
+ +
+
+
Time Spent
+
{stats.timeSpent}
+
-
- {stats.completedCourses} -
-

Finished

- -
- - TOTAL + +
+
+ +
+
+
Streak
+
{stats.streak} days
+
-
- {stats.totalPoints} -
-

Points Earned

- -
- - RANK + +
+
+ +
+
+
Level Progress
+
+
+
+
-
- {stats.rank} -
-

Current Level

+
-
- {/* Continue Learning Section */} - -
-

- Continue Learning -

- + +
+
+ + {/* Search */} +
+ setSearchQuery(e.target.value)} + className="bg-[#0a0e1a]/80 border-cyan-500/40 text-cyan-400 placeholder:text-cyan-400/30 font-mono text-sm" + /> +
+ + {/* Filter */} +
+
-
- {recentCourses.map((course) => ( - -
-
-

- {course.title} -

-
- - {course.time} -
-
- -
- - {/* Progress Bar */} -
-
- Progress - {course.progress}% -
-
-
-
-
- - ))} -
-
- - {/* Achievements Section */} - -

- Achievements -

- -
- {achievements.map((achievement) => { - const Icon = achievement.icon +
+ {filteredQuests.map((quest) => { + const Icon = quest.icon return ( - setSelectedQuest(quest.id)} + className={`w-full text-left p-3 rounded-lg border transition-all duration-300 group ${ + selectedQuest === quest.id + ? 'bg-cyan-500/20 border-cyan-500/60 shadow-[0_0_20px_rgba(6,182,212,0.2)]' + : quest.status === 'completed' + ? 'bg-green-500/5 border-green-500/30 hover:border-green-500/50' + : quest.status === 'unlocked' + ? 'bg-yellow-500/5 border-yellow-500/30 hover:border-yellow-500/50' + : 'bg-[#0a0e1a]/50 border-cyan-500/20 hover:border-cyan-500/30' }`} >
-
- +
-
-

- {achievement.title} -

-

- {achievement.unlocked ? 'Unlocked' : 'Locked'} -

+
+
+ {quest.name} +
+
+ {quest.difficulty} • {quest.reward} pts +
+ {quest.status === 'completed' && } + {quest.status === 'unlocked' && } + {quest.status === 'locked' && }
- + ) })}
+
- + {/* Center - Interactive Quest Map */} + +
+
+

+ + Quest Network +

+
+ {quests.filter(q => q.status === 'completed').length}/{quests.length} Completed +
+
+ + {/* SVG Quest Map */} +
+ + + + + + + + + + + + + + + + + + + + {/* Animated data flow particles */} + {quests.slice(0, -1).map((quest, index) => { + if (quest.status === 'completed') { + const start = questPositions[index] + const end = questPositions[index + 1] + return ( + + + + ) + } + return null + })} + + {/* Connection Lines */} + + + + + + + + + + {/* Quest Nodes - Hexagons */} + {questPositions.map((pos, index) => { + const quest = quests[index] + const isSelected = selectedQuest === quest.id + const isHovered = hoveredQuest === quest.id + const statusColor = + quest.status === 'completed' ? '#10b981' : + quest.status === 'unlocked' ? '#eab308' : + '#ef4444' + + const Icon = quest.icon + const hexSize = 30 + const hexPoints = Array.from({ length: 6 }, (_, i) => { + const angle = (Math.PI / 3) * i + return `${pos.x + hexSize * Math.cos(angle)},${pos.y + hexSize * Math.sin(angle)}` + }).join(' ') + + return ( + setHoveredQuest(quest.id)} + onMouseLeave={() => setHoveredQuest(null)} + onClick={() => setSelectedQuest(quest.id)} + className="cursor-pointer transition-all duration-300" + style={{ + transform: isHovered ? 'translateY(-10px)' : 'translateY(0)', + transformOrigin: `${pos.x}px ${pos.y}px` + }} + > + {/* Outer glow rings */} + {isSelected && ( + <> + { + const angle = (Math.PI / 3) * i + return `${pos.x + 45 * Math.cos(angle)},${pos.y + 45 * Math.sin(angle)}` + }).join(' ')} + fill="none" + stroke={statusColor} + strokeWidth="2" + opacity="0.3" + className="animate-ping" + /> + { + const angle = (Math.PI / 3) * i + return `${pos.x + 40 * Math.cos(angle)},${pos.y + 40 * Math.sin(angle)}` + }).join(' ')} + fill="none" + stroke={statusColor} + strokeWidth="3" + opacity="0.6" + /> + + )} + + {/* Hexagon node */} + + + {/* Inner hexagon */} + { + const angle = (Math.PI / 3) * i + return `${pos.x + 20 * Math.cos(angle)},${pos.y + 20 * Math.sin(angle)}` + }).join(' ')} + fill={statusColor} + opacity={quest.status === 'locked' ? '0.3' : '0.6'} + /> + + {/* Hover tooltip */} + {isHovered && ( + + + + {quest.name} + + + {quest.difficulty} • {quest.estimatedTime} + + + +{quest.reward} PTS + + + )} + + ) + })} + + + {/* Quest Details Panel with Close Button */} + {selectedQuest && ( + + {(() => { + const quest = quests.find(q => q.id === selectedQuest) + if (!quest) return null + const Icon = quest.icon + + return ( + <> + {/* Close Button */} + + +
+
+
+ +
+ +
+
+
+

+ {quest.name} +

+
+ + {quest.difficulty} + + + + {quest.estimatedTime} + + + + +{quest.reward} PTS + +
+
+
+ {quest.status === 'completed' && ( + <> + + Completed + + )} + {quest.status === 'unlocked' && ( + <> + + Available + + )} + {quest.status === 'locked' && ( + <> + + Locked + + )} +
+
+ +

+ {quest.description} +

+ + {/* Prerequisites */} + {quest.prerequisites.length > 0 && ( +
+
+ + Prerequisites: +
+
+ {quest.prerequisites.map(prereqId => { + const prereq = quests.find(q => q.id === prereqId) + return prereq ? ( + + {prereq.name} + + ) : null + })} +
+
+ )} + +
+ + + {quest.status === 'completed' && ( + + )} +
+
+
+ + ) + })()} + + )} +
+
- {/* Subtle grid background */} + {/* Enhanced Background grid */}
+ + {/* Scanline effect */} +
+
+
+ +
) } \ No newline at end of file diff --git a/app/(home)/main/profile/page.tsx b/app/(home)/main/profile/page.tsx index df3b4c0..923c1ab 100644 --- a/app/(home)/main/profile/page.tsx +++ b/app/(home)/main/profile/page.tsx @@ -3,234 +3,443 @@ import { useState } from "react" import { Card } from "@/components/ui/card" import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" import { Progress } from "@/components/ui/progress" -import { User, Award, BookOpen, Trophy, Star } from "lucide-react" +import { User, CheckCircle2, Lock, ChevronLeft, ChevronRight, Sparkles, Zap } from "lucide-react" import Link from "next/link" export default function ProfilePage() { const [activeTab, setActiveTab] = useState("profile") + const [currentBadgeSlide, setCurrentBadgeSlide] = useState(0) // Mock user data const userData = { - name: "Alex Johnson", + nickname: "pennytige", + totalPoints: 1337, level: 5, - xp: 2450, - maxXp: 3000, - rank: "Advanced", - achievements: 8, - coursesCompleted: 12, - totalStudyTime: "124h" + questsCompleted: 7, + totalQuests: 12, + gameProgress: 58 } - const stats = [ - { label: "Level", value: userData.level, icon: Star }, - { label: "XP", value: `${userData.xp}/${userData.maxXp}`, icon: Trophy }, - { label: "Rank", value: userData.rank, icon: Award } + const quests = [ + { id: 1, name: "Registration", date: "2024-08-15 14:23", points: 100, completed: true, active: false }, + { id: 2, name: "Memories", date: "", points: 100, completed: false, active: true, badge: "Получить подарочек" }, + { id: 3, name: "Cyber toy", date: "", points: 100, completed: false, active: false }, + { id: 4, name: "Flood", date: "", points: 100, completed: false, active: false }, + { id: 5, name: "Core", date: "", points: 100, completed: false, active: false }, + { id: 6, name: "Access point", date: "", points: 100, completed: false, active: false } ] - const achievements = [ - { title: "First Steps", description: "Complete your first course", unlocked: true }, - { title: "Quick Learner", description: "Complete a course in under 24h", unlocked: true }, - { title: "Dedication", description: "Study 7 days in a row", unlocked: true }, - { title: "Master", description: "Complete 10 courses", unlocked: true }, - { title: "Expert", description: "Reach level 5", unlocked: true }, - { title: "Marathon", description: "Study for 100 hours", unlocked: true }, - { title: "Perfectionist", description: "Score 100% on 5 tests", unlocked: false }, - { title: "Legend", description: "Reach level 10", unlocked: false } + const badges = [ + { + id: 1, + name: "Speed Runner", + date: "16.08.2024", + description: "За скорость", + requirement: "Решить: 8%", + icon: "🏃", + color: "from-cyan-500 to-blue-500" + }, + { + id: 2, + name: "Precision Master", + date: "17.08.2024", + description: "За точность", + requirement: "Решить: 25%", + icon: "🎯", + color: "from-purple-500 to-pink-500" + }, + { + id: 3, + name: "Secret Master", + date: "Заблокировано", + description: "Заблокировано", + requirement: "Решить: ???", + locked: true, + icon: "🔒", + color: "from-gray-500 to-gray-700" + }, + { + id: 4, + name: "NoName", + date: "Заблокировано", + description: "", + requirement: "Решить:", + locked: true, + icon: "❓", + color: "from-gray-500 to-gray-700" + } ] + const visibleBadges = badges.slice(currentBadgeSlide, currentBadgeSlide + 3) + + const nextSlide = () => { + if (currentBadgeSlide < badges.length - 3) { + setCurrentBadgeSlide(currentBadgeSlide + 1) + } + } + + const prevSlide = () => { + if (currentBadgeSlide > 0) { + setCurrentBadgeSlide(currentBadgeSlide - 1) + } + } + return ( -
+
+ {/* Animated background effects */} +
+
+
+ {/* Header */} -
+
{/* Main Content */} -
+
- {/* User Profile Card */} - -
- {/* Avatar */} -
- -
- - {/* User Info */} -

- {userData.name} -

-

- {userData.rank} • Level {userData.level} -

- - {/* XP Progress */} -
-
- XP Progress - - {userData.xp}/{userData.maxXp} - -
- -
- - {/* Quick Stats */} -
-
- -
- {userData.coursesCompleted} -
-
Courses
-
-
- -
- {userData.achievements} -
-
Badges
-
-
- - -
-
- - {/* Stats and Achievements */} + {/* Left Column - Personal Progress & Quests */}
- {/* Personal Progress Card */} - -

- Personal progress -

-
- {stats.map((stat, index) => { - const Icon = stat.icon - return ( -
- -
- {stat.value} + {/* Personal Progress */} + + {/* Animated border glow */} +
+ +
+
+ +

+ Personal progress +

+
+ +
+
+
+
+
+ {userData.totalPoints}
- {stat.label} + Total Points
- ) - })} +
+
+
+
+
+ Level {userData.level} +
+
+ Current Level +
+
+
+
+
+
+
+ {userData.questsCompleted}/{userData.totalQuests} +
+
+ Quests Completed +
+
+
+
+
+
+
+ {userData.gameProgress}% +
+
+ Game Progress +
+
+
+
+ + {/* Quests List */} +
+ {quests.map((quest) => ( +
+ {quest.active && ( +
+ )} + +
+ {quest.completed ? ( +
+ +
+ +
+
+ ) : ( + + )} +
+
+ + {quest.name} + + {quest.badge && ( + + + {quest.badge} + + )} +
+ {quest.date && ( +
+ {quest.date} +
+ )} +
+
+
+ {quest.points} pts +
+
+ ))} +
- {/* Achievements Card */} - -

- Achievements -

-
- {achievements.map((achievement, index) => ( - +
+ +
+
+ + +
+
+ {visibleBadges.map((badge) => ( + + {!badge.locked && ( +
+ )} + +
+
+ {!badge.locked && ( +
+ )} + {badge.icon} +
+

+ {badge.name} +

+

+ {badge.date} +

+ {badge.description && ( +

+ {badge.description} +

+ )} +

+ {badge.requirement} +

+
+ + ))}
- - ))} +
+ + +
+ + {/* Dots Indicator */} +
+ {Array.from({ length: badges.length - 2 }).map((_, index) => ( +
+ + {/* Right Column - Profile Settings */} + +
+ +
+
+
+
+ +
+

+ Profile settings +

+
+ + {/* School Nickname */} +
+ + +
+ + {/* Change Password */} +
+ + + + + +
+ + {/* Change Avatar */} +
+ +
+ + +
+
+
+
- {/* Background grid */} + {/* Enhanced Background grid */}
+ +
) } \ No newline at end of file diff --git a/app/(home)/main/progress/page.tsx b/app/(home)/main/progress/page.tsx index 6f78c92..66c168d 100644 --- a/app/(home)/main/progress/page.tsx +++ b/app/(home)/main/progress/page.tsx @@ -2,239 +2,286 @@ import { useState } from "react" import { Card } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { Progress } from "@/components/ui/progress" +import { Input } from "@/components/ui/input" +import { Building2, Trophy, User, Search } from "lucide-react" import Link from "next/link" -import { CheckCircle2, Circle, Clock } from "lucide-react" -export default function ProgressPage() { - const [activeTab, setActiveTab] = useState("progress") +export default function RulesPage() { + const [activeTab, setActiveTab] = useState("rules") + const [searchQuery, setSearchQuery] = useState("") - // Mock data - const courses = [ - { id: 1, name: "React", lessons: 12, completed: 8 }, - { id: 2, name: "TypeScript", lessons: 10, completed: 6 }, - { id: 3, name: "Next.js", lessons: 15, completed: 4 }, - { id: 4, name: "Node.js", lessons: 20, completed: 0 } + // Mock data для рейтингов + const cityLeaderboard = [ + { rank: 1, name: "Moscow", points: 12450 }, + { rank: 2, name: "Kazan", points: 8920 }, + { rank: 3, name: "SPB", points: 7185 }, + { rank: 4, name: "Novosibirsk", points: 5670 }, + { rank: 5, name: "Ekaterinburg", points: 4320 } ] - const assignments = [ - { id: 1, course: "React", name: "Build a Todo App", grade: 95, status: "completed" }, - { id: 2, course: "TypeScript", name: "Type System", grade: 88, status: "completed" }, - { id: 3, course: "Next.js", name: "SSR Project", grade: null, status: "pending" }, - { id: 4, course: "Node.js", name: "REST API", grade: null, status: "not_started" } + const playerLeaderboard = [ + { rank: 1, name: "cyber_god", points: 2840 }, + { rank: 2, name: "h4ck3r_pro", points: 2650 }, + { rank: 3, name: "matrix_neo", points: 2420 }, + { rank: 4, name: "data_wizard", points: 2180 }, + { rank: 5, name: "code_ninja", points: 1950 } ] - const weekActivity = [ - { day: "Mon", hours: 2.5 }, - { day: "Tue", hours: 3.2 }, - { day: "Wed", hours: 1.8 }, - { day: "Thu", hours: 4.1 }, - { day: "Fri", hours: 2.9 }, - { day: "Sat", hours: 3.5 }, - { day: "Sun", hours: 1.2 } + const kazanLeaderboard = [ + { rank: 1, name: "pennytige", points: 1337 }, + { rank: 2, name: "kzn_hacker", points: 1280 }, + { rank: 3, name: "tatar_coder", points: 1150 }, + { rank: 4, name: "crypto_bear", points: 980 }, + { rank: 5, name: "byte_master", points: 875 } ] - const maxHours = Math.max(...weekActivity.map(d => d.hours)) + const allPlayers = [ + { rank: 1, name: "cyber_god", level: 12, points: 2840, city: "Moscow" }, + { rank: 2, name: "h4ck3r_pro", level: 11, points: 2650, city: "SPB" }, + { rank: 3, name: "matrix_neo", level: 10, points: 2420, city: "Kazan" }, + { rank: 15, name: "pennytige", level: 5, points: 1337, city: "Kazan" } + ] + + const filteredPlayers = allPlayers.filter(player => + player.name.toLowerCase().includes(searchQuery.toLowerCase()) + ) + + const getRankColor = (rank: number) => { + if (rank === 1) return "text-yellow-400" + if (rank === 2) return "text-gray-300" + if (rank === 3) return "text-amber-600" + return "text-cyan-400" + } return ( -
+
+ {/* Animated background effects */} +
+
+ {/* Header */} -
+
{/* Main Content */} -
-
- {/* Left Column - Course Progress */} -
- {/* My Courses */} - -

- My courses -

-
- {courses.map((course) => { - const progress = (course.completed / course.lessons) * 100 - return ( - -
-

- {course.name} -

- - {course.completed}/{course.lessons} - -
- -
- ) - })} +
+ {/* Top Leaderboards */} +
+ {/* Топ городов */} + +
+ +
+
+
+ +
+

+ Топ городов +

- - {/* My Grades */} - -

- My grades -

-
- {assignments.slice(0, 3).map((assignment) => ( - + {cityLeaderboard.map((entry) => ( +
-
-
-
- {assignment.course} -
-
- {assignment.name} -
-
- {assignment.grade ? ( -
- {assignment.grade}% -
- ) : ( -
- Pending -
- )} +
+ + #{entry.rank} + + + {entry.name} +
- - ))} -
- - - {/* Mathematics (Separate) */} - -

- Mathematics -

-
- -
-

- Algebra -

- - 8/10 + + {entry.points.toLocaleString()}
- -
+ ))}
-
-
+
+
- {/* Center Column - Assignments Table */} - -

- All Assignments -

+ {/* Топ игроков */} + +
+
+
+
+ +
+

+ Топ игроков +

+
+ +
+ {playerLeaderboard.map((entry) => ( +
+
+ + #{entry.rank} + + + {entry.name} + +
+ + {entry.points.toLocaleString()} + +
+ ))} +
+
+ + + {/* Топ Kazan */} + +
+ +
+
+
+ +
+

+ Топ Kazan +

+
+ +
+ {kazanLeaderboard.map((entry) => ( +
+
+ + #{entry.rank} + + + {entry.name} + +
+ + {entry.points.toLocaleString()} + +
+ ))} +
+
+ +
+ + {/* All Players Table */} + +
+ +
+
+ +

+ Все игроки +

+
+ + {/* Search */} +
+ + setSearchQuery(e.target.value)} + className="pl-12 bg-[#0a0e1a]/80 backdrop-blur border-cyan-500/40 text-cyan-400 placeholder:text-cyan-400/30 font-mono hover:border-cyan-500/60 transition-all focus:border-cyan-400 focus:shadow-[0_0_20px_rgba(6,182,212,0.2)]" + /> +
+ {/* Table */}
- - + - - - - - {assignments.map((assignment, index) => ( + {filteredPlayers.map((player) => ( - - - - - ))} @@ -242,41 +289,24 @@ export default function ProgressPage() {
- # +
+ Ранг - Course + + Игрок - Assignment + + Уровень - Grade + + Очки - Status + + Город
- {index + 1} + + + #{player.rank} + - {assignment.course} + + + {player.name} + - {assignment.name} + + + Lvl {player.level} + - {assignment.grade ? `${assignment.grade}%` : '-'} + + + {player.points.toLocaleString()} + -
- {assignment.status === 'completed' ? ( - <> - - - Completed - - - ) : assignment.status === 'pending' ? ( - <> - - - Pending - - - ) : ( - <> - - - Not Started - - - )} -
+
+ + {player.city} +
- {/* Weekly Activity Chart */} -
-

- Weekly Activity -

-
- {weekActivity.map((day) => ( -
-
-
-
-
- {day.day} -
-
- {day.hours}h -
-
- ))} + {filteredPlayers.length === 0 && ( +
+

+ Игрок не найден +

-
- -
+ )} +
+
- {/* Background grid */} + {/* Enhanced Background grid */}
- +