dressed_for_succes_store/frontend old/pages/register.tsx
2025-03-11 22:42:30 +07:00

260 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { Mail, Lock, User, Phone, AlertCircle } from 'lucide-react';
import authService from '../services/auth';
export default function RegisterPage() {
const router = useRouter();
const [formData, setFormData] = useState({
email: '',
password: '',
password_confirm: '',
first_name: '',
last_name: '',
phone: ''
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const [redirectTo, setRedirectTo] = useState<string | null>(null);
// Проверяем, есть ли параметр redirect в URL
useEffect(() => {
if (router.query.redirect) {
setRedirectTo(router.query.redirect as string);
}
// Если пользователь уже авторизован, перенаправляем его
if (authService.isAuthenticated()) {
router.push(redirectTo || '/');
}
}, [router.query.redirect, redirectTo, router]);
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
setError('');
// Проверяем совпадение паролей
if (formData.password !== formData.password_confirm) {
setError('Пароли не совпадают');
setLoading(false);
return;
}
try {
// Отправляем данные для регистрации (включая поле password_confirm)
await authService.register(formData);
// Перенаправляем пользователя после успешной регистрации
router.push(redirectTo || '/');
} catch (err) {
console.error('Ошибка при регистрации:', err);
setError('Не удалось зарегистрироваться. Возможно, пользователь с таким email уже существует.');
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div className="sm:mx-auto sm:w-full sm:max-w-md">
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
Регистрация
</h2>
<p className="mt-2 text-center text-sm text-gray-600">
Уже есть аккаунт?{' '}
<Link href="/login" className="font-medium text-indigo-600 hover:text-indigo-500">
Войдите
</Link>
</p>
</div>
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div className="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
{error && (
<div className="mb-4 bg-red-50 border-l-4 border-red-500 p-4">
<div className="flex">
<div className="flex-shrink-0">
<AlertCircle className="h-5 w-5 text-red-500" />
</div>
<div className="ml-3">
<p className="text-sm text-red-700">{error}</p>
</div>
</div>
</div>
)}
<form className="space-y-6" onSubmit={handleSubmit}>
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
<div>
<label htmlFor="first_name" className="block text-sm font-medium text-gray-700">
Имя
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<User className="h-5 w-5 text-gray-400" />
</div>
<input
id="first_name"
name="first_name"
type="text"
autoComplete="given-name"
required
value={formData.first_name}
onChange={handleChange}
className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="Иван"
/>
</div>
</div>
<div>
<label htmlFor="last_name" className="block text-sm font-medium text-gray-700">
Фамилия
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<User className="h-5 w-5 text-gray-400" />
</div>
<input
id="last_name"
name="last_name"
type="text"
autoComplete="family-name"
required
value={formData.last_name}
onChange={handleChange}
className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="Иванов"
/>
</div>
</div>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Mail className="h-5 w-5 text-gray-400" />
</div>
<input
id="email"
name="email"
type="email"
autoComplete="email"
required
value={formData.email}
onChange={handleChange}
className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="example@example.com"
/>
</div>
</div>
<div>
<label htmlFor="phone" className="block text-sm font-medium text-gray-700">
Телефон (необязательно)
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Phone className="h-5 w-5 text-gray-400" />
</div>
<input
id="phone"
name="phone"
type="tel"
autoComplete="tel"
value={formData.phone}
onChange={handleChange}
className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="+7 (999) 123-45-67"
/>
</div>
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
Пароль
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Lock className="h-5 w-5 text-gray-400" />
</div>
<input
id="password"
name="password"
type="password"
autoComplete="new-password"
required
value={formData.password}
onChange={handleChange}
className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="••••••••"
minLength={8}
/>
</div>
<p className="mt-1 text-xs text-gray-500">Минимум 8 символов</p>
</div>
<div>
<label htmlFor="password_confirm" className="block text-sm font-medium text-gray-700">
Подтверждение пароля
</label>
<div className="mt-1 relative rounded-md shadow-sm">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Lock className="h-5 w-5 text-gray-400" />
</div>
<input
id="password_confirm"
name="password_confirm"
type="password"
autoComplete="new-password"
required
value={formData.password_confirm}
onChange={handleChange}
className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="••••••••"
minLength={8}
/>
</div>
</div>
<div className="flex items-center">
<input
id="terms"
name="terms"
type="checkbox"
required
className="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"
/>
<label htmlFor="terms" className="ml-2 block text-sm text-gray-900">
Я согласен с <a href="#" className="text-indigo-600 hover:text-indigo-500">условиями использования</a> и <a href="#" className="text-indigo-600 hover:text-indigo-500">политикой конфиденциальности</a>
</label>
</div>
<div>
<button
type="submit"
disabled={loading}
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? 'Регистрация...' : 'Зарегистрироваться'}
</button>
</div>
</form>
</div>
</div>
</div>
);
}