216 lines
7.5 KiB
TypeScript
216 lines
7.5 KiB
TypeScript
"use client";
|
|
import React from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Checkbox } from "@/components/ui/checkbox";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import Cookies from "js-cookie";
|
|
import { Icon } from "@/components/ui/icon";
|
|
import { useForm, SubmitHandler } from "react-hook-form";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { z } from "zod";
|
|
import { cn, setCookiesEncrypt } from "@/lib/utils";
|
|
import { Loader2 } from "lucide-react";
|
|
import { getCsrfToken, getProfile, login } from "@/service/auth";
|
|
import { toast } from "sonner";
|
|
import { Link, useRouter } from "@/components/navigation";
|
|
import { warning } from "@/lib/swal";
|
|
|
|
// Schema validasi menggunakan zod
|
|
const schema = z.object({
|
|
username: z.string().min(1, { message: "Judul diperlukan" }),
|
|
password: z.string().min(4, { message: "Password must be at least 4 characters." }),
|
|
});
|
|
|
|
// Tipe untuk form values
|
|
type LoginFormValues = {
|
|
username: string;
|
|
password: string;
|
|
};
|
|
|
|
const LoginForm = () => {
|
|
const [isPending, startTransition] = React.useTransition();
|
|
const router = useRouter();
|
|
const [passwordType, setPasswordType] = React.useState("password");
|
|
|
|
const togglePasswordType = () => {
|
|
setPasswordType((prevType) => (prevType === "password" ? "text" : "password"));
|
|
};
|
|
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
} = useForm<LoginFormValues>({
|
|
resolver: zodResolver(schema),
|
|
mode: "all",
|
|
});
|
|
|
|
// Fungsi submit form
|
|
const onSubmit: SubmitHandler<LoginFormValues> = async (data) => {
|
|
try {
|
|
// const response = null;
|
|
const response = await login({
|
|
...data,
|
|
grantType: "password",
|
|
clientId: "mediahub-app",
|
|
});
|
|
|
|
console.log("LOGIN: ", response);
|
|
|
|
if (response?.error) {
|
|
toast.error("Username / Password Tidak Sesuai");
|
|
} else {
|
|
const { access_token } = response?.data;
|
|
const { refresh_token } = response?.data;
|
|
const dateTime = new Date();
|
|
const newTime = dateTime.getTime() + 10 * 60 * 1000;
|
|
|
|
Cookies.set("access_token", access_token, {
|
|
expires: 1,
|
|
});
|
|
Cookies.set("refresh_token", refresh_token, {
|
|
expires: 1,
|
|
});
|
|
Cookies.set("time_refresh", new Date(newTime).toISOString(), {
|
|
expires: 1,
|
|
});
|
|
|
|
Cookies.set("is_first_login", String(true), {
|
|
secure: true,
|
|
sameSite: "strict",
|
|
});
|
|
const profile = await getProfile(access_token);
|
|
console.log("PROFILE : ", profile?.data?.data);
|
|
|
|
if (profile?.data?.data?.isInternational == true || profile?.data?.data?.isActive == false || profile?.data?.data?.isDelete == true) {
|
|
Object.keys(Cookies.get()).forEach((cookieName) => {
|
|
Cookies.remove(cookieName);
|
|
});
|
|
warning("Akun Anda tidak dapat digunakan untuk masuk ke MediaHub Polri", "/auth/login");
|
|
} else {
|
|
Cookies.set("home_path", profile?.data?.data?.homePath, {
|
|
expires: 1,
|
|
});
|
|
Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, {
|
|
expires: 1,
|
|
});
|
|
Cookies.set("state", profile?.data?.data?.userLevel?.name, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("uie", profile?.data?.data?.id, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("urie", profile?.data?.data?.roleId, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("urne", profile?.data?.data?.role?.name, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("ulie", profile?.data?.data?.userLevel?.id, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("uplie", profile?.data?.data?.userLevel?.parentLevelId, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("ulne", profile?.data?.data?.userLevel?.levelNumber, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("ufne", profile?.data?.data?.fullname, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("ulnae", profile?.data?.data?.userLevel?.name, {
|
|
expires: 1,
|
|
});
|
|
setCookiesEncrypt("uinse", profile?.data?.data?.instituteId, {
|
|
expires: 1,
|
|
});
|
|
|
|
if (
|
|
Number(profile?.data?.data?.roleId) == 2 ||
|
|
Number(profile?.data?.data?.roleId) == 3 ||
|
|
Number(profile?.data?.data?.roleId) == 4 ||
|
|
Number(profile?.data?.data?.roleId) == 9 ||
|
|
Number(profile?.data?.data?.roleId) == 10 ||
|
|
Number(profile?.data?.data?.roleId) == 11 ||
|
|
Number(profile?.data?.data?.roleId) == 12
|
|
) {
|
|
if (profile?.data?.data?.userLevel?.id == 761 || profile?.data?.data?.userLevel?.parentLevelId == 761) {
|
|
window.location.href = "/in/welcome";
|
|
Cookies.set("status", "login", {
|
|
expires: 1,
|
|
});
|
|
} else {
|
|
window.location.href = "/in/dashboard";
|
|
// router.push('/admin/dashboard');
|
|
Cookies.set("status", "login", {
|
|
expires: 1,
|
|
});
|
|
}
|
|
} else {
|
|
window.location.href = "/";
|
|
Cookies.set("status", "login", {
|
|
expires: 1,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
} catch (err: any) {
|
|
toast.error(err.message || "An unexpected error occurred.");
|
|
}
|
|
// startTransition( () => {
|
|
|
|
// });
|
|
};
|
|
|
|
return (
|
|
<form onSubmit={handleSubmit(onSubmit)} className="mt-5 2xl:mt-7 space-y-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="username" className="font-medium text-default-600">
|
|
Username
|
|
</Label>
|
|
<Input
|
|
size="lg"
|
|
disabled={isPending}
|
|
{...register("username")}
|
|
id="username"
|
|
type="username"
|
|
className={cn("", {
|
|
"border-destructive": errors.username,
|
|
})}
|
|
/>
|
|
{errors.username?.message && <div className="text-destructive mt-2 text-sm">{errors.username.message}</div>}
|
|
</div>
|
|
|
|
<div className="mt-3.5 space-y-2">
|
|
<Label htmlFor="password" className="mb-2 font-medium text-default-600">
|
|
Password
|
|
</Label>
|
|
<div className="relative">
|
|
<Input size="lg" disabled={isPending} {...register("password")} id="password" type={passwordType} className="peer" />
|
|
<div className="absolute top-1/2 -translate-y-1/2 ltr:right-4 rtl:left-4 cursor-pointer" onClick={togglePasswordType}>
|
|
{passwordType === "password" ? <Icon icon="heroicons:eye" className="w-5 h-5 text-default-400" /> : <Icon icon="heroicons:eye-slash" className="w-5 h-5 text-default-400" />}
|
|
</div>
|
|
</div>
|
|
{errors.password?.message && <div className="text-destructive mt-2 text-sm">{errors.password.message}</div>}
|
|
</div>
|
|
|
|
<div className="flex justify-between">
|
|
<div className="flex gap-2 items-center">
|
|
<Checkbox id="checkbox" defaultChecked />
|
|
<Label htmlFor="checkbox">Keep Me Signed In</Label>
|
|
</div>
|
|
<Link href="/forgot-password" className="text-sm text-default-800 dark:text-default-400 leading-6 font-medium">
|
|
Forgot Password?
|
|
</Link>
|
|
</div>
|
|
<Button fullWidth disabled={isPending}>
|
|
{isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
|
{isPending ? "Loading..." : "Sign In"}
|
|
</Button>
|
|
</form>
|
|
);
|
|
};
|
|
|
|
export default LoginForm;
|