From 23dc00ff3b9db422b4b81716fd1cc25260ef2961 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Mon, 3 Mar 2025 17:30:57 -0600 Subject: [PATCH] refactor(frontend): moved the login to its own componet --- frontend/src/components/auth/LoginForm.tsx | 157 ++++++++++++++------- frontend/src/routes/login.tsx | 124 +--------------- 2 files changed, 109 insertions(+), 172 deletions(-) diff --git a/frontend/src/components/auth/LoginForm.tsx b/frontend/src/components/auth/LoginForm.tsx index 998bff4..4ecd95b 100644 --- a/frontend/src/components/auth/LoginForm.tsx +++ b/frontend/src/components/auth/LoginForm.tsx @@ -1,76 +1,129 @@ -import {useState} from "react"; import {useSessionStore} from "../../lib/store/sessionStore"; -import {useQueryClient} from "@tanstack/react-query"; +import {LstCard} from "../extendedUI/LstCard"; +import {CardHeader} from "../ui/card"; +import {toast} from "sonner"; +import {z} from "zod"; +import {useRouter} from "@tanstack/react-router"; +import {Controller, useForm} from "react-hook-form"; +import {zodResolver} from "@hookform/resolvers/zod"; +import {Label} from "../ui/label"; +import {Input} from "../ui/input"; +import {Checkbox} from "../ui/checkbox"; +import {Button} from "../ui/button"; + +const FormSchema = z.object({ + username: z.string().min(1, "You must enter a valid username"), + password: z.string().min(4, "You must enter a valid password"), + rememberMe: z.boolean(), +}); const LoginForm = () => { - const [username, setUsername] = useState(""); - const [password, setPassword] = useState(""); - const [error, setError] = useState(""); const {setSession} = useSessionStore(); - const queryClient = useQueryClient(); + const rememeberMe = localStorage.getItem("rememberMe") === "true"; + const username = localStorage.getItem("username") || ""; + const router = useRouter(); + const { + register, + handleSubmit, + control, + formState: {errors}, + } = useForm>({ + resolver: zodResolver(FormSchema), + defaultValues: { + username: username || "", + password: "", + rememberMe: rememeberMe, + }, + }); + + const onSubmitLogin = async (value: z.infer) => { + // Do something with form data + + // first update the rememberMe incase it was selected + if (value.rememberMe) { + localStorage.setItem("rememberMe", value.rememberMe.toString()); + localStorage.setItem("username", value.username); + } else { + localStorage.removeItem("rememberMe"); + localStorage.removeItem("username"); + } - const handleLogin = async (e: React.FormEvent) => { - e.preventDefault(); - // console.log("Form data", {username, password}); try { const response = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json", }, - body: JSON.stringify({username, password}), + body: JSON.stringify({username: value.username, password: value.password}), }); - // if (!response.ok) { - // throw new Error("Invalid credentials"); - // } - const data = await response.json(); - // console.log("Response", data.data); + // Store token in localStorage - localStorage.setItem("auth_token", data.data.token); + // localStorage.setItem("auth_token", data.data.token); - // Optionally store user info - // localStorage.setItem("user", JSON.stringify(user)); - - setSession(data.data.user, data.data.token); - - // Refetch the session data to reflect the logged-in state - queryClient.invalidateQueries(); - - setUsername(""); - setPassword(""); + setSession(data.user, data.token); + toast.success(`You are logged in as ${data.user.username}`); + router.navigate({to: "/"}); } catch (err) { - console.error(err); - setError("Invalid credentials"); + toast.error("Invalid credentials"); } }; return ( -
-
- - setUsername(e.target.value)} - required - /> -
-
- - setPassword(e.target.value)} - required - /> -
- {error &&

{error}

} - -
+
+ + +
+

Login to LST

+
+
+
+
+
+ + + {errors.username &&

{errors.username.message}

} +
+
+ <> + + + {errors.password &&

{errors.password.message}

} + +
+
+
+ ( + + )} + control={control} + name="rememberMe" + defaultValue={rememeberMe} + /> + +
+ +
+ +
+
+
+
+
); }; diff --git a/frontend/src/routes/login.tsx b/frontend/src/routes/login.tsx index e62c3a7..05133fe 100644 --- a/frontend/src/routes/login.tsx +++ b/frontend/src/routes/login.tsx @@ -1,15 +1,6 @@ -import {createFileRoute, redirect, useRouter} from "@tanstack/react-router"; -import {useForm, Controller} from "react-hook-form"; -import {zodResolver} from "@hookform/resolvers/zod"; -import {LstCard} from "../components/extendedUI/LstCard"; -import {Button} from "../components/ui/button"; -import {Input} from "../components/ui/input"; -import {CardHeader} from "../components/ui/card"; -import {Label} from "../components/ui/label"; -import {toast} from "sonner"; -import {useSessionStore} from "../lib/store/sessionStore"; -import {Checkbox} from "../components/ui/checkbox"; -import {z} from "zod"; +import {createFileRoute, redirect} from "@tanstack/react-router"; + +import LoginForm from "@/components/auth/LoginForm"; export const Route = createFileRoute("/login")({ component: RouteComponent, @@ -23,117 +14,10 @@ export const Route = createFileRoute("/login")({ }, }); -const FormSchema = z.object({ - username: z.string().min(1, "You must enter a valid username"), - password: z.string().min(4, "You must enter a valid password"), - rememberMe: z.boolean(), -}); - function RouteComponent() { - const {setSession} = useSessionStore(); - const rememeberMe = localStorage.getItem("rememberMe") === "true"; - const username = localStorage.getItem("username") || ""; - const router = useRouter(); - const { - register, - handleSubmit, - control, - formState: {errors}, - } = useForm>({ - resolver: zodResolver(FormSchema), - defaultValues: { - username: username || "", - password: "", - rememberMe: rememeberMe, - }, - }); - - const onSubmitLogin = async (value: z.infer) => { - // Do something with form data - console.log(value); - // first update the rememberMe incase it was selected - if (value.rememberMe) { - localStorage.setItem("rememberMe", value.rememberMe.toString()); - localStorage.setItem("username", value.username); - } else { - localStorage.removeItem("rememberMe"); - localStorage.removeItem("username"); - } - - try { - const response = await fetch("/api/auth/login", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({username: value.username, password: value.password}), - }); - - const data = await response.json(); - - // Store token in localStorage - // localStorage.setItem("auth_token", data.data.token); - - setSession(data.user, data.token); - toast.success(`You are logged in as ${data.user.username}`); - router.navigate({to: "/"}); - } catch (err) { - toast.error("Invalid credentials"); - } - }; return (
- - -
-

Login to LST

-
-
-
-
-
- - - {errors.username &&

{errors.username.message}

} -
-
- <> - - - {errors.password &&

{errors.password.message}

} - -
-
-
- ( - - )} - control={control} - name="rememberMe" - defaultValue={rememeberMe} - /> - -
- -
- -
-
-
-
+
); }