Compare commits

..

4 Commits

Author SHA1 Message Date
39e3c38aa0 Removed console log 2025-03-17 22:30:21 +01:00
268f404cbe Added navbar 2025-03-17 22:29:43 +01:00
c2c387648f Created navbar 2025-03-17 22:29:37 +01:00
967211565b Changed client to add token to logout call 2025-03-17 22:29:05 +01:00
4 changed files with 89 additions and 1 deletions

View File

@@ -1,3 +1,5 @@
import { useUserStore } from "~/hooks/user";
interface get { interface get {
"/item": { "/item": {
parameters: { parameters: {
@@ -37,6 +39,7 @@ interface post {
username: string; username: string;
password: string; password: string;
}; };
token?: never;
}; };
return: User; return: User;
}; };
@@ -44,6 +47,7 @@ interface post {
parameters: { parameters: {
query?: never; query?: never;
body?: never; body?: never;
token: string;
}; };
return?: never; return?: never;
}; };
@@ -55,6 +59,7 @@ interface post {
password: string; password: string;
email: string; email: string;
}; };
token?: never;
}; };
return?: never; return?: never;
}; };
@@ -78,6 +83,7 @@ export interface Case {
export interface User { export interface User {
uuid: string; uuid: string;
username: string; username: string;
token: string;
} }
class Client { class Client {
@@ -96,6 +102,7 @@ class Client {
: ""; : "";
let response = await fetch(this.baseUrl + path + query, { let response = await fetch(this.baseUrl + path + query, {
method: "GET", method: "GET",
credentials: "include",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
@@ -114,8 +121,12 @@ class Client {
let response = await fetch(this.baseUrl + path + query, { let response = await fetch(this.baseUrl + path + query, {
method: "POST", method: "POST",
body: JSON.stringify(parameters["body"]), body: JSON.stringify(parameters["body"]),
credentials: "include",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: parameters["token"]
? "Bearer " + parameters["token"]
: "",
}, },
}); });
let data; let data;

76
app/components/navbar.tsx Normal file
View File

@@ -0,0 +1,76 @@
import { useState } from "react";
import { useLocation, useNavigate } from "react-router";
import client from "~/api/client";
import { useUserStore } from "~/hooks/user";
export default function NavBar() {
const location = useLocation().pathname;
const user = useUserStore((state) => state.user);
const setUser = useUserStore((state) => state.setUser);
const [popupOpen, setPopupOpen] = useState(false);
const navigate = useNavigate();
function handleProfileClick() {
if (user) {
setPopupOpen(!popupOpen);
} else {
navigate("/login");
}
}
async function handleLogout() {
const [_, status] = await client.POST("/logout", {
token: user ? user.token : "",
});
setUser(null);
}
return (
<div className="flex justify-between p-2">
<div className="flex space-x-4">
<a
onClick={() => navigate("/")}
className={
"border-2 white rounded-md px-2 py-1" +
(location === "/" ? " bg-gray-500" : "")
}
>
Home
</a>
</div>
<button
onClick={handleProfileClick}
className="border-2 white rounded-md px-2 py-1"
>
{user ? user.username : "Login"}
{popupOpen ? (
<>
<div
className="w-screen h-screen absolute top-0 left-0 z-[99]"
onClick={() => {
setPopupOpen(!popupOpen);
}}
></div>
<div className="absolute mt-3 -ml-14 bg-red-600 flex flex-col rounded-md justify-center items-center z-[100] space-y-0.5 w-25 py-1">
<a className="px-2 py-1 hover:bg-blue-400 w-[90%] rounded-md">
Profile
</a>
<a className="px-2 py-1 hover:bg-blue-400 w-[90%] rounded-md">
Settings
</a>
<div className="bg-amber-300 w-[90%] h-[2px] rounded-md"></div>
<a
onClick={handleLogout}
className="px-2 py-1 hover:bg-blue-400 w-[90%] rounded-md"
>
Logout
</a>
</div>
</>
) : (
<></>
)}
</button>
</div>
);
}

View File

@@ -21,7 +21,6 @@ export default function LoginPage() {
}, },
}); });
if (status === 200) { if (status === 200) {
console.log(newUser);
setUser(newUser); setUser(newUser);
navigator("/"); navigator("/");
} else { } else {

View File

@@ -9,6 +9,7 @@ import {
import type { Route } from "./+types/root"; import type { Route } from "./+types/root";
import "./app.css"; import "./app.css";
import NavBar from "./components/navbar";
export const links: Route.LinksFunction = () => [ export const links: Route.LinksFunction = () => [
{ rel: "preconnect", href: "https://fonts.googleapis.com" }, { rel: "preconnect", href: "https://fonts.googleapis.com" },
@@ -33,6 +34,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
<Links /> <Links />
</head> </head>
<body> <body>
<NavBar />
{children} {children}
<ScrollRestoration /> <ScrollRestoration />
<Scripts /> <Scripts />