Files
next-go-blog/app/(auth)/register/page.tsx
Beyhan Oğur 6d95e27114 first commit
2026-04-26 22:16:43 +03:00

162 lines
6.7 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 } from "react";
import { useAppDispatch, useAppSelector } from "@/lib/hooks";
import { register } from "@/lib/features/auth/authSlice";
import { useRouter } from "next/navigation";
import { Turnstile } from "nextjs-turnstile";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { AlertCircle, Loader2 } from "lucide-react";
import Link from "next/link";
import Swal from 'sweetalert2'
import { registerSchema } from "@/lib/schemas/register";
export default function RegisterPage() {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [formErrors, setFormErrors] = useState<Record<string, string>>({});
const [turnstileToken, setTurnstileToken] = useState<string | null>(null);
const dispatch = useAppDispatch();
const { isLoading, error } = useAppSelector((state) => state.auth);
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setFormErrors({});
// Zod Validation
const result = registerSchema.safeParse({
username,
email,
password,
confirmPassword
});
if (!result.success) {
const errors: Record<string, string> = {};
result.error.issues.forEach((issue) => {
const path = issue.path[0];
if (typeof path === 'string') {
errors[path] = issue.message;
}
});
setFormErrors(errors);
return;
}
if (!turnstileToken) {
Swal.fire({
icon: 'error',
title: 'Hata',
text: 'Lütfen doğrulamayı tamamlayın (Turnstile).',
})
return;
}
const dispatchResult = await dispatch(register({ username, email, password }));
if (register.fulfilled.match(dispatchResult)) {
Swal.fire({
position: "center",
icon: "success",
title: "Kayıt Başarılı!",
text: "Lütfen email adresinize gönderilen doğrulama linkine tıklayarak hesabınızı aktif edin.",
showConfirmButton: true,
confirmButtonText: "Giriş Yap"
}).then(() => {
router.push("/login");
});
}
};
return (
<Card className="w-full shadow-lg dark:shadow-slate-800/20">
<CardHeader>
<CardTitle className="text-2xl font-bold text-center">Kayıt Ol</CardTitle>
<CardDescription className="text-center">
Yeni bir hesap oluşturun
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="username">Kullanıcı Adı</Label>
<Input
id="username"
type="text"
placeholder="kullaniciadi"
value={username}
onChange={(e) => setUsername(e.target.value)}
// required validation is now handled by Zod manually on submit
/>
{formErrors.username && <p className="text-destructive text-sm">{formErrors.username}</p>}
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="ornek@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{formErrors.email && <p className="text-destructive text-sm">{formErrors.email}</p>}
</div>
<div className="space-y-2">
<Label htmlFor="password">Şifre</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
{formErrors.password && <p className="text-destructive text-sm">{formErrors.password}</p>}
</div>
<div className="space-y-2">
<Label htmlFor="confirmPassword">Şifre Tekrar</Label>
<Input
id="confirmPassword"
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
/>
{formErrors.confirmPassword && <p className="text-destructive text-sm">{formErrors.confirmPassword}</p>}
</div>
<div className="flex justify-center py-2">
<Turnstile
siteKey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY || "0x4AAAAAACHzHKvlEwMamxCM"}
onSuccess={(token) => setTurnstileToken(token)}
/>
</div>
{error && (
<div className="flex items-center gap-2 text-sm text-destructive bg-destructive/10 p-3 rounded-md">
<AlertCircle className="h-4 w-4" />
<span>{error}</span>
</div>
)}
<Button type="submit" className="w-full" disabled={isLoading || !turnstileToken}>
{isLoading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : "Kayıt Ol"}
</Button>
</form>
</CardContent>
<CardFooter className="flex justify-center">
<p className="text-sm text-muted-foreground">
Zaten hesabınız var mı?{" "}
<Link href="/login" className="text-primary hover:underline">
Giriş Yap
</Link>
</p>
</CardFooter>
</Card>
);
}