"use client"; import { useState, useEffect, Suspense } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { useAuth } from "@/lib/auth"; import { clientFetch } from "@/lib/api"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Separator } from "@/components/ui/separator"; import { Eye, EyeOff, Loader2, LogIn, UserPlus, KeyRound, Mail } from "lucide-react"; import { API_URL } from "@/lib/api"; import { UserRole } from "@/lib/types"; // Default export wraps the inner component in Suspense (required by Next.js // when useSearchParams() is used inside a "use client" page). export default function AuthPage() { return ( ); } function AuthPageInner() { const { currentUser, login, register, refresh } = useAuth(); const router = useRouter(); const searchParams = useSearchParams(); const resetToken = searchParams.get("token") || ""; const initialTab = resetToken ? "reset" : "signin"; const [loading, setLoading] = useState(false); const [showPwd, setShowPwd] = useState(false); // Redirect if already logged in useEffect(() => { if (currentUser) router.replace("/dashboard"); }, [currentUser, router]); // ── Sign In ─────────────────────────────────────────────────────────────── const handleSignIn = async (e: React.FormEvent) => { e.preventDefault(); const fd = new FormData(e.currentTarget); const email = fd.get("email") as string; const password = fd.get("password") as string; setLoading(true); try { await login(email, password); toast.success("Welcome back!"); router.push("/dashboard"); router.refresh(); } catch (err: unknown) { toast.error(err instanceof Error ? err.message : "Login failed"); } finally { setLoading(false); } }; // ── Sign Up ─────────────────────────────────────────────────────────────── const handleSignUp = async (e: React.FormEvent) => { e.preventDefault(); const fd = new FormData(e.currentTarget); const name = fd.get("name") as string; const email = fd.get("email") as string; const password = fd.get("password") as string; setLoading(true); try { await register(name, email, password); toast.success("Account created! Welcome!"); router.push("/dashboard"); router.refresh(); } catch (err: unknown) { toast.error(err instanceof Error ? err.message : "Registration failed"); } finally { setLoading(false); } }; // ── Magic Link ──────────────────────────────────────────────────────────── const handleMagicLink = async (e: React.FormEvent) => { e.preventDefault(); const fd = new FormData(e.currentTarget); const email = fd.get("email") as string; setLoading(true); try { await clientFetch("/auth/magic-link", { method: "POST", body: JSON.stringify({ email }), }); toast.success("Magic link sent! Check your email."); } catch (err: unknown) { toast.error(err instanceof Error ? err.message : "Failed to send magic link"); } finally { setLoading(false); } }; // ── Password Reset Request ──────────────────────────────────────────────── const handleResetRequest = async (e: React.FormEvent) => { e.preventDefault(); const fd = new FormData(e.currentTarget); const email = fd.get("email") as string; setLoading(true); try { await clientFetch("/auth/password-reset/request", { method: "POST", body: JSON.stringify({ email }), }); toast.success("Reset link sent! Check your email."); } catch (err: unknown) { toast.error(err instanceof Error ? err.message : "Failed"); } finally { setLoading(false); } }; // ── Password Reset Confirm ──────────────────────────────────────────────── const handleResetConfirm = async (e: React.FormEvent) => { e.preventDefault(); const fd = new FormData(e.currentTarget); const token = fd.get("token") as string; const password = fd.get("password") as string; setLoading(true); try { await clientFetch("/auth/password-reset/confirm", { method: "POST", body: JSON.stringify({ token, password }), }); toast.success("Password updated! You can now sign in."); } catch (err: unknown) { toast.error(err instanceof Error ? err.message : "Failed to reset password"); } finally { setLoading(false); } }; return (
Sign In Sign Up Reset {/* ── Sign In Tab ─────────────────────────────────────────────────── */} Sign In Sign in to your account to access the dashboard.
{/* ── Sign Up Tab ─────────────────────────────────────────────────── */} Create Account New sign-ups are assigned the default MEMBER role.
{/* ── Reset Password Tab ──────────────────────────────────────────── */} Reset Password {/* Step 1: Request */}
{/* Step 2: Confirm */}
{/* ── Demo credentials card ─────────────────────────────────────────── */}

Demo Admin Account

Email: admin@gmail.com

Password: Whatever123$

Role Permissions

MEMBER — View blog posts only

MANAGER — View all + create (draft only)

ADMIN — Full CRUD access + user management

); }