This commit is contained in:
2025-12-17 14:53:56 +07:00
parent 332491454d
commit debdd66458
22 changed files with 853 additions and 310 deletions

View File

@@ -5,8 +5,8 @@ import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { useAuthStore } from '@/store/auth'
import { marathonsApi } from '@/api'
import { NeonButton, Input } from '@/components/ui'
import { Gamepad2, UserPlus, AlertCircle } from 'lucide-react'
import { NeonButton, Input, GlassCard } from '@/components/ui'
import { Gamepad2, UserPlus, AlertCircle, Trophy, Users, Zap, Target, Sparkles } from 'lucide-react'
const registerSchema = z.object({
login: z
@@ -68,99 +68,172 @@ export function RegisterPage() {
}
}
const features = [
{ icon: <Trophy className="w-5 h-5" />, text: 'Соревнуйтесь с друзьями' },
{ icon: <Target className="w-5 h-5" />, text: 'Выполняйте челленджи' },
{ icon: <Zap className="w-5 h-5" />, text: 'Зарабатывайте очки' },
{ icon: <Users className="w-5 h-5" />, text: 'Создавайте марафоны' },
]
return (
<div className="min-h-[80vh] flex items-center justify-center px-4 -mt-8">
<div className="min-h-[80vh] flex items-center justify-center px-4 py-8">
{/* Background effects */}
<div className="fixed inset-0 overflow-hidden pointer-events-none">
<div className="absolute top-1/3 -right-32 w-96 h-96 bg-accent-500/10 rounded-full blur-[100px]" />
<div className="absolute bottom-1/3 -left-32 w-96 h-96 bg-neon-500/10 rounded-full blur-[100px]" />
</div>
<div className="relative w-full max-w-md">
{/* Card */}
<div className="glass-neon rounded-2xl p-8 animate-scale-in">
{/* Header */}
<div className="text-center mb-8">
<div className="flex justify-center mb-4">
<div className="w-16 h-16 rounded-2xl bg-accent-500/10 border border-accent-500/30 flex items-center justify-center">
<Gamepad2 className="w-8 h-8 text-accent-500" />
{/* Bento Grid */}
<div className="relative w-full max-w-4xl">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 animate-scale-in">
{/* Branding Block (left) */}
<GlassCard className="p-8 flex flex-col justify-center relative overflow-hidden order-2 md:order-1" variant="neon">
{/* Background decoration */}
<div className="absolute inset-0 overflow-hidden pointer-events-none">
<div className="absolute -top-20 -left-20 w-48 h-48 bg-accent-500/20 rounded-full blur-[60px]" />
<div className="absolute -bottom-20 -right-20 w-48 h-48 bg-neon-500/20 rounded-full blur-[60px]" />
</div>
<div className="relative">
{/* Logo */}
<div className="flex justify-center md:justify-start mb-6">
<div className="w-20 h-20 rounded-2xl bg-accent-500/10 border border-accent-500/30 flex items-center justify-center shadow-[0_0_40px_rgba(147,51,234,0.3)]">
<Gamepad2 className="w-10 h-10 text-accent-500" />
</div>
</div>
{/* Title */}
<h1 className="text-3xl md:text-4xl font-bold text-white mb-2 text-center md:text-left">
Game Marathon
</h1>
<p className="text-gray-400 mb-6 text-center md:text-left">
Присоединяйтесь к игровому сообществу
</p>
{/* Benefits */}
<div className="p-4 rounded-xl bg-dark-700/50 border border-dark-600 mb-6">
<div className="flex items-center gap-2 mb-3">
<Sparkles className="w-5 h-5 text-accent-400" />
<span className="text-white font-semibold">Что вас ждет:</span>
</div>
<ul className="space-y-2 text-sm text-gray-400">
<li className="flex items-center gap-2">
<span className="w-1.5 h-1.5 rounded-full bg-neon-500" />
Создавайте игровые марафоны
</li>
<li className="flex items-center gap-2">
<span className="w-1.5 h-1.5 rounded-full bg-accent-500" />
Выполняйте уникальные челленджи
</li>
<li className="flex items-center gap-2">
<span className="w-1.5 h-1.5 rounded-full bg-pink-500" />
Соревнуйтесь за первое место
</li>
</ul>
</div>
{/* Features */}
<div className="grid grid-cols-2 gap-3">
{features.map((feature, index) => (
<div
key={index}
className="flex items-center gap-2 p-3 rounded-xl bg-dark-700/50 border border-dark-600"
>
<div className="w-8 h-8 rounded-lg bg-accent-500/20 flex items-center justify-center text-accent-400">
{feature.icon}
</div>
<span className="text-sm text-gray-300">{feature.text}</span>
</div>
))}
</div>
</div>
<h1 className="text-2xl font-bold text-white mb-2">Создать аккаунт</h1>
<p className="text-gray-400">Присоединяйтесь к игровому марафону</p>
</div>
</GlassCard>
{/* Form */}
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
{(submitError || error) && (
<div className="flex items-center gap-3 p-4 bg-red-500/10 border border-red-500/30 rounded-xl text-red-400 text-sm animate-shake">
<AlertCircle className="w-5 h-5 flex-shrink-0" />
<span>{submitError || error}</span>
{/* Form Block (right) */}
<GlassCard className="p-8 order-1 md:order-2">
{/* Header */}
<div className="text-center mb-6">
<div className="flex justify-center mb-4 md:hidden">
<div className="w-16 h-16 rounded-2xl bg-accent-500/10 border border-accent-500/30 flex items-center justify-center">
<Gamepad2 className="w-8 h-8 text-accent-500" />
</div>
</div>
)}
<h2 className="text-2xl font-bold text-white mb-2">Создать аккаунт</h2>
<p className="text-gray-400">Начните играть уже сегодня</p>
</div>
<Input
label="Логин"
placeholder="Придумайте логин"
error={errors.login?.message}
autoComplete="username"
{...register('login')}
/>
{/* Form */}
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
{(submitError || error) && (
<div className="flex items-center gap-3 p-4 bg-red-500/10 border border-red-500/30 rounded-xl text-red-400 text-sm animate-shake">
<AlertCircle className="w-5 h-5 flex-shrink-0" />
<span>{submitError || error}</span>
</div>
)}
<Input
label="Никнейм"
placeholder="Как вас называть?"
error={errors.nickname?.message}
{...register('nickname')}
/>
<Input
label="Логин"
placeholder="Придумайте логин"
error={errors.login?.message}
autoComplete="username"
{...register('login')}
/>
<Input
label="Пароль"
type="password"
placeholder="Придумайте пароль"
error={errors.password?.message}
autoComplete="new-password"
{...register('password')}
/>
<Input
label="Никнейм"
placeholder="Как вас называть?"
error={errors.nickname?.message}
{...register('nickname')}
/>
<Input
label=одтвердите пароль"
type="password"
placeholder=овторите пароль"
error={errors.confirmPassword?.message}
autoComplete="new-password"
{...register('confirmPassword')}
/>
<Input
label="Пароль"
type="password"
placeholder="Придумайте пароль"
error={errors.password?.message}
autoComplete="new-password"
{...register('password')}
/>
<NeonButton
type="submit"
className="w-full"
size="lg"
color="purple"
isLoading={isLoading}
icon={<UserPlus className="w-5 h-5" />}
>
Зарегистрироваться
</NeonButton>
</form>
<Input
label="Подтвердите пароль"
type="password"
placeholder="Повторите пароль"
error={errors.confirmPassword?.message}
autoComplete="new-password"
{...register('confirmPassword')}
/>
{/* Footer */}
<div className="mt-6 pt-6 border-t border-dark-600 text-center">
<p className="text-gray-400 text-sm">
Уже есть аккаунт?{' '}
<Link
to="/login"
className="text-accent-400 hover:text-accent-300 transition-colors font-medium"
<NeonButton
type="submit"
className="w-full"
size="lg"
color="purple"
isLoading={isLoading}
icon={<UserPlus className="w-5 h-5" />}
>
Войти
</Link>
</p>
</div>
Зарегистрироваться
</NeonButton>
</form>
{/* Footer */}
<div className="mt-6 pt-6 border-t border-dark-600 text-center">
<p className="text-gray-400 text-sm">
Уже есть аккаунт?{' '}
<Link
to="/login"
className="text-accent-400 hover:text-accent-300 transition-colors font-medium"
>
Войти
</Link>
</p>
</div>
</GlassCard>
</div>
{/* Decorative elements */}
<div className="absolute -top-4 -left-4 w-24 h-24 border border-accent-500/20 rounded-2xl -z-10" />
<div className="absolute -bottom-4 -right-4 w-32 h-32 border border-neon-500/20 rounded-2xl -z-10" />
<div className="absolute -top-4 -left-4 w-24 h-24 border border-accent-500/20 rounded-2xl -z-10 hidden md:block" />
<div className="absolute -bottom-4 -right-4 w-32 h-32 border border-neon-500/20 rounded-2xl -z-10 hidden md:block" />
</div>
</div>
)