From 7e668e17d3f55b4030371f10f3ac9f7e474f5a56 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sun, 26 Oct 2025 13:37:15 +0100 Subject: [PATCH] added german translation --- FrontendV2/src/components/Header.tsx | 49 ++++++++-------- FrontendV2/src/pages/HomePage.tsx | 35 ++++++----- FrontendV2/src/pages/Landingpage.tsx | 47 +++++++-------- FrontendV2/src/pages/LoginPage.tsx | 19 +++--- FrontendV2/src/pages/MyLoansPage.tsx | 59 ++++++++++--------- FrontendV2/src/utils/i18n/locales/de/de.json | 61 +++++++++++++++++++- 6 files changed, 166 insertions(+), 104 deletions(-) diff --git a/FrontendV2/src/components/Header.tsx b/FrontendV2/src/components/Header.tsx index 732e4f4..f7df9eb 100644 --- a/FrontendV2/src/components/Header.tsx +++ b/FrontendV2/src/components/Header.tsx @@ -31,7 +31,6 @@ import { useUserContext } from "@/states/Context"; import { useState } from "react"; import MyAlert from "./myChakra/MyAlert"; import { useTranslation } from "react-i18next"; -import { Trans } from "react-i18next"; const API_BASE = (import.meta as any).env?.VITE_BACKEND_URL || @@ -61,8 +60,8 @@ export const Header = () => { const changePassword = async () => { if (newPassword !== confirmPassword) { - setMsgTitle("Passwortänderung fehlgeschlagen"); - setMsgDescription("Passwörter stimmen nicht überein"); + setMsgTitle(t("err_pw_change")); + setMsgDescription(t("pw_mismatch")); setMsgStatus("error"); setIsMsg(true); return; @@ -78,15 +77,15 @@ export const Header = () => { }); if (!response.ok) { - setMsgTitle("Passwortänderung fehlgeschlagen"); - setMsgDescription("Bitte überprüfen Sie Ihre Eingaben"); + setMsgTitle(t("err_pw_change")); + setMsgDescription(t("pw_mismatch")); setMsgStatus("error"); setIsMsg(true); return; } - setMsgTitle("Passwort erfolgreich geändert"); - setMsgDescription("Ihr Passwort wurde erfolgreich geändert"); + setMsgTitle(t("pw_success")); + setMsgDescription(t("pw_success_desc")); setMsgStatus("success"); setIsMsg(true); @@ -143,7 +142,7 @@ export const Header = () => { children={ - Ausleihe erstellen + {t("create-loan")} } /> @@ -153,7 +152,7 @@ export const Header = () => { children={ - Meine Ausleihen + {t("my-loans")} } /> @@ -163,7 +162,7 @@ export const Header = () => { children={ - Passwort ändern + {t("change-password")} } /> @@ -179,7 +178,7 @@ export const Header = () => { children={ - Hilfe + {t("help")} } /> @@ -195,7 +194,7 @@ export const Header = () => { children={ - Source Code + {t("source-code")} } /> @@ -206,7 +205,7 @@ export const Header = () => { children={ - Logout + {t("logout")} } /> @@ -259,21 +258,21 @@ export const Header = () => { > - Ausleihe erstellen + {t("create-loan")} @@ -284,7 +283,7 @@ export const Header = () => { @@ -296,7 +295,7 @@ export const Header = () => { @@ -304,7 +303,7 @@ export const Header = () => { @@ -317,7 +316,7 @@ export const Header = () => { - Passwort ändern + {t("change-password")}
{ @@ -330,17 +329,17 @@ export const Header = () => { setOldPassword(e.target.value)} - placeholder="Altes Passwort" + placeholder={t("old-password")} /> setNewPassword(e.target.value)} - placeholder="Neues Passwort" + placeholder={t("new-password")} /> setConfirmPassword(e.target.value)} - placeholder="Neues Passwort wiederholen" + placeholder={t("confirm-password")} /> @@ -355,10 +354,10 @@ export const Header = () => { )} - + diff --git a/FrontendV2/src/pages/HomePage.tsx b/FrontendV2/src/pages/HomePage.tsx index db5a20b..bbf5153 100644 --- a/FrontendV2/src/pages/HomePage.tsx +++ b/FrontendV2/src/pages/HomePage.tsx @@ -15,6 +15,7 @@ import MyAlert from "@/components/myChakra/MyAlert"; import { borrowAbleItemsAtom } from "@/states/Atoms"; import { createLoan } from "@/utils/Fetcher"; import { Header } from "@/components/Header"; +import { useTranslation } from "react-i18next"; export interface User { username: string; @@ -22,6 +23,8 @@ export interface User { } export const HomePage = () => { + const { t } = useTranslation(); + const [borrowableItems, setBorrowableItems] = useAtom(borrowAbleItemsAtom); const [startDate, setStartDate] = useState(""); const [endDate, setEndDate] = useState(""); @@ -54,21 +57,21 @@ export const HomePage = () => { )} setStartDate(e.target.value)} /> setEndDate(e.target.value)} @@ -78,8 +81,8 @@ export const HomePage = () => { setIsLoadingA(true); if (!startDate || !endDate) { setMsgStatus("error"); - setMsgTitle("Fehlende Eingaben"); - setMsgDescription("Bitte Start- und Enddatum angeben."); + setMsgTitle(t("missing-fields")); + setMsgDescription(t("missing-fields-desc")); setIsMsg(true); setIsLoadingA(false); return; @@ -88,9 +91,9 @@ export const HomePage = () => { setIsLoadingA(false); if (response && response.status === "error") { setMsgStatus("error"); - setMsgTitle(response.title || "Fehler"); + setMsgTitle(response.title || t("error")); setMsgDescription( - response.description || "Unbekannter Frontend Fehler" + response.description || t("unknown-error") ); setIsMsg(true); return; @@ -101,12 +104,12 @@ export const HomePage = () => { }); }} > - Verfügbare Gegenstände anzeigen + {t("get-borrowable-items")} {isLoadingA && ( - Loading... + {t("loading")} )} {borrowableItems.length > 0 && ( @@ -115,7 +118,7 @@ export const HomePage = () => { - Gegenstand + {t("item")} @@ -143,21 +146,21 @@ export const HomePage = () => { createLoan(selectedItems, startDate, endDate).then((response) => { if (response.status === "error") { setMsgStatus("error"); - setMsgTitle(response.title || "Fehler"); + setMsgTitle(response.title || t("error")); setMsgDescription( - response.description || "Unbekannter Frontend Fehler" + response.description || t("unknown-error") ); setIsMsg(true); return; } setMsgStatus("success"); - setMsgTitle("Erfolg"); - setMsgDescription("Gegenstände erfolgreich ausgeliehen."); + setMsgTitle(t("success")); + setMsgDescription(t("loan-success")) ; setIsMsg(true); }) } > - Gegenstände ausleihen + {t("create-loan")} )} diff --git a/FrontendV2/src/pages/Landingpage.tsx b/FrontendV2/src/pages/Landingpage.tsx index 8102816..5f9f51c 100644 --- a/FrontendV2/src/pages/Landingpage.tsx +++ b/FrontendV2/src/pages/Landingpage.tsx @@ -12,6 +12,7 @@ import { } from "@chakra-ui/react"; import { Lock, LockOpen } from "lucide-react"; import MyAlert from "@/components/myChakra/MyAlert"; +import { useTranslation } from "react-i18next"; export const formatDateTime = (value: string | null | undefined) => { if (!value) return "N/A"; @@ -45,6 +46,8 @@ type Device = { }; const Landingpage: React.FC = () => { + const { t } = useTranslation(); + const [isLoading, setIsLoading] = useState(false); const [loans, setLoans] = useState([]); const [devices, setDevices] = useState([]); @@ -76,8 +79,8 @@ const Landingpage: React.FC = () => { } else { setError( "error", - "Fehler beim Laden", - "Unerwartetes Datenformat erhalten. (Ausleihen)" + t("error-by-loading"), + t("unexpected-date-format_loan") ); } @@ -88,16 +91,12 @@ const Landingpage: React.FC = () => { } else { setError( "error", - "Fehler beim Laden", - "Unerwartetes Datenformat erhalten. (Geräte)" + t("error-by-loading"), + t("unexpected-date-format_device") ); } } catch (e) { - setError( - "error", - "Fehler beim Laden", - "Die Ausleihen konnten nicht geladen werden." - ); + setError("error", t("error-by-loading"), t("error-fetching-loans")); } finally { setIsLoading(false); } @@ -112,7 +111,7 @@ const Landingpage: React.FC = () => { - Alle Ausleihen + {t("all-loans")} {isError && ( @@ -126,7 +125,7 @@ const Landingpage: React.FC = () => { {isLoading && ( - Loading... + {t("loading")} )} @@ -138,22 +137,22 @@ const Landingpage: React.FC = () => { # - Benutzername + {t("username")} - Startdatum + {t("start-date")} - Enddatum + {t("end-date")} - Ausgeliehene Artikel + {t("rented-items")} - Rückgabedatum + {t("return-date")} - Ausleihdatum + {t("take-date")} @@ -179,12 +178,12 @@ const Landingpage: React.FC = () => { {!isLoading && loans.length === 0 && !isError && ( - Keine Ausleihen vorhanden. + {t("no-loans-found")} )} - Alle Geräte + {t("all-devices")} {/* Responsive Grid mit gleich hohen Karten */} @@ -202,14 +201,16 @@ const Landingpage: React.FC = () => { {device.item_name} - Ausleihrolle: {device.can_borrow_role} + + {t("rent-role")}: {device.can_borrow_role} + ))} - Legende: + {t("legend")}: diff --git a/FrontendV2/src/pages/LoginPage.tsx b/FrontendV2/src/pages/LoginPage.tsx index 318d83b..56bb460 100644 --- a/FrontendV2/src/pages/LoginPage.tsx +++ b/FrontendV2/src/pages/LoginPage.tsx @@ -6,6 +6,7 @@ import { useAtom } from "jotai"; import Cookies from "js-cookie"; import { Navigate, useNavigate } from "react-router-dom"; import { PasswordInput } from "@/components/ui/password-input"; +import { useTranslation } from "react-i18next"; const API_BASE = (import.meta as any).env?.VITE_BACKEND_URL || @@ -13,6 +14,8 @@ const API_BASE = "http://localhost:8002"; export const LoginPage = () => { + const { t } = useTranslation(); + const [isLoggedIn, setIsLoggedIn] = useAtom(setIsLoggedInAtom); const [triggerLogout, setTriggerLogout] = useAtom(triggerLogoutAtom); const navigate = useNavigate(); @@ -35,7 +38,7 @@ export const LoginPage = () => { if (!response.ok) { return { success: false, - message: data.message ?? "Login fehlgeschlagen", + message: data.message ?? t("login-failed"), description: data.description ?? "", }; } @@ -72,22 +75,20 @@ export const LoginPage = () => { e.preventDefault()}> - Login - - Bitte unten Ihre Zugangsdaten eingeben. - + {t("login")} + {t("enter-credentials")} - Benutzername + {t("username")} setUsername(e.target.value)} /> - Passwort + {t("password")} setPassword(e.target.value)} @@ -107,8 +108,8 @@ export const LoginPage = () => { {triggerLogout && ( )} diff --git a/FrontendV2/src/pages/MyLoansPage.tsx b/FrontendV2/src/pages/MyLoansPage.tsx index bcde82c..3aff205 100644 --- a/FrontendV2/src/pages/MyLoansPage.tsx +++ b/FrontendV2/src/pages/MyLoansPage.tsx @@ -16,6 +16,7 @@ import { } from "@chakra-ui/react"; import { Header } from "@/components/Header"; import { Trash2 } from "lucide-react"; +import { useTranslation } from "react-i18next"; const API_BASE = (import.meta as any).env?.VITE_BACKEND_URL || @@ -23,6 +24,7 @@ const API_BASE = "http://localhost:8002"; export const MyLoansPage = () => { + const { t } = useTranslation(); const navigate = useNavigate(); const [loans, setLoans] = useState([]); @@ -54,21 +56,18 @@ export const MyLoansPage = () => { if (!res.ok) { setMsgStatus("error"); - setMsgTitle("Fehler"); - setMsgDescription( - "Beim Laden der Ausleihen ist ein Fehler aufgetreten." - ); + setMsgTitle(t("error")); + setMsgDescription(t("error-fetching-loans")); setIsMsg(true); return; } const data = await res.json(); setLoans(data); - console.log("Fetched loans:", data); } catch (e) { setMsgStatus("error"); - setMsgTitle("Fehler"); - setMsgDescription("Netzwerkfehler beim Laden der Ausleihen."); + setMsgTitle(t("error")); + setMsgDescription(t("network-error-fetching-loans")); setIsMsg(true); } finally { setIsLoading(false); @@ -89,23 +88,21 @@ export const MyLoansPage = () => { if (!res.ok) { setMsgStatus("error"); - setMsgTitle("Fehler"); - setMsgDescription( - "Beim Löschen der Ausleihe ist ein Fehler aufgetreten." - ); + setMsgTitle(t("error")); + setMsgDescription(t("error-deleting-loan")); setIsMsg(true); return; } setLoans((prev) => prev.filter((loan) => loan.id !== loanId)); setMsgStatus("success"); - setMsgTitle("Erfolg"); - setMsgDescription("Ausleihe erfolgreich gelöscht."); + setMsgTitle(t("success")); + setMsgDescription(t("loan-deletion-success")); setIsMsg(true); } catch (e) { setMsgStatus("error"); - setMsgTitle("Fehler"); - setMsgDescription("Netzwerkfehler beim Löschen der Ausleihe."); + setMsgTitle(t("error")); + setMsgDescription(t("network-error-deleting-loan")); setIsMsg(true); } }; @@ -132,7 +129,7 @@ export const MyLoansPage = () => { {isLoading && ( - Loading... + {t("loading")} )} {loans && ( @@ -159,13 +156,13 @@ export const MyLoansPage = () => { - Ausleihcode - Startdatum - Enddatum - Geräte - Ausleihdatum - Rückgabedatum - Aktionen + {t("loan-code")} + {t("start-date")} + {t("end-date")} + {t("devices")} + {t("take-date")} + {t("return-date")} + {t("actions")} @@ -204,26 +201,28 @@ export const MyLoansPage = () => { - Sicher? + {t("sure")} - Möchtest du die Ausleihe mit dem{" "} - {delLoanCode} Code wirklich - löschen? + {t("sure-delete-loan-0")} + + {delLoanCode} + {" "} + {t("sure-delete-loan-1")}
- Für den Admin bleibt sie weiterhin sichtbar. + {t("sure-delete-loan-2")}
- + diff --git a/FrontendV2/src/utils/i18n/locales/de/de.json b/FrontendV2/src/utils/i18n/locales/de/de.json index f33897f..5f3c209 100644 --- a/FrontendV2/src/utils/i18n/locales/de/de.json +++ b/FrontendV2/src/utils/i18n/locales/de/de.json @@ -1,3 +1,62 @@ { - "greeting": "Willkommen zurück, " + "greeting": "Willkommen zurück, ", + "err_pw_change": "Passwortänderung fehlgeschlagen", + "pw_mismatch": "Bitte überprüfen Sie Ihre Eingaben", + "pw_success": "Passwort erfolgreich geändert", + "pw_success_desc": "Ihr Passwort wurde erfolgreich geändert.", + "create-loan": "Ausleihe erstellen", + "my-loans": "Meine Ausleihen", + "change-password": "Passwort ändern", + "help": "Hilfe", + "source-code": "Quellcode", + "logout": "Abmelden", + "old-password": "Altes Passwort", + "new-password": "Neues Passwort", + "confirm-password": "Neues Passwort wiederholen", + "cancel": "Abbrechen", + "save": "Speichern", + "start-date": "Startdatum", + "end-date": "Enddatum", + "missing-fields": "Fehlende Eingaben", + "missing-fields-desc": "Bitte Start- und Enddatum angeben.", + "error": "Fehler", + "unknown-error": "Unbekannter Frontend Fehler", + "get-borrowable-items": "Verfügbare Gegenstände abrufen", + "loading": "Laden...", + "item": "Gegenstand", + "success": "Erfolg", + "loan-success": "Ausleihe erfolgreich erstellt", + "error-by-loading": "Fehler beim Laden", + "unexpected-date-format_loan": "Unerwartetes Datumsformat erhalten. (Ausleihen)", + "unexpected-date-format_device": "Unerwartetes Datumsformat erhalten. (Gerät)", + "error-fetching-loans": "Die Ausleihen konnten nicht abgerufen werden.", + "all-loans": "Alle Ausleihen", + "username": "Benutzername", + "rented-items": "Ausgeliehene Gegenstände", + "return-date": "Rückgabedatum", + "take-date": "Abholdatum", + "no-loans-found": "Keine Ausleihen vorhanden.", + "all-devices": "Alle Geräte", + "rent-role": "Ausleihrolle", + "legend": "Legende", + "in-locker": "Im Schließfach", + "not-in-locker": "Nicht im Schließfach", + "login-failed": "Anmeldung fehlgeschlagen", + "login": "Anmelden", + "enter-credentials": "Bitte unten Ihre Anmeldedaten eingeben.", + "password": "Passwort", + "logout-success": "Erfolgreich abgemeldet", + "logout-success-desc": "Sie wurden erfolgreich abgemeldet.", + "network-error-fetching-loans": "Netzwerkfehler beim Laden der Ausleihen.", + "error-deleting-loan": "Die Ausleihe konnte nicht gelöscht werden.", + "loan-deletion-success": "Die Ausleihe wurde erfolgreich gelöscht.", + "network-error-deleting-loan": "Netzwerkfehler beim Löschen der Ausleihe.", + "loan-code": "Ausleihcode", + "devices": "Geräte", + "actions": "Aktionen", + "sure": "Sind Sie sicher?", + "sure-delete-loan-0": "Möchten Sie die Ausleihe mit dem ", + "sure-delete-loan-1": " Ausleihcode wirklich löschen?", + "sure-delete-loan-2": "Für den Admin bleibt sie weiterhin sichtbar.", + "delete": "Löschen" } \ No newline at end of file