summaryrefslogtreecommitdiff
path: root/app/login/page.tsx
diff options
context:
space:
mode:
authorIT Fixcomart <it@fixcomart.co.id>2025-10-01 10:07:28 +0000
committerIT Fixcomart <it@fixcomart.co.id>2025-10-01 10:07:28 +0000
commitd4688ee0f8590e54211548dd1cfd0faec87d04d0 (patch)
treed874ad11b52eb9749a53af5d90958e3a76f219c0 /app/login/page.tsx
parent0626907b555ead7991d03c374edc096254aced8d (diff)
parent011c01a741f23734e4154342e9a560925687f152 (diff)
Merged in role (pull request #3)
<Miqdad> Major change: adding Role
Diffstat (limited to 'app/login/page.tsx')
-rw-r--r--app/login/page.tsx107
1 files changed, 95 insertions, 12 deletions
diff --git a/app/login/page.tsx b/app/login/page.tsx
index 3ea2190..b4b0ed0 100644
--- a/app/login/page.tsx
+++ b/app/login/page.tsx
@@ -6,13 +6,17 @@ 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";
+import { clearOdooSession } from "../lib/api/clearOdooSession";
// Ambil tipe parameter untuk setAuth agar sesuai tepat dengan definisinya
type AuthProps = Parameters<typeof setAuth>[0];
@@ -24,25 +28,38 @@ 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(() => {
+ void clearOdooSession(process.env.NEXT_PUBLIC_ODOO_API_HOST ?? "");
const token = getAuth();
- if (token) router.push("/");
+ if (token) router.replace("/");
}, [router]);
- const validateInputs = (e: string, p: string) => {
+ // useEffect(() => {
+ // const token = getAuth();
+ // if (token) router.push("/");
+ // }, [router]);
+
+ const validateInputs = (e: string, p: string, r: "" | Role) => {
let ok = true;
if (!e || !/\S+@\S+\.\S+/.test(e)) {
@@ -63,9 +80,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,27 +108,32 @@ 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);
}
- router.push("/");
+ setCookie("web_role", roleStr, { path: "/", sameSite: "lax" });
+ router.replace("/");
return;
}
@@ -106,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);
@@ -120,11 +162,15 @@ 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"
- 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>
@@ -133,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"
@@ -164,6 +216,7 @@ const Login = () => {
<TextField
error={passwordError}
helperText={passwordErrorMessage}
+ disabled={loading}
name="password"
placeholder="••••••"
type="password"
@@ -179,7 +232,37 @@ const Login = () => {
/>
</FormControl>
- <Button type="submit" fullWidth variant="contained" disabled={loading}>
+ {/* Role selection */}
+ <FormControl error={roleError}>
+ <FormLabel htmlFor="role">Role</FormLabel>
+ <Select
+ id="role"
+ name="role"
+ value={role}
+ disabled={loading}
+ 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>
</Box>