diff --git a/00-backend/datasource/database.sqlite b/00-backend/datasource/database.sqlite index 09a8a66..9781298 100644 Binary files a/00-backend/datasource/database.sqlite and b/00-backend/datasource/database.sqlite differ diff --git a/01-frontend/package-lock.json b/01-frontend/package-lock.json index 64da670..3bf7f22 100644 --- a/01-frontend/package-lock.json +++ b/01-frontend/package-lock.json @@ -25,6 +25,7 @@ "mui": "^0.0.1", "react": "^19.0.0", "react-chartjs-2": "^5.3.0", + "react-cookie": "^8.0.1", "react-dom": "^19.1.0", "react-i18next": "^15.5.1", "react-router-dom": "^7.5.3" @@ -1601,6 +1602,28 @@ } } }, + "node_modules/@mui/x-data-grid/node_modules/@mui/x-internals": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.5.2.tgz", + "integrity": "sha512-5YhB2AekK7G8d0YrAjg3WNf0uy3V73JD98WNxJhbIlCraQgl8QOQzr2zNO7MAf/X7mZQtjpjuAsiG3+gI2NVyg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6", + "@mui/utils": "^7.1.1", + "reselect": "^5.1.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@mui/x-internals": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.5.1.tgz", @@ -2092,6 +2115,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -4063,6 +4096,20 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/react-cookie": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-8.0.1.tgz", + "integrity": "sha512-QNdAd0MLuAiDiLcDU/2s/eyKmmfMHtjPUKJ2dZ/5CcQ9QKUium4B3o61/haq6PQl/YWFqC5PO8GvxeHKhy3GFA==", + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.6", + "hoist-non-react-statics": "^3.3.2", + "universal-cookie": "^8.0.0" + }, + "peerDependencies": { + "react": ">= 16.3.0" + } + }, "node_modules/react-dom": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", @@ -4535,6 +4582,15 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/universal-cookie": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-8.0.1.tgz", + "integrity": "sha512-B6ks9FLLnP1UbPPcveOidfvB9pHjP+wekP2uRYB9YDfKVpvcjKgy1W5Zj+cEXJ9KTPnqOKGfVDQBmn8/YCQfRg==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.2" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", diff --git a/01-frontend/package.json b/01-frontend/package.json index 15bb1d7..e93c645 100644 --- a/01-frontend/package.json +++ b/01-frontend/package.json @@ -29,6 +29,7 @@ "mui": "^0.0.1", "react": "^19.0.0", "react-chartjs-2": "^5.3.0", + "react-cookie": "^8.0.1", "react-dom": "^19.1.0", "react-i18next": "^15.5.1", "react-router-dom": "^7.5.3" diff --git a/01-frontend/src/App.tsx b/01-frontend/src/App.tsx index ba14b89..1c40177 100644 --- a/01-frontend/src/App.tsx +++ b/01-frontend/src/App.tsx @@ -15,6 +15,7 @@ import { CustomThemeProvider } from './theme/ThemeContext'; import FSComponents from './pages/FSComponents.tsx'; import AdminPanel from './pages/AdminPanel'; import { AccountProvider } from './helper/AccountProvider.tsx'; +import { CookiesProvider } from 'react-cookie'; export default function App() { @@ -24,24 +25,26 @@ export default function App() { - - - - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - - - + + + + + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + + diff --git a/01-frontend/src/helper/AccountProvider.tsx b/01-frontend/src/helper/AccountProvider.tsx index 73ab17c..c416221 100644 --- a/01-frontend/src/helper/AccountProvider.tsx +++ b/01-frontend/src/helper/AccountProvider.tsx @@ -1,10 +1,17 @@ -import { createContext, ReactNode, useContext, useState } from "react"; +import { createContext, ReactNode, useContext, useEffect, useState } from "react"; import { AccountContextType, User } from "../components/Account"; +import { useCookies } from 'react-cookie'; const AccountContext = createContext(undefined); export const AccountProvider = ({ children }: { children: ReactNode }) => { - const [user, setUser] = useState(null); + const [cookies, setCookie] = useCookies(["account"]); + + const initialAccount = + typeof cookies.account === "object" && !Array.isArray(cookies.account) + ? cookies.account + : null; + const [user, setUser] = useState(initialAccount); const login = (userData: User) => { setUser(userData); @@ -14,6 +21,10 @@ export const AccountProvider = ({ children }: { children: ReactNode }) => { setUser(null); }; + useEffect(() => { + setCookie("account", user, { path: "/", maxAge: 3600 * 24 * 7 }); + }, [user, setCookie]); + return ( {children} diff --git a/01-frontend/src/helper/BasketProvider.tsx b/01-frontend/src/helper/BasketProvider.tsx index 1bd52b7..1a29bfa 100644 --- a/01-frontend/src/helper/BasketProvider.tsx +++ b/01-frontend/src/helper/BasketProvider.tsx @@ -1,5 +1,6 @@ -import React, { createContext, useContext, useState } from 'react'; +import React, { createContext, useContext, useEffect, useState } from 'react'; import Item from '../components/Item'; +import { useCookies } from 'react-cookie'; export interface BasketItem { item: Item; @@ -15,7 +16,8 @@ interface BasketContextType { const BasketContext = createContext(undefined); export const BasketProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - const [basket, setBasket] = useState([]); + const [cookies, setCookie] = useCookies(["basket"]); + const [basket, setBasket] = useState(cookies.basket || []); const addToBasket = (item: Item, quantity: number) => { setBasket((prevBasket) => { @@ -37,6 +39,10 @@ export const BasketProvider: React.FC<{ children: React.ReactNode }> = ({ childr setBasket([]); }; + useEffect(() => { + setCookie("basket", basket, { path: "/", maxAge: 3600 * 24 * 7 }); // 7 Tage + }, [basket, setCookie]); + return ( {children} diff --git a/01-frontend/src/helper/navbar/NavBar.tsx b/01-frontend/src/helper/navbar/NavBar.tsx index e003dfb..54a5b55 100644 --- a/01-frontend/src/helper/navbar/NavBar.tsx +++ b/01-frontend/src/helper/navbar/NavBar.tsx @@ -110,7 +110,8 @@ export default function NavBar() { React.useEffect(() => { // Setze den Avatar-Namen, wenn der Benutzer angemeldet ist - if (user) { + if (user !== undefined && user !== null) { + console.log("User:", user); setAvatarName(user.email.toUpperCase()); } }, [user]);