Files
next-dj/app/auth/register/page.tsx
Beyhan Oğur e881f38e4e first commit
2026-04-26 22:12:36 +03:00

258 lines
9.4 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.
"use client";
import { useState, FormEvent } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000/api/v1";
export default function RegisterPage() {
const [formData, setFormData] = useState({
email: "",
password: "",
re_password: "",
first_name: "",
last_name: "",
});
const [error, setError] = useState<string>("");
const [fieldErrors, setFieldErrors] = useState<Record<string, string[]>>({});
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false);
const router = useRouter();
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
// Clear field error when user starts typing
if (fieldErrors[e.target.name]) {
const newErrors = { ...fieldErrors };
delete newErrors[e.target.name];
setFieldErrors(newErrors);
}
};
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setError("");
setFieldErrors({});
setLoading(true);
try {
const response = await fetch(`${API_BASE_URL}/auth/users/`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
});
const data = await response.json();
if (!response.ok) {
if (data.email || data.password || data.first_name || data.last_name) {
setFieldErrors(data);
} else if (data.detail) {
setError(data.detail);
} else {
setError("Kayıt başarısız. Lütfen bilgilerinizi kontrol edin.");
}
} else {
setSuccess(true);
setTimeout(() => {
router.push("/auth/login");
}, 3000);
}
} catch (err) {
setError("Bir hata oluştu. Lütfen tekrar deneyin.");
console.error("Registration error:", err);
} finally {
setLoading(false);
}
};
if (success) {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<div className="max-w-md w-full space-y-8 p-8 bg-white rounded-lg shadow">
<div className="text-center">
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
<svg
className="h-6 w-6 text-green-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M5 13l4 4L19 7"
/>
</svg>
</div>
<h2 className="mt-6 text-center text-3xl font-bold text-gray-900">
Kayıt Başarılı!
</h2>
<p className="mt-2 text-center text-sm text-gray-600">
Email adresinize gönderilen aktivasyon linkine tıklayarak hesabınızı aktifleştirin.
</p>
<p className="mt-2 text-center text-sm text-gray-500">
Giriş sayfasına yönlendiriliyorsunuz...
</p>
</div>
</div>
</div>
);
}
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div>
<h2 className="mt-6 text-center text-3xl font-bold text-gray-900">
Hesap Oluştur
</h2>
<p className="mt-2 text-center text-sm text-gray-600">
Veya{" "}
<Link
href="/auth/login"
className="font-medium text-blue-600 hover:text-blue-500"
>
mevcut hesabınızla giriş yapın
</Link>
</p>
</div>
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
<div className="rounded-md shadow-sm space-y-4">
<div className="grid grid-cols-2 gap-4">
<div>
<label htmlFor="first_name" className="block text-sm font-medium text-gray-700 mb-1">
Ad
</label>
<input
id="first_name"
name="first_name"
type="text"
className={`appearance-none relative block w-full px-3 py-2 border ${
fieldErrors.first_name ? "border-red-300" : "border-gray-300"
} placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm`}
placeholder="Ad"
value={formData.first_name}
onChange={handleChange}
/>
{fieldErrors.first_name && (
<p className="mt-1 text-sm text-red-600">{fieldErrors.first_name[0]}</p>
)}
</div>
<div>
<label htmlFor="last_name" className="block text-sm font-medium text-gray-700 mb-1">
Soyad
</label>
<input
id="last_name"
name="last_name"
type="text"
className={`appearance-none relative block w-full px-3 py-2 border ${
fieldErrors.last_name ? "border-red-300" : "border-gray-300"
} placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm`}
placeholder="Soyad"
value={formData.last_name}
onChange={handleChange}
/>
{fieldErrors.last_name && (
<p className="mt-1 text-sm text-red-600">{fieldErrors.last_name[0]}</p>
)}
</div>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
Email adresi
</label>
<input
id="email"
name="email"
type="email"
autoComplete="email"
required
className={`appearance-none relative block w-full px-3 py-2 border ${
fieldErrors.email ? "border-red-300" : "border-gray-300"
} placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm`}
placeholder="ornek@email.com"
value={formData.email}
onChange={handleChange}
/>
{fieldErrors.email && (
<p className="mt-1 text-sm text-red-600">{fieldErrors.email[0]}</p>
)}
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700 mb-1">
Şifre
</label>
<input
id="password"
name="password"
type="password"
autoComplete="new-password"
required
className={`appearance-none relative block w-full px-3 py-2 border ${
fieldErrors.password ? "border-red-300" : "border-gray-300"
} placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm`}
placeholder="Minimum 8 karakter"
value={formData.password}
onChange={handleChange}
/>
{fieldErrors.password && (
<p className="mt-1 text-sm text-red-600">{fieldErrors.password[0]}</p>
)}
</div>
<div>
<label htmlFor="re_password" className="block text-sm font-medium text-gray-700 mb-1">
Şifre Tekrar
</label>
<input
id="re_password"
name="re_password"
type="password"
autoComplete="new-password"
required
className={`appearance-none relative block w-full px-3 py-2 border ${
fieldErrors.re_password ? "border-red-300" : "border-gray-300"
} placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm`}
placeholder="Şifrenizi tekrar girin"
value={formData.re_password}
onChange={handleChange}
/>
{fieldErrors.re_password && (
<p className="mt-1 text-sm text-red-600">{fieldErrors.re_password[0]}</p>
)}
</div>
</div>
{error && (
<div className="rounded-md bg-red-50 p-4">
<p className="text-sm text-red-800">{error}</p>
</div>
)}
<div>
<button
type="submit"
disabled={loading}
className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? "Kayıt yapılıyor..." : "Kayıt Ol"}
</button>
</div>
</form>
</div>
</div>
);
}