411 lines
18 KiB
TypeScript
411 lines
18 KiB
TypeScript
"use client"
|
||
|
||
import { useState, useEffect, useRef } from "react"
|
||
import { Card } from "@/components/ui/card"
|
||
import { Button } from "@/components/ui/button"
|
||
import Link from "next/link"
|
||
import {
|
||
MessageCircle,
|
||
X,
|
||
Sparkles,
|
||
Shield,
|
||
Zap,
|
||
CheckCircle,
|
||
ArrowRight,
|
||
Info
|
||
} from "lucide-react"
|
||
|
||
interface Particle {
|
||
x: number
|
||
y: number
|
||
vx: number
|
||
vy: number
|
||
size: number
|
||
opacity: number
|
||
color: string
|
||
}
|
||
|
||
export default function RegisterPage() {
|
||
const [showModal, setShowModal] = useState(false)
|
||
const [particles, setParticles] = useState<Particle[]>([])
|
||
const [mousePos, setMousePos] = useState({ x: 0, y: 0 })
|
||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
||
|
||
const telegramBotUrl = "https://t.me/School21AnonimousGame_bot"
|
||
|
||
// Initialize particles
|
||
useEffect(() => {
|
||
const initParticles: Particle[] = []
|
||
const colors = ['#06b6d4', '#0ea5e9', '#3b82f6', '#8b5cf6']
|
||
for (let i = 0; i < 50; i++) {
|
||
initParticles.push({
|
||
x: Math.random() * (typeof window !== 'undefined' ? window.innerWidth : 1920),
|
||
y: Math.random() * (typeof window !== 'undefined' ? window.innerHeight : 1080),
|
||
vx: (Math.random() - 0.5) * 0.5,
|
||
vy: (Math.random() - 0.5) * 0.5,
|
||
size: Math.random() * 2 + 1,
|
||
opacity: Math.random() * 0.4 + 0.2,
|
||
color: colors[Math.floor(Math.random() * colors.length)]
|
||
})
|
||
}
|
||
setParticles(initParticles)
|
||
}, [])
|
||
|
||
// Animate particles
|
||
useEffect(() => {
|
||
const canvas = canvasRef.current
|
||
if (!canvas) return
|
||
|
||
const ctx = canvas.getContext('2d')
|
||
if (!ctx) return
|
||
|
||
const updateCanvasSize = () => {
|
||
canvas.width = window.innerWidth
|
||
canvas.height = window.innerHeight
|
||
}
|
||
updateCanvasSize()
|
||
|
||
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))
|
||
|
||
ctx.shadowBlur = 8
|
||
ctx.shadowColor = particle.color
|
||
ctx.fillStyle = `${particle.color}${Math.floor(particle.opacity * 255).toString(16).padStart(2, '0')}`
|
||
ctx.beginPath()
|
||
ctx.arc(newX, newY, particle.size, 0, Math.PI * 2)
|
||
ctx.fill()
|
||
|
||
return { ...particle, x: newX, y: newY }
|
||
})
|
||
})
|
||
|
||
animationFrameId = requestAnimationFrame(animate)
|
||
}
|
||
|
||
animate()
|
||
|
||
window.addEventListener('resize', updateCanvasSize)
|
||
return () => {
|
||
cancelAnimationFrame(animationFrameId)
|
||
window.removeEventListener('resize', updateCanvasSize)
|
||
}
|
||
}, [])
|
||
|
||
// Mouse parallax
|
||
useEffect(() => {
|
||
const handleMouseMove = (e: MouseEvent) => {
|
||
setMousePos({ x: e.clientX, y: e.clientY })
|
||
}
|
||
window.addEventListener('mousemove', handleMouseMove)
|
||
return () => window.removeEventListener('mousemove', handleMouseMove)
|
||
}, [])
|
||
|
||
const handleTelegramClick = () => {
|
||
setShowModal(true)
|
||
setTimeout(() => {
|
||
window.open(telegramBotUrl, '_blank')
|
||
}, 500)
|
||
}
|
||
|
||
return (
|
||
<div className="min-h-screen bg-[#0a0e1a] flex items-center justify-center p-6 relative overflow-hidden">
|
||
{/* Animated particles canvas */}
|
||
<canvas
|
||
ref={canvasRef}
|
||
className="fixed inset-0 pointer-events-none z-0"
|
||
style={{ opacity: 0.6 }}
|
||
/>
|
||
|
||
{/* Background grid */}
|
||
<div
|
||
className="fixed inset-0 pointer-events-none -z-10 opacity-40"
|
||
style={{
|
||
backgroundImage: `
|
||
linear-gradient(rgba(6, 182, 212, 0.08) 1px, transparent 1px),
|
||
linear-gradient(90deg, rgba(6, 182, 212, 0.08) 1px, transparent 1px)
|
||
`,
|
||
backgroundSize: '60px 60px'
|
||
}}
|
||
/>
|
||
|
||
{/* Glowing effects */}
|
||
<div
|
||
className="fixed w-[500px] h-[500px] bg-cyan-500/15 rounded-full blur-[150px] animate-pulse transition-transform duration-1000"
|
||
style={{
|
||
top: '10%',
|
||
left: '20%',
|
||
transform: `translate(${(mousePos.x - (typeof window !== 'undefined' ? window.innerWidth : 1920) / 2) * 0.02}px, ${(mousePos.y - (typeof window !== 'undefined' ? window.innerHeight : 1080) / 2) * 0.02}px)`
|
||
}}
|
||
/>
|
||
<div
|
||
className="fixed w-[500px] h-[500px] bg-blue-500/15 rounded-full blur-[150px] animate-pulse transition-transform duration-1000"
|
||
style={{
|
||
bottom: '10%',
|
||
right: '20%',
|
||
animationDelay: '1s',
|
||
transform: `translate(${-(mousePos.x - (typeof window !== 'undefined' ? window.innerWidth : 1920) / 2) * 0.02}px, ${-(mousePos.y - (typeof window !== 'undefined' ? window.innerHeight : 1080) / 2) * 0.02}px)`
|
||
}}
|
||
/>
|
||
|
||
<Card className="w-full max-w-md bg-[#0d1117]/80 backdrop-blur-xl border-2 border-cyan-500/40 shadow-[0_0_60px_rgba(6,182,212,0.3)] relative overflow-hidden z-10">
|
||
{/* Animated top accent line */}
|
||
<div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-transparent via-cyan-400 to-transparent animate-shimmer" />
|
||
|
||
{/* Animated corner glow */}
|
||
<div className="absolute inset-0 bg-gradient-to-br from-cyan-500/5 via-transparent to-blue-500/5 opacity-50" />
|
||
|
||
<div className="p-8 relative z-10">
|
||
{/* Header */}
|
||
<div className="text-center mb-8">
|
||
<div className="w-20 h-20 bg-gradient-to-br from-cyan-500/30 via-blue-500/30 to-purple-500/30 rounded-2xl flex items-center justify-center mx-auto mb-4 border-2 border-cyan-500/40 shadow-[0_0_30px_rgba(6,182,212,0.3)] relative overflow-hidden group">
|
||
<div className="absolute inset-0 bg-gradient-to-br from-cyan-400/20 to-blue-400/20 animate-pulse" />
|
||
<Sparkles className="w-10 h-10 text-cyan-400 relative z-10 drop-shadow-[0_0_10px_rgba(6,182,212,0.8)] animate-pulse" />
|
||
</div>
|
||
<h1 className="text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-blue-400 to-cyan-400 font-mono mb-2 animate-gradient">
|
||
Registration
|
||
</h1>
|
||
<p className="text-cyan-400/60 font-mono text-sm">
|
||
Join the Cyber Academy
|
||
</p>
|
||
</div>
|
||
|
||
{/* Info Block */}
|
||
<div className="mb-6 p-4 bg-gradient-to-r from-cyan-500/10 to-blue-500/10 border border-cyan-500/30 rounded-xl">
|
||
<div className="flex items-start gap-3">
|
||
<div className="w-8 h-8 bg-cyan-500/20 rounded-lg flex items-center justify-center flex-shrink-0 mt-0.5">
|
||
<Info className="w-4 h-4 text-cyan-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-cyan-400 font-mono text-sm leading-relaxed">
|
||
Регистрация проходит через нашего <span className="font-bold text-cyan-300">Telegram бота</span>.
|
||
Нажмите кнопку ниже для начала регистрации.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Features List */}
|
||
<div className="mb-6 space-y-3">
|
||
{[
|
||
{ icon: Zap, text: "Быстрая регистрация", color: "blue" },
|
||
{ icon: CheckCircle, text: "Мгновенный доступ", color: "purple" }
|
||
].map((feature, index) => (
|
||
<div
|
||
key={index}
|
||
className="flex items-center gap-3 p-3 bg-[#0a0e1a]/50 border border-cyan-500/20 rounded-lg hover:border-cyan-500/40 transition-all cursor-pointer hover:scale-[1.02] group"
|
||
style={{ animationDelay: `${index * 0.1}s` }}
|
||
>
|
||
<div className={`w-10 h-10 bg-gradient-to-br from-${feature.color}-500/20 to-${feature.color}-600/20 rounded-lg flex items-center justify-center border border-${feature.color}-500/30 group-hover:scale-110 transition-transform`}>
|
||
<feature.icon className={`w-5 h-5 text-${feature.color}-400`} />
|
||
</div>
|
||
<span className="text-cyan-400/80 font-mono text-sm group-hover:text-cyan-300 transition-colors">
|
||
{feature.text}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Telegram Registration Button */}
|
||
<Button
|
||
onClick={handleTelegramClick}
|
||
className="w-full bg-gradient-to-r from-cyan-500 to-blue-500 hover:from-cyan-400 hover:to-blue-400 text-white font-bold font-mono tracking-wider py-6 text-base shadow-[0_0_40px_rgba(6,182,212,0.4)] hover:shadow-[0_0_60px_rgba(6,182,212,0.6)] transition-all hover:scale-105 active:scale-95 cursor-pointer relative overflow-hidden group"
|
||
>
|
||
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000" />
|
||
<div className="relative z-10 flex items-center justify-center gap-3">
|
||
<MessageCircle className="w-5 h-5" />
|
||
<span>REGISTER VIA TELEGRAM</span>
|
||
<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
|
||
</div>
|
||
</Button>
|
||
|
||
{/* Telegram Bot Username */}
|
||
<div className="mt-4 text-center">
|
||
<p className="text-cyan-400/50 font-mono text-xs mb-2">Telegram Bot:</p>
|
||
<a
|
||
href={telegramBotUrl}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-2 text-cyan-400 hover:text-cyan-300 font-mono text-sm font-bold transition-colors cursor-pointer hover:scale-105"
|
||
>
|
||
<MessageCircle className="w-4 h-4" />
|
||
@School21AnonimousGame_bot
|
||
</a>
|
||
</div>
|
||
|
||
{/* Footer Links */}
|
||
<div className="mt-8 text-center space-y-4">
|
||
<div className="relative">
|
||
<div className="absolute inset-0 flex items-center">
|
||
<div className="w-full border-t border-cyan-500/20"></div>
|
||
</div>
|
||
<div className="relative flex justify-center text-xs">
|
||
<span className="bg-[#0d1117] px-4 text-cyan-400/40 font-mono">
|
||
OR
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<p className="text-cyan-400/60 font-mono text-sm">
|
||
Already have an account?{" "}
|
||
<Link
|
||
href="/login"
|
||
className="text-cyan-400 hover:text-cyan-300 font-bold transition-colors cursor-pointer"
|
||
>
|
||
Login
|
||
</Link>
|
||
</p>
|
||
|
||
<Link
|
||
href="/"
|
||
className="inline-block text-cyan-400/50 hover:text-cyan-400 font-mono text-xs transition-colors cursor-pointer"
|
||
>
|
||
← Back to home
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Enhanced corner decorations */}
|
||
<div className="absolute top-2 left-2 w-6 h-6 border-t-2 border-l-2 border-cyan-500/40 rounded-tl-sm"></div>
|
||
<div className="absolute top-2 right-2 w-6 h-6 border-t-2 border-r-2 border-cyan-500/40 rounded-tr-sm"></div>
|
||
<div className="absolute bottom-2 left-2 w-6 h-6 border-b-2 border-l-2 border-cyan-500/40 rounded-bl-sm"></div>
|
||
<div className="absolute bottom-2 right-2 w-6 h-6 border-b-2 border-r-2 border-cyan-500/40 rounded-br-sm"></div>
|
||
</Card>
|
||
|
||
{/* Modal */}
|
||
{showModal && (
|
||
<div className="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center p-6 z-50 animate-in fade-in duration-300">
|
||
<Card className="w-full max-w-lg bg-[#0d1117]/95 backdrop-blur-xl border-2 border-cyan-500/40 shadow-[0_0_80px_rgba(6,182,212,0.4)] relative overflow-hidden animate-in zoom-in-95 duration-300">
|
||
{/* Animated top accent */}
|
||
<div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-transparent via-cyan-400 to-transparent animate-shimmer" />
|
||
|
||
{/* Close button */}
|
||
<button
|
||
onClick={() => setShowModal(false)}
|
||
className="absolute top-4 right-4 w-10 h-10 bg-red-500/20 hover:bg-red-500/30 rounded-lg flex items-center justify-center transition-all border border-red-500/40 hover:border-red-500/60 cursor-pointer hover:scale-110 active:scale-95 z-10"
|
||
>
|
||
<X className="w-5 h-5 text-red-400" />
|
||
</button>
|
||
|
||
<div className="p-8">
|
||
{/* Icon */}
|
||
<div className="w-20 h-20 bg-gradient-to-br from-cyan-500/30 via-blue-500/30 to-purple-500/30 rounded-2xl flex items-center justify-center mx-auto mb-6 border-2 border-cyan-500/40 shadow-[0_0_40px_rgba(6,182,212,0.4)] relative overflow-hidden">
|
||
<div className="absolute inset-0 bg-gradient-to-br from-cyan-400/20 to-blue-400/20 animate-pulse" />
|
||
<MessageCircle className="w-10 h-10 text-cyan-400 relative z-10 drop-shadow-[0_0_15px_rgba(6,182,212,1)] animate-pulse" />
|
||
</div>
|
||
|
||
{/* Title */}
|
||
<h2 className="text-2xl font-bold text-center text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-blue-400 to-cyan-400 font-mono mb-4 animate-gradient">
|
||
Регистрация через Telegram
|
||
</h2>
|
||
|
||
{/* Content */}
|
||
<div className="space-y-4 mb-6">
|
||
<p className="text-cyan-400/80 font-mono text-sm text-center leading-relaxed">
|
||
Вы будете перенаправлены на нашего <span className="font-bold text-cyan-300">Telegram бота</span>.
|
||
</p>
|
||
|
||
<div className="bg-gradient-to-r from-cyan-500/10 to-blue-500/10 border border-cyan-500/30 rounded-xl p-4">
|
||
<div className="flex items-center gap-3 mb-3">
|
||
<div className="w-8 h-8 bg-cyan-500/20 rounded-lg flex items-center justify-center">
|
||
<Shield className="w-4 h-4 text-cyan-400" />
|
||
</div>
|
||
<span className="text-cyan-400 font-mono text-sm font-bold">Что нужно сделать:</span>
|
||
</div>
|
||
<ol className="space-y-2 text-cyan-400/70 font-mono text-sm ml-11">
|
||
<li className="flex items-start gap-2">
|
||
<span className="text-cyan-400 font-bold">1.</span>
|
||
<span>Откройте бота в Telegram</span>
|
||
</li>
|
||
<li className="flex items-start gap-2">
|
||
<span className="text-cyan-400 font-bold">2.</span>
|
||
<span>Нажмите "Start" или "/start"</span>
|
||
</li>
|
||
<li className="flex items-start gap-2">
|
||
<span className="text-cyan-400 font-bold">3.</span>
|
||
<span>Следуйте инструкциям бота</span>
|
||
</li>
|
||
<li className="flex items-start gap-2">
|
||
<span className="text-cyan-400 font-bold">4.</span>
|
||
<span>Получите данные для входа</span>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
|
||
{/* Bot username display */}
|
||
<div className="flex items-center justify-center gap-2 p-4 bg-[#0a0e1a]/80 border border-cyan-500/30 rounded-xl">
|
||
<MessageCircle className="w-5 h-5 text-cyan-400" />
|
||
<a
|
||
href={telegramBotUrl}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="text-cyan-400 hover:text-cyan-300 font-mono font-bold transition-colors cursor-pointer"
|
||
>
|
||
@School21AnonimousGame_bot
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Buttons */}
|
||
<div className="flex gap-3">
|
||
<Button
|
||
onClick={() => setShowModal(false)}
|
||
variant="outline"
|
||
className="flex-1 bg-[#0a0e1a] border-cyan-500/40 text-cyan-400 hover:bg-cyan-500/10 hover:border-cyan-400/60 font-mono font-bold transition-all cursor-pointer"
|
||
>
|
||
Close
|
||
</Button>
|
||
<Button
|
||
onClick={() => window.open(telegramBotUrl, '_blank')}
|
||
className="flex-1 bg-gradient-to-r from-cyan-500 to-blue-500 hover:from-cyan-400 hover:to-blue-400 text-white font-bold font-mono shadow-[0_0_30px_rgba(6,182,212,0.4)] hover:shadow-[0_0_50px_rgba(6,182,212,0.6)] transition-all hover:scale-105 active:scale-95 cursor-pointer relative overflow-hidden group"
|
||
>
|
||
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000" />
|
||
<span className="relative z-10 flex items-center gap-2">
|
||
Open Bot
|
||
<ArrowRight className="w-4 h-4" />
|
||
</span>
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Corner decorations */}
|
||
<div className="absolute top-2 left-2 w-6 h-6 border-t-2 border-l-2 border-cyan-500/40 rounded-tl-sm"></div>
|
||
<div className="absolute top-2 right-2 w-6 h-6 border-t-2 border-r-2 border-cyan-500/40 rounded-tr-sm"></div>
|
||
<div className="absolute bottom-2 left-2 w-6 h-6 border-b-2 border-l-2 border-cyan-500/40 rounded-bl-sm"></div>
|
||
<div className="absolute bottom-2 right-2 w-6 h-6 border-b-2 border-r-2 border-cyan-500/40 rounded-br-sm"></div>
|
||
</Card>
|
||
</div>
|
||
)}
|
||
|
||
<style jsx>{`
|
||
@keyframes shimmer {
|
||
0% { transform: translateX(-100%); }
|
||
100% { transform: translateX(100%); }
|
||
}
|
||
.animate-shimmer {
|
||
animation: shimmer 3s infinite;
|
||
}
|
||
@keyframes gradient {
|
||
0%, 100% { background-position: 0% 50%; }
|
||
50% { background-position: 100% 50%; }
|
||
}
|
||
.animate-gradient {
|
||
background-size: 200% 200%;
|
||
animation: gradient 3s ease infinite;
|
||
}
|
||
`}</style>
|
||
</div>
|
||
)
|
||
} |