From 117be0f4b29ef8eb5622f7bf300fec570677cc23 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 30 Sep 2025 15:29:56 +0700 Subject: add role selection when login --- app/login/page.tsx | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 4 deletions(-) (limited to 'app/login') diff --git a/app/login/page.tsx b/app/login/page.tsx index 3ea2190..3ccefa4 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -6,12 +6,16 @@ import { FormLabel, TextField, Typography, + Select, + MenuItem, + SelectChangeEvent, } from "@mui/material"; import Header from "../lib/camera/component/hedear"; import odooApi from "../lib/api/odooApi"; import { getAuth, setAuth } from "../lib/api/auth"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; +import { setCookie } from "cookies-next"; // Ambil tipe parameter untuk setAuth agar sesuai tepat dengan definisinya type AuthProps = Parameters[0]; @@ -24,17 +28,24 @@ type LoginResult = { }; type LoginResponse = { status?: LoginStatus; result?: LoginResult }; +type Role = "driver" | "dispatch"; + const Login = () => { const router = useRouter(); - // state untuk validasi MUI helperText + // state input const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); + const [role, setRole] = useState<"" | Role>(""); + // state error helperText const [emailError, setEmailError] = useState(false); const [emailErrorMessage, setEmailErrorMessage] = useState(""); const [passwordError, setPasswordError] = useState(false); const [passwordErrorMessage, setPasswordErrorMessage] = useState(""); + const [roleError, setRoleError] = useState(false); + const [roleErrorMessage, setRoleErrorMessage] = useState(""); + const [loading, setLoading] = useState(false); useEffect(() => { @@ -42,7 +53,7 @@ const Login = () => { if (token) router.push("/"); }, [router]); - const validateInputs = (e: string, p: string) => { + const validateInputs = (e: string, p: string, r: "" | Role) => { let ok = true; if (!e || !/\S+@\S+\.\S+/.test(e)) { @@ -63,9 +74,27 @@ const Login = () => { setPasswordErrorMessage(""); } + if (!r) { + setRoleError(true); + setRoleErrorMessage("Please select a role."); + ok = false; + } else { + setRoleError(false); + setRoleErrorMessage(""); + } + return ok; }; + const handleRoleChange = (e: SelectChangeEvent) => { + const val = e.target.value as Role | ""; + setRole(val); + if (val) { + setRoleError(false); + setRoleErrorMessage(""); + } + }; + const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); @@ -73,26 +102,31 @@ const Login = () => { const fd = new FormData(event.currentTarget); const rawEmail = fd.get("email"); const rawPassword = fd.get("password"); + const rawRole = fd.get("role"); const emailStr = typeof rawEmail === "string" ? rawEmail.trim() : ""; const passwordStr = typeof rawPassword === "string" ? rawPassword : ""; + const roleStr: "" | Role = rawRole === "driver" || rawRole === "dispatch" ? rawRole : ""; - if (!validateInputs(emailStr, passwordStr)) return; + if (!validateInputs(emailStr, passwordStr, roleStr)) return; try { setLoading(true); + // Kirim web_role juga (opsional, kalau backend abaikan juga tidak masalah) const res = (await odooApi("POST", "/api/v1/user/login", { email: emailStr, password: passwordStr, + web_role: roleStr, })) as unknown as LoginResponse; const auth = res?.result; if (res?.status?.code === 200 && auth?.is_auth) { - // Cast auth.user ke AuthProps → cocok dengan setAuth if (auth.user && typeof auth.user === "object") { setAuth(auth.user as AuthProps); } + // Simpan pilihan role agar bisa dipakai di halaman lain + setCookie("web_role", roleStr, { path: "/" }); router.push("/"); return; } @@ -179,6 +213,30 @@ const Login = () => { /> + {/* Role selection */} + + Role + + {roleError && ( + + {roleErrorMessage || "Please select a role."} + + )} + + -- cgit v1.2.3 From 352000c186a2765416cd2fab6693e68bb62e9e53 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 30 Sep 2025 16:20:05 +0700 Subject: done --- app/login/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/login') diff --git a/app/login/page.tsx b/app/login/page.tsx index 3ccefa4..c0d7ab8 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -154,7 +154,7 @@ const Login = () => {
-
+
Date: Tue, 30 Sep 2025 22:42:46 +0700 Subject: No auto login --- app/login/page.tsx | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) (limited to 'app/login') diff --git a/app/login/page.tsx b/app/login/page.tsx index c0d7ab8..b4b0ed0 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -16,7 +16,7 @@ import { getAuth, setAuth } from "../lib/api/auth"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { setCookie } from "cookies-next"; - +import { clearOdooSession } from "../lib/api/clearOdooSession"; // Ambil tipe parameter untuk setAuth agar sesuai tepat dengan definisinya type AuthProps = Parameters[0]; @@ -49,10 +49,16 @@ const Login = () => { const [loading, setLoading] = useState(false); useEffect(() => { + void clearOdooSession(process.env.NEXT_PUBLIC_ODOO_API_HOST ?? ""); const token = getAuth(); - if (token) router.push("/"); + if (token) router.replace("/"); }, [router]); + // useEffect(() => { + // const token = getAuth(); + // if (token) router.push("/"); + // }, [router]); + const validateInputs = (e: string, p: string, r: "" | Role) => { let ok = true; @@ -105,7 +111,8 @@ const Login = () => { const rawRole = fd.get("role"); const emailStr = typeof rawEmail === "string" ? rawEmail.trim() : ""; const passwordStr = typeof rawPassword === "string" ? rawPassword : ""; - const roleStr: "" | Role = rawRole === "driver" || rawRole === "dispatch" ? rawRole : ""; + const roleStr: "" | Role = + rawRole === "driver" || rawRole === "dispatch" ? rawRole : ""; if (!validateInputs(emailStr, passwordStr, roleStr)) return; @@ -125,9 +132,8 @@ const Login = () => { if (auth.user && typeof auth.user === "object") { setAuth(auth.user as AuthProps); } - // Simpan pilihan role agar bisa dipakai di halaman lain - setCookie("web_role", roleStr, { path: "/" }); - router.push("/"); + setCookie("web_role", roleStr, { path: "/", sameSite: "lax" }); + router.replace("/"); return; } @@ -140,7 +146,9 @@ const Login = () => { alert("Akun anda belum aktif"); break; default: - alert(res?.status?.description || "Login gagal. Periksa email/password."); + alert( + res?.status?.description || "Login gagal. Periksa email/password." + ); } } catch (error) { console.error(error); @@ -158,7 +166,11 @@ const Login = () => { Sign in @@ -167,13 +179,19 @@ const Login = () => { component="form" onSubmit={handleSubmit} noValidate - sx={{ display: "flex", flexDirection: "column", width: "100%", gap: 2 }} + sx={{ + display: "flex", + flexDirection: "column", + width: "100%", + gap: 2, + }} > Email { { id="role" name="role" value={role} + disabled={loading} onChange={handleRoleChange} displayEmpty size="small" @@ -237,7 +257,12 @@ const Login = () => { )} - -- cgit v1.2.3