"use client"; import { useState, useMemo } from "react"; import { useSearchParams, useRouter } from "next/navigation"; import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, } from "@/components/ui/card"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Alert, AlertDescription } from "@/components/ui/alert"; export default function LoginPage() { const router = useRouter(); const searchParams = useSearchParams(); const nextPath = useMemo( () => searchParams.get("next") || "/dashboard", [searchParams] ); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [showPw, setShowPw] = useState(false); const [remember, setRemember] = useState(false); const [submitting, setSubmitting] = useState(false); const [err, setErr] = useState(""); async function onSubmit(e) { e.preventDefault(); setErr(""); if (!username.trim() || !password) { setErr("กรอกชื่อผู้ใช้และรหัสผ่านให้ครบ"); return; } try { setSubmitting(true); // เรียก backend ให้ตั้ง HttpOnly cookie: access_token const res = await fetch( `${process.env.NEXT_PUBLIC_API_BASE}/api/auth/login`, { method: "POST", credentials: "include", // สำคัญ: รับ/ส่งคุกกี้ headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password, remember }), cache: "no-store", } ); if (!res.ok) { const data = await res.json().catch(() => ({})); setErr(data?.message || "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"); return; } // สำเร็จ → backend ตั้งคุกกี้แล้ว → redirect router.replace(nextPath); } catch (e) { setErr("เชื่อมต่อเซิร์ฟเวอร์ไม่ได้ กรุณาลองใหม่"); } finally { setSubmitting(false); } } return ( เข้าสู่ระบบ Document Management System • LCBP3 {err ? ( {err} ) : null} ชื่อผู้ใช้ setUsername(e.target.value)} placeholder="เช่น superadmin" disabled={submitting} /> รหัสผ่าน setPassword(e.target.value)} placeholder="••••••••" disabled={submitting} className="pr-10" /> setShowPw((v) => !v)} className="absolute inset-y-0 px-2 my-auto text-xs bg-white border rounded-md right-2 hover:bg-slate-50" aria-label={showPw ? "ซ่อนรหัสผ่าน" : "แสดงรหัสผ่าน"} disabled={submitting} > {showPw ? "Hide" : "Show"} setRemember(e.target.checked)} disabled={submitting} /> จดจำฉันไว้ในเครื่องนี้ ลืมรหัสผ่าน? {submitting ? ( กำลังเข้าสู่ระบบ… ) : ( "เข้าสู่ระบบ" )} © {new Date().getFullYear()} np-dms.work ); } /** Spinner แบบไม่พึ่งไลบรารีเสริม */ function Spinner() { return ( ); }