From 117be0f4b29ef8eb5622f7bf300fec570677cc23 Mon Sep 17 00:00:00 2001
From: Miqdad <ahmadmiqdad27@gmail.com>
Date: Tue, 30 Sep 2025 15:29:56 +0700
Subject: <Miqdad> add role selection when login

---
 app/login/page.tsx | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 4 deletions(-)

(limited to 'app/login/page.tsx')

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<typeof setAuth>[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<HTMLFormElement>) => {
     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 = () => {
               />
             </FormControl>
 
+            {/* Role selection */}
+            <FormControl error={roleError}>
+              <FormLabel htmlFor="role">Role</FormLabel>
+              <Select
+                id="role"
+                name="role"
+                value={role}
+                onChange={handleRoleChange}
+                displayEmpty
+                size="small"
+              >
+                <MenuItem value="">
+                  <em>Pilih role</em>
+                </MenuItem>
+                <MenuItem value="driver">Driver</MenuItem>
+                <MenuItem value="dispatch">Dispatch</MenuItem>
+              </Select>
+              {roleError && (
+                <Typography variant="caption" color="error" sx={{ mt: 0.5 }}>
+                  {roleErrorMessage || "Please select a role."}
+                </Typography>
+              )}
+            </FormControl>
+
             <Button type="submit" fullWidth variant="contained" disabled={loading}>
               {loading ? "Loading..." : "Sign in"}
             </Button>
-- 
cgit v1.2.3


From 352000c186a2765416cd2fab6693e68bb62e9e53 Mon Sep 17 00:00:00 2001
From: Miqdad <ahmadmiqdad27@gmail.com>
Date: Tue, 30 Sep 2025 16:20:05 +0700
Subject: <Miqdad> done

---
 app/login/page.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'app/login/page.tsx')

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 = () => {
     <div className="bg-[#fafeff] h-screen overflow-auto">
       <Header />
       <div className="py-4 px-4 sm:px-96 pt-20">
-        <div className="bg-white py-6 px-4 sm:px-96 shadow-md rounded-sm">
+        <div className="py-6 px-4 sm:px-96 shadow-md rounded-sm text-black">
           <Typography
             component="h1"
             variant="h4"
-- 
cgit v1.2.3


From 011c01a741f23734e4154342e9a560925687f152 Mon Sep 17 00:00:00 2001
From: Miqdad <ahmadmiqdad27@gmail.com>
Date: Tue, 30 Sep 2025 22:42:46 +0700
Subject: <Miqdad> No auto login

---
 app/login/page.tsx | 45 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 35 insertions(+), 10 deletions(-)

(limited to 'app/login/page.tsx')

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<typeof setAuth>[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 = () => {
           <Typography
             component="h1"
             variant="h4"
-            sx={{ width: "100%", fontSize: "clamp(2rem, 10vw, 2.15rem)", mb: 4 }}
+            sx={{
+              width: "100%",
+              fontSize: "clamp(2rem, 10vw, 2.15rem)",
+              mb: 4,
+            }}
           >
             Sign in
           </Typography>
@@ -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,
+            }}
           >
             <FormControl>
               <FormLabel htmlFor="email">Email</FormLabel>
               <TextField
                 error={emailError}
                 helperText={emailErrorMessage}
+                disabled={loading}
                 id="email"
                 type="email"
                 name="email"
@@ -198,6 +216,7 @@ const Login = () => {
               <TextField
                 error={passwordError}
                 helperText={passwordErrorMessage}
+                disabled={loading}
                 name="password"
                 placeholder="••••••"
                 type="password"
@@ -220,6 +239,7 @@ const Login = () => {
                 id="role"
                 name="role"
                 value={role}
+                disabled={loading}
                 onChange={handleRoleChange}
                 displayEmpty
                 size="small"
@@ -237,7 +257,12 @@ const Login = () => {
               )}
             </FormControl>
 
-            <Button type="submit" fullWidth variant="contained" disabled={loading}>
+            <Button
+              type="submit"
+              fullWidth
+              variant="contained"
+              disabled={loading}
+            >
               {loading ? "Loading..." : "Sign in"}
             </Button>
           </Box>
-- 
cgit v1.2.3

