qudoco-fe/components/form/login.tsx

232 lines
7.5 KiB
TypeScript
Raw Normal View History

2026-02-17 09:05:22 +00:00
"use client";
import React, { useState } from "react";
import Link from "next/link";
import Cookies from "js-cookie";
import { close, error, loading } from "@/config/swal";
import { useRouter } from "next/navigation";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { Input } from "../ui/input";
import { Button } from "../ui/button";
import { Label } from "../ui/label";
import { EyeSlashFilledIcon, EyeFilledIcon } from "../icons";
import Image from "next/image";
import { EyeOff, Eye } from "lucide-react";
2026-02-25 09:11:26 +00:00
import { saveActivity } from "@/service/activity-log";
import { postSignIn, getProfile } from "@/service/master-user";
2026-02-17 09:05:22 +00:00
export default function Login() {
const router = useRouter();
const [isVisible, setIsVisible] = useState(false);
const [isVisibleSetup, setIsVisibleSetup] = useState([false, false]);
const [oldEmail, setOldEmail] = useState("");
const [newEmail, setNewEmail] = useState("");
const toggleVisibility = () => setIsVisible(!isVisible);
const [needOtp, setNeedOtp] = useState(false);
const [isFirstLogin, setFirstLogin] = useState(false);
const [otpValue, setOtpValue] = useState("");
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
const setValUsername = (e: any) => {
const uname = e.replaceAll(/[^\w.-]/g, "");
setUsername(uname.toLowerCase());
};
const onSubmit = async () => {
2026-02-25 09:11:26 +00:00
const data = {
username: username,
password: password,
};
2026-02-17 09:05:22 +00:00
if (!username || !password) {
error("Username & Password Wajib Diisi !");
2026-02-25 09:11:26 +00:00
} else {
loading();
const response = await postSignIn(data);
if (response?.error) {
error("Username / Password Tidak Sesuai");
} else {
const profile = await getProfile(response?.data?.data?.access_token);
const dateTime: any = new Date();
const newTime: any = dateTime.getTime() + 10 * 60 * 1000;
Cookies.set("access_token", response?.data?.data?.access_token, {
expires: 1,
});
Cookies.set("refresh_token", response?.data?.data?.refresh_token, {
expires: 1,
});
Cookies.set("time_refresh", newTime, {
expires: 1,
});
Cookies.set("is_first_login", "true", {
secure: true,
sameSite: "strict",
});
await saveActivity(
{
activityTypeId: 1,
url: "https://dev.mikulnews.com/auth",
userId: profile?.data?.data?.id,
},
response?.data?.data?.access_token,
);
Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, {
expires: 1,
});
Cookies.set("uie", profile?.data?.data?.id, {
expires: 1,
});
Cookies.set("ufne", profile?.data?.data?.fullname, {
expires: 1,
});
Cookies.set("ulie", profile?.data?.data?.userLevelGroup, {
expires: 1,
});
Cookies.set("username", profile?.data?.data?.username, {
expires: 1,
});
Cookies.set("fullname", profile?.data?.data?.fullname, {
expires: 1,
});
Cookies.set("urie", profile?.data?.data?.userRoleId, {
expires: 1,
});
Cookies.set("roleName", profile?.data?.data?.roleName, {
expires: 1,
});
Cookies.set("masterPoldaId", profile?.data?.data?.masterPoldaId, {
expires: 1,
});
Cookies.set("ulne", profile?.data?.data?.userLevelId, {
expires: 1,
});
Cookies.set("urce", profile?.data?.data?.roleCode, {
expires: 1,
});
Cookies.set("email", profile?.data?.data?.email, {
expires: 1,
});
router.push("/admin/dashboard");
Cookies.set("status", "login", {
expires: 1,
});
2026-02-17 09:05:22 +00:00
close();
}
2026-02-25 09:11:26 +00:00
}
2026-02-17 09:05:22 +00:00
};
return (
<div className="min-h-screen flex">
{/* LEFT IMAGE SECTION */}
<div className="hidden lg:block lg:w-1/2 relative">
<Image
src="/image/login.jpg"
alt="Login Illustration"
fill
priority
className="object-cover"
/>
</div>
{/* RIGHT FORM SECTION */}
<div className="w-full lg:w-1/2 flex items-center justify-center bg-gray-50 px-6">
<div className="w-full max-w-md">
{/* LOGO */}
<div className="flex justify-center mb-8">
<Image
src="/image/qudo1.png"
alt="Qudoco Logo"
width={90}
height={90}
className="object-contain"
/>
</div>
{/* TITLE */}
<h1 className="text-3xl font-bold text-gray-900 mb-8 text-center">
Welcome Back
</h1>
{/* FORM */}
<div className="space-y-6">
{/* Username */}
<div>
<label className="block text-sm text-gray-600 mb-2">
Username
</label>
<Input
type="text"
placeholder="Enter username"
value={username}
onChange={(e) => setValUsername(e.target.value)}
className="w-full border-b border-gray-300 focus:border-[#9c6b16] outline-none py-2 bg-transparent transition"
/>
</div>
{/* Password */}
<div>
<label className="block text-sm text-gray-600 mb-2">
Password
</label>
<div className="relative">
<Input
type={showPassword ? "text" : "password"}
placeholder="Enter password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full border-b border-gray-300 focus:border-[#9c6b16] outline-none py-2 pr-10 bg-transparent transition"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-0 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
>
{showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
</button>
</div>
</div>
{/* BUTTON */}
<button
onClick={onSubmit}
className="w-full bg-[#9c6b16] hover:bg-[#805512] text-white py-3 rounded-lg transition font-medium"
>
Login
</button>
</div>
{/* REGISTER */}
<p className="text-center text-sm text-gray-500 mt-6">
Dont have an account?{" "}
<span className="text-blue-600 cursor-pointer hover:underline">
Register
</span>
</p>
{/* FOOTER */}
<div className="text-center text-xs text-gray-400 mt-12 space-x-4">
<span className="hover:text-gray-600 cursor-pointer">Terms</span>
<span className="hover:text-gray-600 cursor-pointer">
Privacy Policy
</span>
<span className="hover:text-gray-600 cursor-pointer">Security</span>
<div className="mt-4">
© 2024 Copyrights by company. All Rights Reserved.
<br />
Designed by <span className="font-medium">Qudoco Team</span>
</div>
</div>
</div>
</div>
</div>
);
}