From eb9883a1c312c2ecd4ea334f499a4de6889f0ae3 Mon Sep 17 00:00:00 2001
From: cdricms <36056008+cdricms@users.noreply.github.com>
Date: Fri, 17 Jan 2025 15:37:01 +0100
Subject: [PATCH] Added /users/me route, and handling auth in frontend
---
backend/api/auth.go | 4 +-
backend/api/get_me.go | 33 +++++++
backend/main.go | 22 ++++-
frontend/app/(main)/login/page.tsx | 15 ++-
frontend/app/layout.tsx | 23 ++---
frontend/components/app-sidebar.tsx | 11 ++-
frontend/components/layouts/swr-layout.tsx | 27 +++++
frontend/components/login-form.tsx | 46 ++++++++-
frontend/components/nav-bar.tsx | 7 +-
frontend/components/nav-user.tsx | 40 ++++----
frontend/hooks/use-api.tsx | 109 +++++++++++++++++++++
frontend/hooks/use-login.tsx | 31 ++++++
frontend/hooks/use-me.tsx | 16 +++
frontend/interfaces/IUser.ts | 10 ++
frontend/lib/constants.ts | 1 +
frontend/middleware.ts | 43 ++++++++
frontend/next.config.ts | 19 ++--
frontend/package-lock.json | 55 +++++++++++
frontend/package.json | 1 +
nginx.conf | 8 --
20 files changed, 453 insertions(+), 68 deletions(-)
create mode 100644 backend/api/get_me.go
create mode 100644 frontend/components/layouts/swr-layout.tsx
create mode 100644 frontend/hooks/use-api.tsx
create mode 100644 frontend/hooks/use-login.tsx
create mode 100644 frontend/hooks/use-me.tsx
create mode 100644 frontend/interfaces/IUser.ts
create mode 100644 frontend/lib/constants.ts
create mode 100644 frontend/middleware.ts
diff --git a/backend/api/auth.go b/backend/api/auth.go
index 4383054..69b2b60 100644
--- a/backend/api/auth.go
+++ b/backend/api/auth.go
@@ -135,8 +135,10 @@ func AuthJWT(next http.Handler) http.Handler {
return
}
+ ctx := context.WithValue(r.Context(), "token", token)
+
// Call the next handler if the JWT is valid
- next.ServeHTTP(w, r)
+ next.ServeHTTP(w, r.WithContext(ctx))
})
}
diff --git a/backend/api/get_me.go b/backend/api/get_me.go
new file mode 100644
index 0000000..6ad406e
--- /dev/null
+++ b/backend/api/get_me.go
@@ -0,0 +1,33 @@
+package api
+
+import (
+ "net/http"
+
+ "fr.latosa-escrima/api/core"
+ "github.com/golang-jwt/jwt/v5"
+)
+
+func HandleGetMe(w http.ResponseWriter, r *http.Request) {
+ token, ok := r.Context().Value("token").(*jwt.Token)
+ if !ok {
+ core.JSONError{
+ Status: core.Error,
+ Message: "Couldn't retrieve your JWT.",
+ }.Respond(w, http.StatusInternalServerError)
+ return
+ }
+
+ claims, ok := token.Claims.(jwt.MapClaims)
+ if !ok {
+ core.JSONError{
+ Status: core.Error,
+ Message: "Invalid token claims.",
+ }.Respond(w, http.StatusInternalServerError)
+ return
+ }
+
+ uuid := claims["user_id"].(string)
+
+ r.SetPathValue("user_uuid", uuid)
+ HandleGetUser(w, r)
+}
diff --git a/backend/main.go b/backend/main.go
index e799caf..aa115ae 100644
--- a/backend/main.go
+++ b/backend/main.go
@@ -17,6 +17,21 @@ import (
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "
-

) {
return (
- //
fetch(url).then((res) => res.json()),
- // revalidateOnFocus: false,
- // }}
- //>
-
-
- {children}
-
-
- //
+
+
+
{children}
+
+
);
}
diff --git a/frontend/components/app-sidebar.tsx b/frontend/components/app-sidebar.tsx
index 5f094b6..715a576 100644
--- a/frontend/components/app-sidebar.tsx
+++ b/frontend/components/app-sidebar.tsx
@@ -10,6 +10,7 @@ import {
GalleryVerticalEnd,
Settings2,
Calendar,
+ Loader2,
} from "lucide-react";
import { NavMain } from "@/components/nav-main";
@@ -23,6 +24,8 @@ import {
SidebarHeader,
SidebarRail,
} from "@/components/ui/sidebar";
+import useMe from "@/hooks/use-me";
+import { useEffect } from "react";
// This is sample data.
const data = {
@@ -93,6 +96,8 @@ const data = {
};
export function AppSidebar({ ...props }: React.ComponentProps
) {
+ const { user, isLoading, success, error } = useMe();
+
return (
@@ -102,7 +107,11 @@ export function AppSidebar({ ...props }: React.ComponentProps) {
-
+ {isLoading ? (
+
+ ) : (
+
+ )}
diff --git a/frontend/components/layouts/swr-layout.tsx b/frontend/components/layouts/swr-layout.tsx
new file mode 100644
index 0000000..44d81bb
--- /dev/null
+++ b/frontend/components/layouts/swr-layout.tsx
@@ -0,0 +1,27 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Hammed Abass. <3 All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+"use client";
+
+import { SWRConfig } from "swr";
+
+interface SWRLayoutProps {
+ children: React.ReactNode;
+}
+
+const SWRLayout: React.FC = ({ children }) => (
+
+ fetch(url, { credentials: "include" }).then((res) =>
+ res.json(),
+ ),
+ revalidateOnFocus: false,
+ }}
+ >
+ {children}
+
+);
+
+export default SWRLayout;
diff --git a/frontend/components/login-form.tsx b/frontend/components/login-form.tsx
index 78da3d8..427d62a 100644
--- a/frontend/components/login-form.tsx
+++ b/frontend/components/login-form.tsx
@@ -1,14 +1,39 @@
+"use client";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
+import { useState } from "react";
+import { useRouter } from "next/navigation";
+import useLogin from "@/hooks/use-login";
+import { Loader2 } from "lucide-react";
export function LoginForm({
className,
...props
}: React.ComponentPropsWithoutRef<"form">) {
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const { login, loading, isSuccess } = useLogin();
+ const router = useRouter();
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ try {
+ const res = await login({ email, password });
+ if (res.status === "Success") router.push("/dashboard");
+ console.log(res);
+ } catch (err: any) {
+ console.log(err.message);
+ }
+ };
+
return (
-
-