From 3f5c6e86c57f3dbcc76a12294cbad94e8b130443 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 25 Sep 2025 08:22:51 +0700 Subject: Fix login --- app/login/page.tsx | 220 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 164 insertions(+), 56 deletions(-) diff --git a/app/login/page.tsx b/app/login/page.tsx index 9e0a5fe..3ea2190 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -1,84 +1,192 @@ "use client"; - -import { useRouter } from "next/navigation"; -import { useState } from "react"; +import { + Box, + Button, + FormControl, + FormLabel, + TextField, + Typography, +} 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"; + +// Ambil tipe parameter untuk setAuth agar sesuai tepat dengan definisinya +type AuthProps = Parameters[0]; type LoginStatus = { code?: number; description?: string }; -type LoginResult = { token?: string; email?: string; [k: string]: unknown }; +type LoginResult = { + is_auth?: boolean; + reason?: "NOT_FOUND" | "NOT_ACTIVE" | string; + user?: unknown; // akan dicast ke AuthProps jika lolos +}; type LoginResponse = { status?: LoginStatus; result?: LoginResult }; -export default function LoginPage() { +const Login = () => { const router = useRouter(); + + // state untuk validasi MUI helperText + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + + const [emailError, setEmailError] = useState(false); + const [emailErrorMessage, setEmailErrorMessage] = useState(""); + const [passwordError, setPasswordError] = useState(false); + const [passwordErrorMessage, setPasswordErrorMessage] = useState(""); const [loading, setLoading] = useState(false); - const onSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setLoading(true); + useEffect(() => { + const token = getAuth(); + if (token) router.push("/"); + }, [router]); - const fd = new FormData(e.currentTarget); + const validateInputs = (e: string, p: string) => { + let ok = true; + + if (!e || !/\S+@\S+\.\S+/.test(e)) { + setEmailError(true); + setEmailErrorMessage("Please enter a valid email address."); + ok = false; + } else { + setEmailError(false); + setEmailErrorMessage(""); + } + + if (!p || p.length < 6) { + setPasswordError(true); + setPasswordErrorMessage("Password must be at least 6 characters long."); + ok = false; + } else { + setPasswordError(false); + setPasswordErrorMessage(""); + } + + return ok; + }; - // Narrowing ke string, bukan File/null + const handleSubmit = async (event: React.FormEvent) => { + event.preventDefault(); + + // Ambil dari FormData agar sesuai dengan form yang disubmit + const fd = new FormData(event.currentTarget); const rawEmail = fd.get("email"); const rawPassword = fd.get("password"); - const email = typeof rawEmail === "string" ? rawEmail.trim() : ""; - const password = typeof rawPassword === "string" ? rawPassword : ""; + const emailStr = typeof rawEmail === "string" ? rawEmail.trim() : ""; + const passwordStr = typeof rawPassword === "string" ? rawPassword : ""; - if (!email || !password) { - alert("Email dan password wajib diisi."); - setLoading(false); - return; - } + if (!validateInputs(emailStr, passwordStr)) return; try { + setLoading(true); + const res = (await odooApi("POST", "/api/v1/user/login", { - email, - password, + email: emailStr, + password: passwordStr, })) as unknown as LoginResponse; - if (res?.status?.code === 200) { - // Jika kamu punya util setAuth(res.result), panggil di sini. + 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("/"); - } else { - alert(res?.status?.description || "Login gagal. Periksa email/password."); + return; } - } catch (err) { - console.error(err); - alert("Terjadi kesalahan saat login."); + + // Tangani alasan gagal umum + switch (auth?.reason) { + case "NOT_FOUND": + alert("Email tidak ditemukan"); + break; + case "NOT_ACTIVE": + alert("Akun anda belum aktif"); + break; + default: + alert(res?.status?.description || "Login gagal. Periksa email/password."); + } + } catch (error) { + console.error(error); + alert("Gagal login, silahkan coba lagi"); } finally { setLoading(false); } }; return ( -
-
-

Login

- - - - - - -
-
+
+
+
+
+ + Sign in + + + + + Email + setEmail(e.target.value)} + /> + + + + + Password + + setPassword(e.target.value)} + /> + + + + +
+
+
); -} \ No newline at end of file +}; + +export default Login; -- cgit v1.2.3