232 lines
6.6 KiB
TypeScript
232 lines
6.6 KiB
TypeScript
import React, { useState } from "react";
|
||
import { useAuth } from "../hooks/useAuth";
|
||
|
||
interface RegisterFormProps {
|
||
onSwitchToLogin: () => void;
|
||
}
|
||
|
||
export const RegisterForm: React.FC<RegisterFormProps> = ({
|
||
onSwitchToLogin,
|
||
}) => {
|
||
const [formData, setFormData] = useState({
|
||
first_name: "",
|
||
last_name: "",
|
||
username: "",
|
||
email: "",
|
||
password: "",
|
||
confirmPassword: "",
|
||
});
|
||
|
||
const { register, isLoading, error } = useAuth();
|
||
|
||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||
setFormData({
|
||
...formData,
|
||
[e.target.id]: e.target.value,
|
||
});
|
||
};
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
await register(formData);
|
||
};
|
||
|
||
return (
|
||
<form onSubmit={handleSubmit} className="space-y-4">
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label
|
||
htmlFor="first_name"
|
||
className="block text-sm font-medium mb-2"
|
||
style={{ color: "var(--text-secondary)" }}
|
||
>
|
||
Имя
|
||
</label>
|
||
<input
|
||
id="first_name"
|
||
type="text"
|
||
value={formData.first_name}
|
||
onChange={handleChange}
|
||
className="w-full px-4 py-2 rounded-lg border transition-all focus:outline-none focus:ring-2"
|
||
style={{
|
||
backgroundColor: "var(--input-bg)",
|
||
color: "var(--text-primary)",
|
||
borderColor: "var(--border)",
|
||
"--tw-ring-color": "var(--accent)",
|
||
}}
|
||
required
|
||
disabled={isLoading}
|
||
placeholder="Имя"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label
|
||
htmlFor="last_name"
|
||
className="block text-sm font-medium mb-2"
|
||
style={{ color: "var(--text-secondary)" }}
|
||
>
|
||
Фамилия
|
||
</label>
|
||
<input
|
||
id="last_name"
|
||
type="text"
|
||
value={formData.last_name}
|
||
onChange={handleChange}
|
||
className="w-full px-4 py-2 rounded-lg border transition-all focus:outline-none focus:ring-2"
|
||
style={{
|
||
backgroundColor: "var(--input-bg)",
|
||
color: "var(--text-primary)",
|
||
borderColor: "var(--border)",
|
||
"--tw-ring-color": "var(--accent)",
|
||
}}
|
||
required
|
||
disabled={isLoading}
|
||
placeholder="Фамилия"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label
|
||
htmlFor="username"
|
||
className="block text-sm font-medium mb-2"
|
||
style={{ color: "var(--text-secondary)" }}
|
||
>
|
||
Имя пользователя
|
||
</label>
|
||
<input
|
||
id="username"
|
||
type="text"
|
||
value={formData.username}
|
||
onChange={handleChange}
|
||
className="w-full px-4 py-2 rounded-lg border transition-all focus:outline-none focus:ring-2"
|
||
style={{
|
||
backgroundColor: "var(--input-bg)",
|
||
color: "var(--text-primary)",
|
||
borderColor: "var(--border)",
|
||
"--tw-ring-color": "var(--accent)",
|
||
}}
|
||
required
|
||
disabled={isLoading}
|
||
placeholder="username"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label
|
||
htmlFor="email"
|
||
className="block text-sm font-medium mb-2"
|
||
style={{ color: "var(--text-secondary)" }}
|
||
>
|
||
Email
|
||
</label>
|
||
<input
|
||
id="email"
|
||
type="email"
|
||
value={formData.email}
|
||
onChange={handleChange}
|
||
className="w-full px-4 py-2 rounded-lg border transition-all focus:outline-none focus:ring-2"
|
||
style={{
|
||
backgroundColor: "var(--input-bg)",
|
||
color: "var(--text-primary)",
|
||
borderColor: "var(--border)",
|
||
"--tw-ring-color": "var(--accent)",
|
||
}}
|
||
required
|
||
disabled={isLoading}
|
||
placeholder="example@mail.com"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label
|
||
htmlFor="password"
|
||
className="block text-sm font-medium mb-2"
|
||
style={{ color: "var(--text-secondary)" }}
|
||
>
|
||
Пароль
|
||
</label>
|
||
<input
|
||
id="password"
|
||
type="password"
|
||
value={formData.password}
|
||
onChange={handleChange}
|
||
className="w-full px-4 py-2 rounded-lg border transition-all focus:outline-none focus:ring-2"
|
||
style={{
|
||
backgroundColor: "var(--input-bg)",
|
||
color: "var(--text-primary)",
|
||
borderColor: "var(--border)",
|
||
"--tw-ring-color": "var(--accent)",
|
||
}}
|
||
required
|
||
disabled={isLoading}
|
||
placeholder="Введите пароль"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label
|
||
htmlFor="confirmPassword"
|
||
className="block text-sm font-medium mb-2"
|
||
style={{ color: "var(--text-secondary)" }}
|
||
>
|
||
Подтверждение пароля
|
||
</label>
|
||
<input
|
||
id="confirmPassword"
|
||
type="password"
|
||
value={formData.confirmPassword}
|
||
onChange={handleChange}
|
||
className="w-full px-4 py-2 rounded-lg border transition-all focus:outline-none focus:ring-2"
|
||
style={{
|
||
backgroundColor: "var(--input-bg)",
|
||
color: "var(--text-primary)",
|
||
borderColor: "var(--border)",
|
||
"--tw-ring-color": "var(--accent)",
|
||
}}
|
||
required
|
||
disabled={isLoading}
|
||
placeholder="Повторите пароль"
|
||
/>
|
||
</div>
|
||
|
||
{error && (
|
||
<div
|
||
className="p-3 rounded-lg text-sm"
|
||
style={{
|
||
backgroundColor: "var(--error-bg)",
|
||
borderColor: "var(--error-border)",
|
||
color: "var(--error-text)",
|
||
}}
|
||
>
|
||
{error}
|
||
</div>
|
||
)}
|
||
|
||
<button
|
||
type="submit"
|
||
disabled={isLoading}
|
||
className="w-full py-2 px-4 rounded-lg font-medium transition-all transform hover:scale-[1.02] active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed"
|
||
style={{
|
||
backgroundColor: "var(--button-primary)",
|
||
color: "var(--button-primary-text)",
|
||
}}
|
||
>
|
||
{isLoading ? "Регистрация..." : "Зарегистрироваться"}
|
||
</button>
|
||
|
||
<div className="text-center">
|
||
<button
|
||
type="button"
|
||
onClick={onSwitchToLogin}
|
||
className="text-sm transition-colors hover:underline"
|
||
style={{ color: "var(--link)" }}
|
||
>
|
||
Уже есть аккаунт? Войти
|
||
</button>
|
||
</div>
|
||
</form>
|
||
);
|
||
};
|