แก้ไขหน้าล็อกอิน

This commit is contained in:
Flook 2025-11-10 05:07:03 +07:00
parent c52928fb1e
commit 1e7160922b
2 changed files with 80 additions and 62 deletions

View File

@ -8,16 +8,15 @@ import { yupResolver } from '@hookform/resolvers/yup';
// Hook API Components // Hook API Components
import { useLoginMutation } from '../services/authApi'; import { useLoginMutation } from '../services/authApi';
import LandingIntro from './LandingIntro'; import LandingIntro from './LandingIntro';
import InputText from './InputText'; import InputText from './InputText'; // Path
import { loginSchema } from '../schemas/authSchema'; // Path
import { loginSchema } from '../schemas/authSchema';
export default function LoginForm() { export default function LoginForm() {
// 1. Hook API
const loginMutation = useLoginMutation(); const loginMutation = useLoginMutation();
const [apiErrorMessage, setApiErrorMessage] = useState(""); const [apiErrorMessage, setApiErrorMessage] = useState("");
// 2. Hook Form Setup
const { const {
register, register,
handleSubmit, handleSubmit,
@ -30,13 +29,11 @@ export default function LoginForm() {
} }
}); });
// 3. Form Submission Logic
const onSubmit = (data) => { const onSubmit = (data) => {
setApiErrorMessage(""); setApiErrorMessage("");
// Mutation (Token + Fetch User) // Mutation (Token + Fetch User)
loginMutation.mutate({ loginMutation.mutate({
// 'username' 'password' API
username: data.username, username: data.username,
password: data.password password: data.password
}, { }, {
@ -49,73 +46,94 @@ export default function LoginForm() {
const loading = loginMutation.isPending; const loading = loginMutation.isPending;
return ( return (
<div className="card w-full shadow-xl bg-base-100"> // Card : bg-white, shadow, border-radius Contabo
<div className="card w-full shadow-lg rounded-xl bg-white min-h-full">
<div className="grid md:grid-cols-2 grid-cols-1"> <div className="grid md:grid-cols-2 grid-cols-1">
{/* คอลัมน์ซ้าย: Intro/Features */}
<div className="hidden md:block"> <div className="hidden md:block">
<LandingIntro /> <LandingIntro />
</div> </div>
<div className='py-12 px-10'> {/* คอลัมน์ขวา: Form Wrapper (จัดกึ่งกลางเนื้อหา) */}
<h2 className='text-2xl font-semibold mb-6 text-center text-base-content'>เขาสระบบ DDO Console</h2> <div className='py-12 px-10 flex flex-col justify-center items-center'>
<form onSubmit={handleSubmit(onSubmit)}> {/* Div จำกัดความกว้างของฟอร์มจริง ๆ */}
<div className="w-full max-w-sm">
{/* API Error Alert */} {/* Text: ปรับเป็นภาษาไทย */}
{apiErrorMessage && ( <h2 className='text-3xl font-bold mb-8 text-center text-gray-800'>นดอนรบกลบมา</h2>
<div className="alert alert-error text-sm my-4"> <p className='text-sm mb-6 text-center text-gray-600 leading-relaxed'>
<svg xmlns="http://www.w3.org/2000/svg" className="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> ณสามารถเขาสระบบ DDO Console ได โปรดทราบวาขอมลประจำตวนอาจแตกตางจากขอมลประจำตวสำหรบระบบอ
<span>{apiErrorMessage}</span> </p>
<form onSubmit={handleSubmit(onSubmit)}>
{/* API Error Alert */}
{apiErrorMessage && (
<div className="alert alert-error text-sm my-4 rounded-md">
<svg xmlns="http://www.w3.org/2000/svg" className="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
<span>{apiErrorMessage}</span>
</div>
)}
<div className="mb-4">
{/* Username Input: เปลี่ยนเป็น 'ชื่อผู้ใช้' */}
<InputText
type="text"
containerStyle="mt-4"
labelTitle="ชื่อผู้ใช้"
placeholder="ชื่อผู้ใช้ของคุณ"
{...register('username')} // RHF 'username'
error={errors.username}
/>
{/* Password Input: เปลี่ยนเป็น 'รหัสผ่าน' */}
<InputText
type="password"
containerStyle="mt-4"
labelTitle="รหัสผ่าน"
placeholder="********"
{...register('password')}
error={errors.password}
/>
</div> </div>
)}
<div className="mb-4"> {/* Checkbox และ Link ลืมรหัสผ่าน */}
{/* Username Input (เชื่อม RHF) */} <div className='flex justify-between items-center text-sm mt-6'>
<InputText <label className="flex items-center space-x-2 text-gray-600">
type="text" <input type="checkbox" className="checkbox checkbox-primary checkbox-sm" />
containerStyle="mt-4" <span>จดจำฉ</span>
labelTitle="ชื่อผู้ใช้งาน" </label>
{...register('username')} <Link to="/forgot-password">
error={errors.username} <span className="inline-block text-blue-600 hover:underline hover:cursor-pointer transition duration-200">
/> มรหสผาน?
</span>
</Link>
</div>
{/* Password Input (เชื่อม RHF) */} {/* ปุ่ม Submit: ปรับสี, corner, shadow ตามสไตล์ Contabo */}
<InputText <button
type="password" type="submit"
containerStyle="mt-4" className={"btn mt-8 w-full bg-blue-500 text-white border-blue-500 hover:bg-blue-600 hover:border-blue-600 rounded-full shadow-lg transition duration-300 ease-in-out" + (loading ? " loading" : "")}
labelTitle="รหัสผ่าน" disabled={loading}
{...register('password')} >
error={errors.password} {loading ? 'กำลังเข้าสู่ระบบ...' : 'เข้าสู่ระบบ'}
/> </button>
</div>
<div className='text-right'> {/* "ยังไม่มีบัญชีใช่ไหม?" */}
<Link to="/forgot-password"> <div className='text-center mt-6 text-gray-600'>
<span className="text-sm inline-block hover:text-primary hover:underline hover:cursor-pointer transition duration-200"> งไมญชใชไหม?
มรหสผาน? <Link to="/register">
</span> <span className="inline-block text-blue-600 hover:underline hover:cursor-pointer transition duration-200 ml-1">
</Link> ลงทะเบยน
</div> </span>
</Link>
</div>
</form>
</div> {/* สิ้นสุด Div จำกัดความกว้าง */}
{/* ปุ่ม Submit */} </div> {/* สิ้นสุดคอลัมน์ขวา */}
<button
type="submit"
className={"btn mt-6 w-full btn-primary" + (loading ? " loading" : "")}
disabled={loading}
>
{loading ? 'กำลังเข้าสู่ระบบ...' : 'เข้าสู่ระบบ'}
</button>
<div className='text-center mt-4 text-base-content/80'>
งไมญชใชไหม?
<Link to="/register">
<span className="inline-block text-primary hover:underline hover:cursor-pointer transition duration-200 ml-1">
ลงทะเบยน
</span>
</Link>
</div>
</form>
</div>
</div> </div>
</div> </div>
) )

View File

@ -4,10 +4,10 @@ export default function AuthLayout(){
return( return(
<> <>
{/* 1. Div หลัก: จัดให้อยู่ตรงกลางจอ (ใช้ flex h-screen) */} {/* 1. Div หลัก: จัดให้อยู่ตรงกลางจอ (ใช้ flex h-screen) */}
<div className="flex h-screen items-center justify-center bg-base-200 p-4"> <div className="flex h-screen items-center justify-center bg-base-100">
{/* 2. Div ภาชนะสำหรับเนื้อหา: กำหนดขนาดสูงสุด */} {/* 2. Div ภาชนะสำหรับเนื้อหา: กำหนดขนาดสูงสุด */}
<div className="w-full max-w-5xl"> <div className="w-full h-full">
<Outlet/> <Outlet/>
</div> </div>
</div> </div>