316 lines
14 KiB
TypeScript
316 lines
14 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from "react"
|
||
import { Card } from "@/components/ui/card"
|
||
import { Input } from "@/components/ui/input"
|
||
import { Building2, Trophy, User, Search } from "lucide-react"
|
||
import Link from "next/link"
|
||
|
||
export default function RulesPage() {
|
||
const [activeTab, setActiveTab] = useState("rules")
|
||
const [searchQuery, setSearchQuery] = useState("")
|
||
|
||
// 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 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 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 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 (
|
||
<div className="min-h-screen bg-[#0a0e1a] relative overflow-hidden">
|
||
{/* Animated background effects */}
|
||
<div className="fixed top-20 left-20 w-96 h-96 bg-cyan-500/5 rounded-full blur-[120px] animate-pulse" />
|
||
<div className="fixed bottom-20 right-20 w-96 h-96 bg-purple-500/5 rounded-full blur-[120px] animate-pulse" style={{ animationDelay: '1s' }} />
|
||
|
||
{/* Header */}
|
||
<header className="bg-[#0d1117]/80 backdrop-blur-xl border-b border-cyan-500/30 sticky top-0 z-50 shadow-lg shadow-cyan-500/5">
|
||
<nav className="container mx-auto px-6 py-4">
|
||
<div className="flex items-center justify-center">
|
||
<div className="flex items-center gap-12">
|
||
<Link href="/main">
|
||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80 hover:scale-105">
|
||
Main
|
||
</button>
|
||
</Link>
|
||
<Link href="/main/progress">
|
||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80 hover:scale-105">
|
||
Progress
|
||
</button>
|
||
</Link>
|
||
<Link href="/main/profile">
|
||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80 hover:scale-105">
|
||
Profile
|
||
</button>
|
||
</Link>
|
||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-400 scale-110 drop-shadow-[0_0_8px_rgba(6,182,212,0.5)]">
|
||
Rules
|
||
</button>
|
||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80 hover:scale-105">
|
||
Logoff
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
</header>
|
||
|
||
{/* Main Content */}
|
||
<main className="container mx-auto px-6 py-8 max-w-7xl relative z-10">
|
||
{/* Top Leaderboards */}
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
|
||
{/* Топ городов */}
|
||
<Card className="bg-[#0d1117]/50 backdrop-blur-xl border-2 border-cyan-500/30 p-6 shadow-[0_0_30px_rgba(6,182,212,0.1)] hover:shadow-[0_0_50px_rgba(6,182,212,0.2)] transition-all duration-300 relative overflow-hidden group">
|
||
<div className="absolute inset-0 bg-gradient-to-br from-cyan-500/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
|
||
|
||
<div className="relative z-10">
|
||
<div className="flex items-center gap-3 mb-4">
|
||
<div className="w-10 h-10 bg-cyan-500/20 rounded-lg flex items-center justify-center">
|
||
<Building2 className="w-5 h-5 text-cyan-400" />
|
||
</div>
|
||
<h3 className="text-lg font-bold text-cyan-400 font-mono">
|
||
Топ городов
|
||
</h3>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
{cityLeaderboard.map((entry) => (
|
||
<div
|
||
key={entry.rank}
|
||
className="flex items-center justify-between p-3 bg-[#0a0e1a]/80 rounded-lg border border-cyan-500/20 hover:border-cyan-500/40 transition-all group/item"
|
||
>
|
||
<div className="flex items-center gap-3">
|
||
<span className={`font-bold font-mono text-sm w-8 ${getRankColor(entry.rank)}`}>
|
||
#{entry.rank}
|
||
</span>
|
||
<span className="text-cyan-400 font-mono text-sm">
|
||
{entry.name}
|
||
</span>
|
||
</div>
|
||
<span className="text-green-400 font-mono font-bold text-sm">
|
||
{entry.points.toLocaleString()}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Топ игроков */}
|
||
<Card className="bg-[#0d1117]/50 backdrop-blur-xl border-2 border-yellow-500/30 p-6 shadow-[0_0_30px_rgba(234,179,8,0.1)] hover:shadow-[0_0_50px_rgba(234,179,8,0.2)] transition-all duration-300 relative overflow-hidden group">
|
||
<div className="absolute inset-0 bg-gradient-to-br from-yellow-500/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
|
||
|
||
<div className="relative z-10">
|
||
<div className="flex items-center gap-3 mb-4">
|
||
<div className="w-10 h-10 bg-yellow-500/20 rounded-lg flex items-center justify-center">
|
||
<Trophy className="w-5 h-5 text-yellow-400" />
|
||
</div>
|
||
<h3 className="text-lg font-bold text-yellow-400 font-mono">
|
||
Топ игроков
|
||
</h3>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
{playerLeaderboard.map((entry) => (
|
||
<div
|
||
key={entry.rank}
|
||
className="flex items-center justify-between p-3 bg-[#0a0e1a]/80 rounded-lg border border-yellow-500/20 hover:border-yellow-500/40 transition-all group/item"
|
||
>
|
||
<div className="flex items-center gap-3">
|
||
<span className={`font-bold font-mono text-sm w-8 ${getRankColor(entry.rank)}`}>
|
||
#{entry.rank}
|
||
</span>
|
||
<span className="text-cyan-400 font-mono text-sm">
|
||
{entry.name}
|
||
</span>
|
||
</div>
|
||
<span className="text-green-400 font-mono font-bold text-sm">
|
||
{entry.points.toLocaleString()}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Топ Kazan */}
|
||
<Card className="bg-[#0d1117]/50 backdrop-blur-xl border-2 border-cyan-500/30 p-6 shadow-[0_0_30px_rgba(6,182,212,0.1)] hover:shadow-[0_0_50px_rgba(6,182,212,0.2)] transition-all duration-300 relative overflow-hidden group">
|
||
<div className="absolute inset-0 bg-gradient-to-br from-cyan-500/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
|
||
|
||
<div className="relative z-10">
|
||
<div className="flex items-center gap-3 mb-4">
|
||
<div className="w-10 h-10 bg-cyan-500/20 rounded-lg flex items-center justify-center">
|
||
<User className="w-5 h-5 text-cyan-400" />
|
||
</div>
|
||
<h3 className="text-lg font-bold text-cyan-400 font-mono">
|
||
Топ Kazan
|
||
</h3>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
{kazanLeaderboard.map((entry) => (
|
||
<div
|
||
key={entry.rank}
|
||
className="flex items-center justify-between p-3 bg-[#0a0e1a]/80 rounded-lg border border-cyan-500/20 hover:border-cyan-500/40 transition-all group/item"
|
||
>
|
||
<div className="flex items-center gap-3">
|
||
<span className={`font-bold font-mono text-sm w-8 ${getRankColor(entry.rank)}`}>
|
||
#{entry.rank}
|
||
</span>
|
||
<span className="text-cyan-400 font-mono text-sm">
|
||
{entry.name}
|
||
</span>
|
||
</div>
|
||
<span className="text-green-400 font-mono font-bold text-sm">
|
||
{entry.points.toLocaleString()}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
</div>
|
||
|
||
{/* All Players Table */}
|
||
<Card className="bg-[#0d1117]/50 backdrop-blur-xl border-2 border-cyan-500/30 p-6 shadow-[0_0_30px_rgba(6,182,212,0.1)] hover:shadow-[0_0_50px_rgba(6,182,212,0.2)] transition-all duration-300 relative overflow-hidden group">
|
||
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-cyan-500/10 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000" />
|
||
|
||
<div className="relative z-10">
|
||
<div className="flex items-center gap-3 mb-6">
|
||
<Trophy className="w-6 h-6 text-cyan-400 animate-pulse" />
|
||
<h3 className="text-xl font-bold text-cyan-400 font-mono">
|
||
Все игроки
|
||
</h3>
|
||
</div>
|
||
|
||
{/* Search */}
|
||
<div className="mb-6 relative">
|
||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-cyan-400/50" />
|
||
<Input
|
||
type="text"
|
||
placeholder="Поиск игрока..."
|
||
value={searchQuery}
|
||
onChange={(e) => 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)]"
|
||
/>
|
||
</div>
|
||
|
||
{/* Table */}
|
||
<div className="overflow-x-auto">
|
||
<table className="w-full">
|
||
<thead>
|
||
<tr className="border-b border-cyan-500/30">
|
||
<th className="text-left py-4 px-4 text-sm font-mono text-cyan-400/60 uppercase">
|
||
Ранг
|
||
</th>
|
||
<th className="text-left py-4 px-4 text-sm font-mono text-cyan-400/60 uppercase">
|
||
Игрок
|
||
</th>
|
||
<th className="text-left py-4 px-4 text-sm font-mono text-cyan-400/60 uppercase">
|
||
Уровень
|
||
</th>
|
||
<th className="text-left py-4 px-4 text-sm font-mono text-cyan-400/60 uppercase">
|
||
Очки
|
||
</th>
|
||
<th className="text-left py-4 px-4 text-sm font-mono text-cyan-400/60 uppercase">
|
||
Город
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{filteredPlayers.map((player) => (
|
||
<tr
|
||
key={player.rank}
|
||
className="border-b border-cyan-500/10 hover:bg-cyan-500/5 transition-all group/row"
|
||
>
|
||
<td className="py-4 px-4">
|
||
<span className={`font-bold font-mono text-sm ${getRankColor(player.rank)}`}>
|
||
#{player.rank}
|
||
</span>
|
||
</td>
|
||
<td className="py-4 px-4">
|
||
<span className="text-cyan-400 font-mono text-sm group-hover/row:text-cyan-300 transition-colors">
|
||
{player.name}
|
||
</span>
|
||
</td>
|
||
<td className="py-4 px-4">
|
||
<span className="text-cyan-400 font-mono text-sm">
|
||
Lvl {player.level}
|
||
</span>
|
||
</td>
|
||
<td className="py-4 px-4">
|
||
<span className="text-green-400 font-mono font-bold text-sm">
|
||
{player.points.toLocaleString()}
|
||
</span>
|
||
</td>
|
||
<td className="py-4 px-4">
|
||
<span className="text-cyan-400/70 font-mono text-sm">
|
||
{player.city}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
))}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
{filteredPlayers.length === 0 && (
|
||
<div className="text-center py-12">
|
||
<p className="text-cyan-400/50 font-mono">
|
||
Игрок не найден
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</Card>
|
||
</main>
|
||
|
||
{/* Enhanced Background grid */}
|
||
<div
|
||
className="fixed inset-0 pointer-events-none -z-10 opacity-50"
|
||
style={{
|
||
backgroundImage: `
|
||
linear-gradient(rgba(6, 182, 212, 0.05) 1px, transparent 1px),
|
||
linear-gradient(90deg, rgba(6, 182, 212, 0.05) 1px, transparent 1px)
|
||
`,
|
||
backgroundSize: '50px 50px'
|
||
}}
|
||
/>
|
||
</div>
|
||
)
|
||
} |