From e9e3343f2682f5176531b89ee9fc6177276faf2f Mon Sep 17 00:00:00 2001 From: Phil Leon Kersting Date: Fri, 25 Jul 2025 11:26:19 +0200 Subject: [PATCH] error fixes by gpt --- frontend_admin/src/App.tsx | 49 +++--- frontend_admin/src/components/Header.tsx | 69 ++++---- frontend_admin/src/components/LoginCard.tsx | 165 +++++++++----------- frontend_admin/src/layout/Layout.tsx | 34 +--- frontend_admin/src/utils/context.ts | 9 ++ frontend_admin/src/utils/frontendService.ts | 2 +- frontend_admin/src/utils/userHandler.ts | 4 +- 7 files changed, 142 insertions(+), 190 deletions(-) create mode 100644 frontend_admin/src/utils/context.ts diff --git a/frontend_admin/src/App.tsx b/frontend_admin/src/App.tsx index d431165..8f93142 100644 --- a/frontend_admin/src/App.tsx +++ b/frontend_admin/src/App.tsx @@ -6,45 +6,44 @@ import { useEffect, useState } from "react"; import { loadTheme } from "./utils/frontendService"; import "react-toastify/dist/ReactToastify.css"; import Cookies from "js-cookie"; +import { AuthContext } from "./utils/context"; function App() { useEffect(() => { loadTheme(); }, []); - // Track authentication state - const [isAuthenticated, setIsAuthenticated] = useState( - !!Cookies.get("token") - ); + const [isAuthenticated, setIsAuthenticated] = useState(!!Cookies.get("token")); const [showLogin, setShowLogin] = useState(false); + const handleLogout = () => { + Cookies.remove("token"); + setIsAuthenticated(false); + }; + return ( - - {isAuthenticated ? ( - - ) : ( - <> -
-

- Please log in to view the user table. -

- -
- {showLogin && ( + + + {isAuthenticated ? ( + + ) : ( + <> setShowLogin(false)} changeAuth={(loggedIn) => setIsAuthenticated(loggedIn)} /> - )} - - )} - +
+

+ Please log in to view the user table. +

+
+ + )} +
+ ); } + + export default App; diff --git a/frontend_admin/src/components/Header.tsx b/frontend_admin/src/components/Header.tsx index 130bca8..3b4e96d 100644 --- a/frontend_admin/src/components/Header.tsx +++ b/frontend_admin/src/components/Header.tsx @@ -1,50 +1,37 @@ -import { useState } from "react"; -import React from "react"; -import LoginCard from "./LoginCard"; -import { greeting } from "../utils/frontendService"; -import { changeTheme } from "../utils/frontendService"; +import React, { useContext } from "react"; +import Cookies from "js-cookie"; +import { AuthContext } from "../utils/context"; -export interface HeaderProps { - changeAuth?: (isLoggedIn: boolean) => void; -} +const Header: React.FC = () => { + const { isAuthenticated, setIsAuthenticated } = useContext(AuthContext); + const username = Cookies.get("username"); -const Header: React.FC = ({ changeAuth }) => { - const [loginCardVisible, setLoginCardVisible] = useState(false); - - const closeLoginCard = () => { - setLoginCardVisible(false); + const handleLogout = () => { + Cookies.remove("token"); + Cookies.remove("username"); + setIsAuthenticated(false); }; - let loginBtnVal: string = "Hello, " + greeting() + "!"; - return ( -
-
-

- Bikelane Admin Panel -

- +
+

+ 🚲 Bikelane Dashboard +

+
+ {isAuthenticated && ( + <> + + Hello, {username || "User"} + + + + )}
-
{loginCardVisible && }
); }; diff --git a/frontend_admin/src/components/LoginCard.tsx b/frontend_admin/src/components/LoginCard.tsx index 3191c3f..4579fac 100644 --- a/frontend_admin/src/components/LoginCard.tsx +++ b/frontend_admin/src/components/LoginCard.tsx @@ -1,106 +1,85 @@ -import React from "react"; +import React, { useState, useContext } from "react"; import Cookies from "js-cookie"; -import { logout, loginUser } from "../utils/userHandler"; -type LoginCardProps = { +import { AuthContext } from "../utils/context"; + +interface LoginCardProps { onClose: () => void; - changeAuth?: (isLoggedIn: boolean) => void; -}; + changeAuth?: (loggedIn: boolean) => void; +} const LoginCard: React.FC = ({ onClose, changeAuth }) => { + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const { setIsAuthenticated } = useContext(AuthContext); + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault(); + setError(""); + try { + const response = await fetch("http://localhost:5002/api/login", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ username, password }), + }); + const data = await response.json(); + if (response.ok && data.token) { + Cookies.set("token", data.token); + Cookies.set("username", username); + setIsAuthenticated(true); + if (changeAuth) changeAuth(true); + onClose(); + } else { + setError(data.message || "Login fehlgeschlagen"); + } + } catch (err) { + setError("Netzwerkfehler"); + } + }; + return ( -
-
- -

+
+ {/* Overlay */} +
+ {/* Card oben am Dashboard */} +
+

Login

- { - event.preventDefault(); - const formData = new FormData(event.currentTarget); - const username = formData.get("username") as string; - const password = formData.get("password") as string; - const success = await loginUser(username, password); // Make loginUser return true/false - if (success) { - changeAuth?.(true); - onClose(); - } - }} - className="space-y-4 text-black dark:text-white" - > -
- - -
-
- - -
- {Cookies.get("name") ? ( -

- ) : ( - - )} -
- {Cookies.get("token") ? ( - - ) : ( -

- Don't have an account?{" "} - - Register here - -

+ {error && ( +
{error}
)} -
+ setUsername(e.target.value)} + className="border border-blue-300 dark:border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400 dark:bg-gray-800 dark:text-white" + required + /> + setPassword(e.target.value)} + className="border border-blue-300 dark:border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400 dark:bg-gray-800 dark:text-white" + required + /> +
+ +
+

); }; export default LoginCard; + diff --git a/frontend_admin/src/layout/Layout.tsx b/frontend_admin/src/layout/Layout.tsx index 9eb51f4..24f9a3f 100644 --- a/frontend_admin/src/layout/Layout.tsx +++ b/frontend_admin/src/layout/Layout.tsx @@ -1,44 +1,22 @@ -import React, { useEffect } from "react"; +import React from "react"; import Header from "../components/Header"; -import Cookies from "js-cookie"; import Sidebar from "../components/Sidebar"; import { ToastContainer } from "react-toastify"; -import { AuthContext } from "../utils/context"; type LayoutProps = { children: React.ReactNode; }; const Layout: React.FC = ({ children }) => { - const [loggedIn, setLoggedIn] = React.useState(false); - - useEffect(() => { - const token = Cookies.get("token"); - if (token) { - setLoggedIn(true); - } else { - setLoggedIn(false); - } - }, [loggedIn]); - return (
-
setLoggedIn(isLoggedIn) - } /> +
- - {/* Main content */} - {loggedIn && ( - <> - -
- {children} -
- - )} -
+ +
+ {children} +