From d05e9ab3ee895c4653ba927c2663b4fca6009364 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Mon, 9 Feb 2026 13:42:06 +0100 Subject: [PATCH 1/5] deleted unused changelog --- FrontendV2/src/components/Changelog.json | 50 ----- FrontendV2/src/components/Changelog.tsx | 263 ----------------------- 2 files changed, 313 deletions(-) delete mode 100644 FrontendV2/src/components/Changelog.json delete mode 100644 FrontendV2/src/components/Changelog.tsx diff --git a/FrontendV2/src/components/Changelog.json b/FrontendV2/src/components/Changelog.json deleted file mode 100644 index df87241..0000000 --- a/FrontendV2/src/components/Changelog.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "title": "Changelog", - "items": [ - { - "version": "v2.1.0", - "date": "2025-10-24", - "changes": [ - { - "type": "Hinzugefügt", - "text": [ - "Neue Changelog-Komponente mit zentriertem Layout.", - "Unterstützung für mehrsprachige Einträge (Englisch und Deutsch)." - ] - }, - { - "type": "Verbessert", - "text": [ - "Performance-Optimierungen beim Laden der Listenansichten.", - "Verbesserte Barrierefreiheit durch ARIA-Attribute." - ] - }, - { - "type": "Behoben", - "text": [ - "Fehler bei der Datumsauswahl im Safari-Browser.", - "Anzeigeprobleme bei hohen DPI-Einstellungen." - ] - } - ] - }, - { - "version": "v2.0.3", - "date": "2025-10-10", - "changes": [ - { - "type": "Geändert", - "text": [ - "Standard-Timeout für API-Requests auf 10s erhöht." - ] - }, - { - "type": "Sicherheit", - "text": [ - "Abhängigkeiten aktualisiert (kritische CVEs behoben)." - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/FrontendV2/src/components/Changelog.tsx b/FrontendV2/src/components/Changelog.tsx deleted file mode 100644 index 7ca3095..0000000 --- a/FrontendV2/src/components/Changelog.tsx +++ /dev/null @@ -1,263 +0,0 @@ -import { useEffect, useRef, useState } from "react"; - -const STORAGE_KEY = "changelog"; - -type ChangeType = - | "Hinzugefügt" - | "Geändert" - | "Behoben" - | "Entfernt" - | "Verbessert" - | "Sicherheit" - | "Veraltet" - | string; - -type ChangeEntry = { - type: ChangeType; - text: string | string[]; // aus localStorage kann es eine Liste sein -}; - -type ChangelogItem = { - version?: string; - date: string; - changes: ChangeEntry[]; -}; - -type StoredChangelog = { - title: string; - items: ChangelogItem[]; -}; - -const typeStyles: Record = { - Hinzugefügt: - "bg-emerald-500/15 text-emerald-300 ring-1 ring-inset ring-emerald-500/30", - Geändert: "bg-blue-500/15 text-blue-300 ring-1 ring-inset ring-blue-500/30", - Behoben: "bg-amber-500/15 text-amber-300 ring-1 ring-inset ring-amber-500/30", - Entfernt: "bg-rose-500/15 text-rose-300 ring-1 ring-inset ring-rose-500/30", - Verbessert: - "bg-indigo-500/15 text-indigo-300 ring-1 ring-inset ring-indigo-500/30", - Sicherheit: "bg-red-500/15 text-red-300 ring-1 ring-inset ring-red-500/30", - Veraltet: "bg-zinc-700/30 text-zinc-300 ring-1 ring-inset ring-zinc-600/40", -}; - -export default function Changelog() { - const [open, setOpen] = useState(true); - const [mounted, setMounted] = useState(false); - const [data, setData] = useState(null); - const [error, setError] = useState(null); - const cardRef = useRef(null); - - useEffect(() => setMounted(true), []); - - const loadFromStorage = () => { - try { - setError(null); - const raw = - typeof window !== "undefined" - ? localStorage.getItem(STORAGE_KEY) - : null; - if (!raw) { - setData(null); - return; - } - const parsed = JSON.parse(raw) as StoredChangelog; - if (!parsed || !Array.isArray(parsed.items)) { - throw new Error("Ungültiges Format"); - } - setData(parsed); - } catch (e) { - setError("Changelog konnte nicht aus localStorage geladen werden."); - setData(null); - } - }; - - useEffect(() => { - loadFromStorage(); - }, []); - - useEffect(() => { - const onKey = (e: KeyboardEvent) => { - if (e.key === "Escape") setOpen(false); - }; - const onClickOutside = (e: MouseEvent) => { - if (cardRef.current && !cardRef.current.contains(e.target as Node)) { - setOpen(false); - } - }; - const onStorage = (e: StorageEvent) => { - if (e.key === STORAGE_KEY) loadFromStorage(); - }; - window.addEventListener("keydown", onKey); - document.addEventListener("mousedown", onClickOutside); - window.addEventListener("storage", onStorage); - return () => { - window.removeEventListener("keydown", onKey); - document.removeEventListener("mousedown", onClickOutside); - window.removeEventListener("storage", onStorage); - }; - }, []); - - if (!open) return null; - - const title = data?.title ?? "Changelog"; - const items = data?.items ?? []; - - return ( -
-
- {/* Gradient border wrapper */} -
- {/* Card */} -
- {/* Accent top line */} -
- - {/* Close button */} - - - {/* Header */} -
-
-
- - - -
-
-

- {title} -

-

- Aktuelle Änderungen und Updates -

-
-
-
- - {/* Body */} -
-
-
- - {error && ( -
-
- {error} -
-
- )} - - {!error && items.length === 0 && ( -
-

- Kein Changelog im localStorage gefunden (Key: {STORAGE_KEY} - ). -

-
- )} - -
    - {items.map((entry, idx) => ( -
  • - {/* Kopfzeile je Release */} -
    - {entry.version && ( - - {entry.version} - - )} - -
    - - {/* Zweispaltiges Layout: Typ links, Text rechts (mit schöner Leselänge) */} -
    - {entry.changes.map((c, i) => ( -
    -
    - - {c.type} - -
    - -
    - {Array.isArray(c.text) ? ( -
      - {c.text.map((t, k) => ( -
    • - {t} -
    • - ))} -
    - ) : ( -

    {c.text}

    - )} -
    -
    - ))} -
    -
  • - ))} -
-
- - {/* soft bottom glow */} -
-
-
-
-
- ); -} From 757b316b495751ee2982070fe28fa6d65f9f48b2 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Mon, 9 Feb 2026 13:42:19 +0100 Subject: [PATCH 2/5] fixed translation bug --- FrontendV2/src/utils/Fetcher.ts | 10 ++++++---- FrontendV2/src/utils/i18n/locales/de/de.json | 1 + FrontendV2/src/utils/i18n/locales/en/en.json | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/FrontendV2/src/utils/Fetcher.ts b/FrontendV2/src/utils/Fetcher.ts index 035de1f..c6be318 100644 --- a/FrontendV2/src/utils/Fetcher.ts +++ b/FrontendV2/src/utils/Fetcher.ts @@ -1,10 +1,13 @@ import Cookies from "js-cookie"; import { API_BASE } from "@/config/api.config"; +import { useTranslation } from "react-i18next"; export const getBorrowableItems = async ( startDate: string, - endDate: string + endDate: string, ) => { + const { t } = useTranslation(); + try { const response = await fetch(`${API_BASE}/api/loans/borrowable-items`, { method: "POST", @@ -21,8 +24,7 @@ export const getBorrowableItems = async ( data: null, status: "error", title: "Server error", - description: - "Ein Fehler ist auf dem Server aufgetreten. Manchmal hilft es, die Seite neu zu laden.", + description: t("serverError"), }; } @@ -48,7 +50,7 @@ export const createLoan = async ( itemIds: number[], startDate: string, endDate: string, - note: string | null + note: string | null, ) => { const response = await fetch(`${API_BASE}/api/loans/createLoan`, { method: "POST", diff --git a/FrontendV2/src/utils/i18n/locales/de/de.json b/FrontendV2/src/utils/i18n/locales/de/de.json index 5d39c80..f6ed2dc 100644 --- a/FrontendV2/src/utils/i18n/locales/de/de.json +++ b/FrontendV2/src/utils/i18n/locales/de/de.json @@ -84,6 +84,7 @@ "contact": "Kontakt", "take": "Abholen", "return": "Zurückgeben", + "serverError": "Serverfehler. Bitte versuchen Sie es später erneut, oder laden Sie die Seite neu.", "take-loan-success": "Ausleihe erfolgreich abgeholt", "return-loan-success": "Ausleihe erfolgreich zurückgegeben", "network-error": "Netzwerkfehler. Kontaktieren Sie den Administrator.", diff --git a/FrontendV2/src/utils/i18n/locales/en/en.json b/FrontendV2/src/utils/i18n/locales/en/en.json index 13dec04..6a52916 100644 --- a/FrontendV2/src/utils/i18n/locales/en/en.json +++ b/FrontendV2/src/utils/i18n/locales/en/en.json @@ -82,6 +82,7 @@ "contactPage_messagePlaceholder": "Enter your message here...", "contactPage_messageErrorText": "This field cannot be empty.", "contact": "Contact", + "serverError": "Server error. Please try again later, or refresh the page.", "take": "Take", "return": "Return", "take-loan-success": "Loan taken successfully", From 38c647c62f3623119e4252d3ec05c1213d3bca79 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Mon, 9 Feb 2026 15:49:51 +0100 Subject: [PATCH 3/5] Fixed bug/issue: #13 --- FrontendV2/src/components/footer/Footer.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/FrontendV2/src/components/footer/Footer.tsx b/FrontendV2/src/components/footer/Footer.tsx index 3d11c18..4732e17 100644 --- a/FrontendV2/src/components/footer/Footer.tsx +++ b/FrontendV2/src/components/footer/Footer.tsx @@ -5,15 +5,7 @@ export const Footer = () => { const { data: info } = useVersionInfoQuery(); return ( - + Made with ❤️ by Theis Gaedigk - Class of 2019 at MCS-Bochum
Frontend-Version: {info ? info["frontend-info"].version : "N/A"} | From 977a6c1b16e9e21506e5a2f186d00a603a9d181c Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Mon, 9 Feb 2026 15:51:00 +0100 Subject: [PATCH 4/5] deltedt mock data because its too old --- backendV2/schemeV2.mock_data.sql | 120 ------------------------------- 1 file changed, 120 deletions(-) delete mode 100644 backendV2/schemeV2.mock_data.sql diff --git a/backendV2/schemeV2.mock_data.sql b/backendV2/schemeV2.mock_data.sql deleted file mode 100644 index 7201901..0000000 --- a/backendV2/schemeV2.mock_data.sql +++ /dev/null @@ -1,120 +0,0 @@ -USE borrow_system_new; - --- Reset tables (no FKs defined, so order is safe) -SET FOREIGN_KEY_CHECKS = 0; -TRUNCATE TABLE loans; -TRUNCATE TABLE apiKeys; -TRUNCATE TABLE items; -TRUNCATE TABLE users; -SET FOREIGN_KEY_CHECKS = 1; - --- Users (roles 1–6, plain-text passwords; is_admin is BOOL) -INSERT INTO users (username, password, email, first_name, last_name, role, is_admin) VALUES -('admin', 'adminpass', 'admin@example.com', 'System', 'Admin', 6, TRUE), -('alice', 'alice123', 'alice@example.com', 'Alice', 'Andersen',1, FALSE), -('bob', 'bob12345', 'bob@example.com', 'Bob', 'Berg', 2, FALSE), -('carol', 'carol123', 'carol@example.com', 'Carol', 'Christensen', 3, FALSE), -('dave', 'dave123', 'dave@example.com', 'Dave', 'Dahl', 4, FALSE), -('erin', 'erin123', 'erin@example.com', 'Erin', 'Enevoldsen', 5, FALSE), -('frank', 'frank123', 'frank@example.com', 'Frank', 'Fisher', 2, FALSE), -('grace', 'grace123', 'grace@example.com', 'Grace', 'Gundersen',1, FALSE), -('heidi', 'heidi123', 'heidi@example.com', 'Heidi', 'Hansen', 4, FALSE), -('tech', 'techpass', 'tech@example.com', 'Tech', 'User', 5, TRUE); - --- Items (safe_nr is two digits or NULL; matches CHECK and UNIQUE constraint) -INSERT INTO items (item_name, can_borrow_role, in_safe, safe_nr, last_borrowed_person, currently_borrowing) VALUES -('Laptop A', 2, FALSE, NULL, 'grace', 'bob'), -('Laptop B', 2, TRUE, '01', NULL, NULL), -('Camera Canon', 3, TRUE, '02', 'erin', NULL), -('Microphone Rode', 1, TRUE, '03', 'grace', NULL), -('Tripod Manfrotto', 1, TRUE, '04', 'frank', NULL), -('Oscilloscope Tek', 4, TRUE, '05', NULL, NULL), -('VR Headset', 3, FALSE, NULL, 'heidi', 'carol'), -('Keycard Programmer', 6, TRUE, '06', 'admin', NULL); - --- Loans (JSON strings, 6-digit numeric loan_code per CHECK) --- Assumes the items above have ids 1..8 in insert order -INSERT INTO loans ( - username, - lockers, - loan_code, - start_date, - end_date, - take_date, - returned_date, - loaned_items_id, - loaned_items_name, - deleted, - note -) VALUES --- Active loan: bob has Laptop A (item id 1, locker "01") -('bob', - '["01"]', - '123456', - '2025-11-15 09:00:00', - '2025-11-22 17:00:00', - '2025-11-15 09:15:00', - NULL, - '[1]', - '["Laptop A"]', - FALSE, - 'Active loan - Laptop A' -), --- Returned loan: frank had Tripod Manfrotto (item id 5, locker "04") -('frank', - '["04"]', - '234567', - '2025-10-01 10:00:00', - '2025-10-07 16:00:00', - '2025-10-01 10:05:00', - '2025-10-05 15:30:00', - '[5]', - '["Tripod Manfrotto"]', - FALSE, - 'Completed loan' -), --- Future reservation: dave will take Oscilloscope Tek (item id 6, locker "05") -('dave', - '["05"]', - '345678', - '2025-12-10 09:00:00', - '2025-12-12 17:00:00', - NULL, - NULL, - '[6]', - '["Oscilloscope Tek"]', - FALSE, - 'Reserved' -), --- Active loan: carol has VR Headset (item id 7, locker "02") -('carol', - '["02"]', - '456789', - '2025-11-10 13:00:00', - '2025-11-20 12:00:00', - '2025-11-10 13:10:00', - NULL, - '[7]', - '["VR Headset"]', - FALSE, - 'Active loan - VR Headset' -), --- Soft-deleted historic loan: grace had Microphone + Tripod (item ids 4,5; lockers "03","04") -('grace', - '["03","04"]', - '567890', - '2025-09-01 09:00:00', - '2025-09-03 17:00:00', - '2025-09-01 09:10:00', - '2025-09-03 16:45:00', - '[4,5]', - '["Microphone Rode","Tripod Manfrotto"]', - TRUE, - 'Canceled/soft-deleted record' -); - --- API keys (8-digit numeric keys per CHECK) -INSERT INTO apiKeys (api_key, entry_name, last_used_at) VALUES -('12345678', 'CI token', '2025-11-15 08:00:00'), -('87654321', 'Local dev', NULL), -('00000001', 'Monitoring', '2025-11-10 12:30:00'); \ No newline at end of file From 8589971dc8f3a457526c2a1ae207f89d8df27254 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Mon, 9 Feb 2026 15:55:27 +0100 Subject: [PATCH 5/5] added scheme to demo branch --- backendV2/schemeV2.mock.sql | 100 ++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 backendV2/schemeV2.mock.sql diff --git a/backendV2/schemeV2.mock.sql b/backendV2/schemeV2.mock.sql new file mode 100644 index 0000000..fcd2d19 --- /dev/null +++ b/backendV2/schemeV2.mock.sql @@ -0,0 +1,100 @@ +USE borrow_system_new; + +-- USERS +INSERT INTO users (username, password, email, first_name, last_name, role, is_admin) +VALUES + ('user1', 'passwordhash1', 'user1@example.com', 'First1', 'Last1', 1, false), + ('user2', 'passwordhash2', 'user2@example.com', 'First2', 'Last2', 1, false), + ('user3', 'passwordhash3', 'user3@example.com', 'First3', 'Last3', 2, false), + ('admin1', 'passwordhash4', 'admin1@example.com', 'Admin', 'One', 9, true), + ('admin2', 'passwordhash5', 'admin2@example.com', 'Admin', 'Two', 9, true); + +-- ITEMS +INSERT INTO items (item_name, can_borrow_role, in_safe, safe_nr, door_key, last_borrowed_person, currently_borrowing) +VALUES + ('Item1', 1, true, 1, 101, NULL, NULL), + ('Item2', 1, true, 2, 102, 'user1', 'user1'), + ('Item3', 2, true, 3, 103, 'user2', NULL), + ('Item4', 1, false, NULL, NULL, NULL, NULL), + ('Item5', 2, false, NULL, NULL, 'user3', 'user3'); + +-- LOANS +INSERT INTO loans ( + username, + lockers, + loan_code, + start_date, + end_date, + take_date, + returned_date, + created_at, + loaned_items_id, + loaned_items_name, + deleted, + note +) +VALUES + ( + 'user1', + JSON_ARRAY('Locker1', 'Locker2'), + '123456', + '2026-02-01 09:00:00', + '2026-02-10 17:00:00', + '2026-02-01 09:15:00', + NULL, + '2026-02-01 09:00:00', + JSON_ARRAY(1, 2), + JSON_ARRAY('Item1', 'Item2'), + false, + 'Erste allgemeine Ausleihe' + ), + ( + 'user2', + JSON_ARRAY('Locker3'), + '234567', + '2026-02-02 10:00:00', + '2026-02-05 16:00:00', + '2026-02-02 10:05:00', + '2026-02-05 15:30:00', + '2026-02-02 10:00:00', + JSON_ARRAY(3), + JSON_ARRAY('Item3'), + false, + 'Zurückgegeben vor Enddatum' + ), + ( + 'user3', + JSON_ARRAY(), + '345678', + '2026-02-03 08:30:00', + '2026-02-15 18:00:00', + NULL, + NULL, + '2026-02-03 08:30:00', + JSON_ARRAY(5), + JSON_ARRAY('Item5'), + false, + 'Noch ausgeliehen' + ), + ( + 'user1', + JSON_ARRAY('Locker4'), + '456789', + '2025-12-01 09:00:00', + '2025-12-03 17:00:00', + '2025-12-01 09:10:00', + '2025-12-03 16:45:00', + '2025-12-01 09:00:00', + JSON_ARRAY(1), + JSON_ARRAY('Item1'), + true, + 'Alte, gelöschte Ausleihe' + ); + +-- API KEYS +INSERT INTO apiKeys (api_key, entry_name) +VALUES + ('10000001', 'Entry1'), + ('10000002', 'Entry2'), + ('10000003', 'Entry3'), + ('10000004', 'Entry4'); \ No newline at end of file