diff --git a/Docs/backend_API_docs/README.md b/Docs/backend_API_docs/README.md index ce50061..d7b8c5b 100644 --- a/Docs/backend_API_docs/README.md +++ b/Docs/backend_API_docs/README.md @@ -24,6 +24,16 @@ Example: `/apiV2/items/{ADMIN_ID}` --- +## URL + +- The frontend is currently running on `https://insta.the1s.de`. + +- The backend is currently running on `https://backend.insta.the1s.de`. + +You can see the status of this and all my other services at `https://status.the1s.de`. + +--- + ## Current endpoints ### 1. Get All Items @@ -81,9 +91,9 @@ POST /apiV2/controlInSafe/your_admin_key/5/0 {} ``` -*An empty object means, that the operation was successful and no further information is returned.* +_An empty object means, that the operation was successful and no further information is returned._ -*You also get an http 2xx status code.* +_You also get an http 2xx status code._ --- @@ -107,9 +117,9 @@ POST /apiV2/setReturnDate/your_admin_key/123456 {} ``` -*An empty object means, that the operation was successful and no further information is returned.* +_An empty object means, that the operation was successful and no further information is returned._ -*You also get an http 2xx status code.* +_You also get an http 2xx status code._ --- @@ -133,9 +143,9 @@ POST /apiV2/setTakeDate/your_admin_key/123456 {} ``` -*An empty object means, that the operation was successful and no further information is returned.* +_An empty object means, that the operation was successful and no further information is returned._ -*You also get an http 2xx status code.* +_You also get an http 2xx status code._ --- diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1a0f911..46c90c1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "@tailwindcss/vite": "^4.1.11", - "@tanstack/react-query": "^5.85.0", + "@tanstack/react-query": "^5.85.5", "js-cookie": "^3.0.5", "lucide-react": "^0.539.0", "primeicons": "^7.0.0", @@ -1836,9 +1836,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.85.3", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.3.tgz", - "integrity": "sha512-9Ne4USX83nHmRuEYs78LW+3lFEEO2hBDHu7mrdIgAFx5Zcrs7ker3n/i8p4kf6OgKExmaDN5oR0efRD7i2J0DQ==", + "version": "5.85.5", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.5.tgz", + "integrity": "sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w==", "license": "MIT", "funding": { "type": "github", @@ -1846,12 +1846,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.85.3", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.3.tgz", - "integrity": "sha512-AqU8TvNh5GVIE8I+TUU0noryBRy7gOY0XhSayVXmOPll4UkZeLWKDwi0rtWOZbwLRCbyxorfJ5DIjDqE7GXpcQ==", + "version": "5.85.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.5.tgz", + "integrity": "sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.85.3" + "@tanstack/query-core": "5.85.5" }, "funding": { "type": "github", diff --git a/frontend/package.json b/frontend/package.json index 03ca040..b2b6313 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@tailwindcss/vite": "^4.1.11", - "@tanstack/react-query": "^5.85.0", + "@tanstack/react-query": "^5.85.5", "js-cookie": "^3.0.5", "lucide-react": "^0.539.0", "primeicons": "^7.0.0", @@ -41,4 +41,4 @@ "typescript-eslint": "^8.39.0", "vite": "^7.1.0" } -} \ No newline at end of file +} diff --git a/frontend/src/components/Form4.tsx b/frontend/src/components/Form4.tsx index 17f961c..c4ed1f7 100644 --- a/frontend/src/components/Form4.tsx +++ b/frontend/src/components/Form4.tsx @@ -1,6 +1,9 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { Trash, ArrowLeftRight } from "lucide-react"; import { handleDeleteLoan } from "../utils/userHandler"; +import { useMutation, useQuery } from "@tanstack/react-query"; +import Cookies from "js-cookie"; +import { queryClient } from "../utils/queryClient"; type Loan = { id: number; @@ -22,40 +25,39 @@ const formatDate = (iso: string | null) => { return d.toLocaleString("de-DE", { dateStyle: "short", timeStyle: "short" }); }; -const readUserLoansFromStorage = (): Loan[] => { - const raw = localStorage.getItem("userLoans"); - if (!raw || raw === '"No loans found for this user"') return []; - try { - const parsed = JSON.parse(raw); - return Array.isArray(parsed) ? (parsed as Loan[]) : []; - } catch { - return []; - } -}; +async function fetchUserLoans(): Promise { + const res = await fetch("http://localhost:8002/api/userLoans", { + method: "GET", + headers: { Authorization: `Bearer ${Cookies.get("token") || ""}` }, + }); + if (!res.ok) throw new Error("Failed to fetch user loans"); + const data = await res.json(); + if (data === "No loans found for this user") return []; + return Array.isArray(data) ? (data as Loan[]) : []; +} const Form4: React.FC = () => { - const [userLoans, setUserLoans] = useState(() => - readUserLoansFromStorage() - ); + const { data: userLoans = [], isFetching } = useQuery({ + queryKey: ["userLoans"], + queryFn: fetchUserLoans, + }); - useEffect(() => { - const onStorage = (e: StorageEvent) => { - if (e.key === "userLoans") { - setUserLoans(readUserLoansFromStorage()); - } - }; - window.addEventListener("storage", onStorage); - return () => window.removeEventListener("storage", onStorage); - }, []); + const deleteMutation = useMutation({ + mutationFn: (loanID: number) => handleDeleteLoan(loanID), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["userLoans"] }); + }, + }); - const onDelete = async (loanID: number) => { - const ok = await handleDeleteLoan(loanID); - if (ok) { - setUserLoans((prev) => - prev.filter((l) => Number(l.id) !== Number(loanID)) - ); - } - }; + const onDelete = (loanID: number) => deleteMutation.mutate(loanID); + + if (isFetching) { + return ( +
+

Lade Ausleihen…

+
+ ); + } if (userLoans.length === 0) { return ( diff --git a/frontend/src/components/Object.tsx b/frontend/src/components/Object.tsx index 339612f..a2e8cf2 100644 --- a/frontend/src/components/Object.tsx +++ b/frontend/src/components/Object.tsx @@ -8,7 +8,7 @@ type ObjectProps = { const Object: React.FC = ({ title, description }) => { return (
-

{title}

+

{title}

{description}

); diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 2d0c77b..3750fd0 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from "react"; import Object from "./Object"; +import { MonitorSmartphone } from "lucide-react"; import { ALL_ITEMS_UPDATED_EVENT } from "../utils/fetchData"; const Sidebar: React.FC = () => { @@ -21,74 +22,72 @@ const Sidebar: React.FC = () => { const sorted = [...items].sort((a, b) => Number(a.inSafe) - Number(b.inSafe)); return ( -