first commit

This commit is contained in:
TuanVT
2026-05-23 09:48:07 +07:00
parent 03b9101bd5
commit b6ccde2c74
134 changed files with 7178 additions and 110 deletions
@@ -0,0 +1,269 @@
"use client";
import React, { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useMutation } from "@tanstack/react-query";
import { LockKeyhole, ShieldPlus, User } from "lucide-react";
import { useSelector } from "react-redux";
import { RootState, store } from "@/redux/store";
import {
setDataLoginStorage,
setStateLogin,
setToken,
} from "@/redux/reducer/auth";
import { setRememberPassword } from "@/redux/reducer/site";
import { setInfoUser } from "@/redux/reducer/user";
import authServices from "@/services/authServices";
import { httpRequest } from "@/services";
import { PATH } from "@/constant/config";
import FormCustom from "@/components/utils/FormCustom";
import InputForm from "@/components/utils/FormCustom/components/InputForm";
import CustomLoading from "@/components/customs/custom-loading";
// import FormCustom, { InputForm } from "@/components/common/FormCustom";
export default function MainLogin() {
const router = useRouter();
const { dataLoginStorage } = useSelector((state: RootState) => state.auth);
const { isRememberPassword } = useSelector((state: RootState) => state.site);
const [form, setForm] = useState({
username: isRememberPassword ? dataLoginStorage?.usernameStorage || "" : "",
password: isRememberPassword ? dataLoginStorage?.passwordStorage || "" : "",
});
const loginMutation = useMutation({
mutationFn: async () => {
return httpRequest({
showMessageFailed: true,
showMessageSuccess: true,
msgSuccess: "Đăng nhập thành công!",
http: authServices.login({
username: form.username,
password: form.password,
ip: "",
address: "",
type: 0,
}),
});
},
onSuccess(data: any) {
if (!data) return;
store.dispatch(setStateLogin(true));
store.dispatch(setToken(data.accessToken));
store.dispatch(
setInfoUser({
accessToken: data?.accessToken || "",
refreshToken: data?.refreshToken || "",
accessExpiresAt: data?.accessExpiresAt || "",
refreshExpiresAt: data?.refreshExpiresAt || "",
avatar: data?.avatar || "",
fullname: data?.fullname || "",
}),
);
if (isRememberPassword) {
store.dispatch(
setDataLoginStorage({
usernameStorage: form.username,
passwordStorage: form.password,
}),
);
} else {
store.dispatch(setDataLoginStorage(null));
}
router.replace(PATH.HOME);
},
});
const handleLogin = () => {
loginMutation.mutate();
};
return (
<div className="w-full">
<CustomLoading loading={loginMutation.isPending} />
<FormCustom form={form} setForm={setForm} onSubmit={handleLogin}>
{/* TITLE */}
<h3
className="
text-[34px]
font-semibold
text-[#1A1B2D]
"
>
Đăng nhập
</h3>
<p
className="
mt-1
text-[14px]
font-medium
text-[#6F767E]
"
>
Chào mừng bạn đến với hệ thống quản
</p>
{/* FORM */}
<div className="mt-6">
{/* USERNAME */}
<InputForm
label={
<span>
Tài khoản
<span className="text-red-500"> *</span>
</span>
}
placeholder="Tài khoản"
type="text"
name="username"
onClean
isRequired
isBlur
showDone
icon={<User size={22} />}
/>
{/* PASSWORD */}
<div className="mt-5">
<InputForm
label={
<span>
Mật khẩu
<span className="text-red-500"> *</span>
</span>
}
placeholder="Mật khẩu"
type="password"
name="password"
onClean
isRequired
isBlur
showDone
icon={<ShieldPlus size={22} />}
/>
</div>
{/* REMEMBER PASSWORD */}
<div
className="
mt-[14px]
flex
items-center
gap-2
cursor-pointer
"
>
<input
id="rememberPassword"
type="checkbox"
checked={isRememberPassword}
onChange={() =>
store.dispatch(setRememberPassword(!isRememberPassword))
}
className="
h-5
w-5
cursor-pointer
accent-[#0011AB]
"
/>
<label
htmlFor="rememberPassword"
className="
cursor-pointer
select-none
text-[14px]
font-medium
text-[#171717]
"
>
Nhớ mật khẩu
</label>
</div>
{/* BUTTONS */}
<div className="mt-6">
{/* LOGIN */}
<button
type="submit"
disabled={loginMutation.isPending}
className="
flex
h-[52px]
w-full
items-center
justify-center
rounded-full
bg-[#0011AB]
px-6
text-white
font-bold
transition-all
hover:opacity-90
disabled:cursor-not-allowed
disabled:opacity-50
"
>
Đăng nhập
</button>
{/* LINE */}
<div
className="
my-5
h-[1px]
w-full
bg-[#E5E5E5]
"
/>
{/* FORGOT PASSWORD */}
<button
type="button"
onClick={() => router.push(PATH.FORGOT_PASSWORD)}
className="
flex
h-[52px]
w-full
items-center
justify-center
gap-2
rounded-full
border
border-gray-300
bg-white
px-6
font-bold
text-[#171717]
transition-all
hover:bg-gray-50
"
>
<LockKeyhole size={22} />
Quên mật khẩu
</button>
</div>
</div>
</FormCustom>
</div>
);
}