diff --git a/Docs/backend_API_docs/README.md b/Docs/backend_API_docs/README.md
index e993c89..0d15fc0 100644
--- a/Docs/backend_API_docs/README.md
+++ b/Docs/backend_API_docs/README.md
@@ -1,7 +1,7 @@
# Borrow System API Documentation
**Frontend:** https://insta.the1s.de
-**Backend base URL:** `https://backend.insta.the1s.de/api`
+**Backend base URL:** `https://insta.the1s.de/backend/api`
---
diff --git a/FrontendV2/nginx.conf b/FrontendV2/nginx.conf
index 4aa4fa8..cbb9122 100644
--- a/FrontendV2/nginx.conf
+++ b/FrontendV2/nginx.conf
@@ -9,6 +9,14 @@ server {
try_files $uri $uri/ /index.html;
}
+ location = /backend {
+ return 301 /backend/;
+ }
+
+ location /backend/ {
+ proxy_pass http://borrow_system-backend_v2:8004/;
+ }
+
location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 1y;
access_log off;
diff --git a/FrontendV2/src/App.tsx b/FrontendV2/src/App.tsx
index 5c774c9..05c206c 100644
--- a/FrontendV2/src/App.tsx
+++ b/FrontendV2/src/App.tsx
@@ -16,7 +16,6 @@ import { Box, Flex } from "@chakra-ui/react";
import { Footer } from "./components/footer/Footer";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { API_BASE } from "@/config/api.config";
-import { NotFoundPage } from "./pages/NotFoundPage";
const queryClient = new QueryClient();
@@ -84,7 +83,6 @@ function App() {
} />
- } />
diff --git a/FrontendV2/src/components/Header.tsx b/FrontendV2/src/components/Header.tsx
index 2ba22cb..a01199e 100644
--- a/FrontendV2/src/components/Header.tsx
+++ b/FrontendV2/src/components/Header.tsx
@@ -4,25 +4,18 @@ import {
Heading,
Stack,
Text,
- CloseButton,
- Dialog,
- Portal,
HStack,
IconButton,
Menu,
Box,
Avatar,
- Card,
- Grid,
} from "@chakra-ui/react";
-import { PasswordInput } from "@/components/ui/password-input";
import Cookies from "js-cookie";
import { useAtom } from "jotai";
import { setIsLoggedInAtom, triggerLogoutAtom } from "@/states/Atoms";
import { useNavigate } from "react-router-dom";
import {
CircleUserRound,
- RotateCcwKey,
Code,
LifeBuoy,
LogOut,
@@ -33,69 +26,19 @@ import {
} from "lucide-react";
import { useUserContext } from "@/states/Context";
import { useState } from "react";
-import MyAlert from "./myChakra/MyAlert";
import { useTranslation } from "react-i18next";
-import { API_BASE } from "@/config/api.config";
+import { UserDialogue } from "./UserDialogue";
export const Header = () => {
const navigate = useNavigate();
const userData = useUserContext();
- console.log(userData);
const { t } = useTranslation();
- // Error handling states
- const [isMsg, setIsMsg] = useState(false);
- const [msgStatus, setMsgStatus] = useState<"error" | "success">("error");
- const [msgTitle, setMsgTitle] = useState("");
- const [msgDescription, setMsgDescription] = useState("");
-
- const [oldPassword, setOldPassword] = useState("");
- const [newPassword, setNewPassword] = useState("");
- const [confirmPassword, setConfirmPassword] = useState("");
-
const [, setTriggerLogout] = useAtom(triggerLogoutAtom);
const [, setIsLoggedIn] = useAtom(setIsLoggedInAtom);
- // Dialog control
- const [isPwOpen, setPwOpen] = useState(false);
const [userDialog, setUserDialog] = useState(false);
- const changePassword = async () => {
- if (newPassword !== confirmPassword) {
- setMsgTitle(t("err_pw_change"));
- setMsgDescription(t("pw_mismatch"));
- setMsgStatus("error");
- setIsMsg(true);
- return;
- }
-
- const response = await fetch(`${API_BASE}/api/users/change-password`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Authorization: `Bearer ${Cookies.get("token")}`,
- },
- body: JSON.stringify({ oldPassword, newPassword }),
- });
-
- if (!response.ok) {
- setMsgTitle(t("err_pw_change"));
- setMsgDescription(t("pw_mismatch"));
- setMsgStatus("error");
- setIsMsg(true);
- return;
- }
-
- setMsgTitle(t("pw_success"));
- setMsgDescription(t("pw_success_desc"));
- setMsgStatus("success");
- setIsMsg(true);
-
- setOldPassword("");
- setNewPassword("");
- setConfirmPassword("");
- };
-
const username = userData.first_name ? userData.first_name : "N/A";
const fullname = userData.first_name + " " + userData.last_name;
const randomColor = [
@@ -375,146 +318,7 @@ export const Header = () => {
{/* User Info Dialoge */}
- {userDialog && (
-
-
-
-
-
-
-
-
-
-
- {t("user-info-desc")}
-
-
-
-
-
-
- {t("first-name")}:
-
- {userData.first_name}
-
-
- {t("last-name")}:
-
- {userData.last_name}
-
-
- {t("username")}:
-
- {userData.username}
-
-
- {t("role")}:
-
- {userData.role}
-
-
- {t("admin-status")}:
-
-
- {userData.is_admin ? t("yes") : t("no")}
-
-
-
-
-
-
-
-
-
-
-
-
- )}
-
- {/* Passwort-Dialog (kontrolliert) */}
- setPwOpen(e.open)}>
-
-
-
-
-
- {t("change-password")}
-
-
-
-
-
-
-
-
-
+ {userDialog && }
);
};
diff --git a/FrontendV2/src/components/UserDialogue.tsx b/FrontendV2/src/components/UserDialogue.tsx
new file mode 100644
index 0000000..d4e88b6
--- /dev/null
+++ b/FrontendV2/src/components/UserDialogue.tsx
@@ -0,0 +1,220 @@
+import {
+ Button,
+ Flex,
+ Stack,
+ Text,
+ CloseButton,
+ Dialog,
+ Portal,
+ HStack,
+ Box,
+ Avatar,
+ Card,
+ Grid,
+} from "@chakra-ui/react";
+import { PasswordInput } from "@/components/ui/password-input";
+import { RotateCcwKey } from "lucide-react";
+import MyAlert from "./myChakra/MyAlert";
+import { API_BASE } from "@/config/api.config";
+import { useUserContext } from "@/states/Context";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import Cookies from "js-cookie";
+
+type UserDialogueProps = {
+ setUserDialog: (value: boolean) => void;
+ fullname: string;
+ randomColor: string[];
+};
+
+export const UserDialogue = (props: UserDialogueProps) => {
+ const userData = useUserContext();
+ const { t } = useTranslation();
+ // Error handling states
+ const [isMsg, setIsMsg] = useState(false);
+ const [msgStatus, setMsgStatus] = useState<"error" | "success">("error");
+ const [msgTitle, setMsgTitle] = useState("");
+ const [msgDescription, setMsgDescription] = useState("");
+
+ const [oldPassword, setOldPassword] = useState("");
+ const [newPassword, setNewPassword] = useState("");
+ const [confirmPassword, setConfirmPassword] = useState("");
+
+ // Dialog control
+ const [isPwOpen, setPwOpen] = useState(false);
+
+ const changePassword = async () => {
+ if (newPassword !== confirmPassword) {
+ setMsgTitle(t("err_pw_change"));
+ setMsgDescription(t("pw_mismatch"));
+ setMsgStatus("error");
+ setIsMsg(true);
+ return;
+ }
+
+ const response = await fetch(`${API_BASE}/api/users/change-password`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${Cookies.get("token")}`,
+ },
+ body: JSON.stringify({ oldPassword, newPassword }),
+ });
+
+ if (!response.ok) {
+ setMsgTitle(t("err_pw_change"));
+ setMsgDescription(t("pw_mismatch"));
+ setMsgStatus("error");
+ setIsMsg(true);
+ return;
+ }
+
+ setMsgTitle(t("pw_success"));
+ setMsgDescription(t("pw_success_desc"));
+ setMsgStatus("success");
+ setIsMsg(true);
+
+ setOldPassword("");
+ setNewPassword("");
+ setConfirmPassword("");
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {t("user-info-desc")}
+
+
+
+
+
+
+ {t("first-name")}:
+
+ {userData.first_name}
+
+
+ {t("last-name")}:
+
+ {userData.last_name}
+
+
+ {t("username")}:
+
+ {userData.username}
+
+
+ {t("role")}:
+
+ {userData.role}
+
+
+ {t("admin-status")}:
+
+ {userData.is_admin ? t("yes") : t("no")}
+
+
+
+
+
+
+
+
+
+
+
+ {/* Passwort-Dialog (kontrolliert) */}
+ setPwOpen(e.open)}>
+
+
+
+
+
+ {t("change-password")}
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/FrontendV2/src/pages/NotFoundPage.tsx b/FrontendV2/src/pages/NotFoundPage.tsx
deleted file mode 100644
index b3c36f6..0000000
--- a/FrontendV2/src/pages/NotFoundPage.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from "react";
-
-export const NotFoundPage = () => {
- return (
- <>
-
- >
- )
-};
diff --git a/FrontendV2/src/utils/i18n/locales/de/de.json b/FrontendV2/src/utils/i18n/locales/de/de.json
index f9d361b..2d7cf8f 100644
--- a/FrontendV2/src/utils/i18n/locales/de/de.json
+++ b/FrontendV2/src/utils/i18n/locales/de/de.json
@@ -63,7 +63,7 @@
"timezone-info": "Die angezeigten Daten und Uhrzeiten werden in deutscher Zeitzone dargestellt und müssen auch so eingegeben werden.",
"optional-note": "Optionale Notiz",
"note": "Notiz",
- "user-info-desc": "Hier können Sie Ihre persönlichen Informationen einsehen und ändern.",
+ "user-info-desc": "Hier können Sie Ihre persönlichen Informationen einsehen und das Passwort ändern. Falls Sie weitere Änderungen benötigen, wenden Sie sich bitte an einen Administrator.",
"role": "Rolle",
"admin-status": "Admin-Status",
"first-name": "Vorname",
diff --git a/FrontendV2/src/utils/i18n/locales/en/en.json b/FrontendV2/src/utils/i18n/locales/en/en.json
index 8d8f891..8091bb0 100644
--- a/FrontendV2/src/utils/i18n/locales/en/en.json
+++ b/FrontendV2/src/utils/i18n/locales/en/en.json
@@ -63,7 +63,7 @@
"timezone-info": "The displayed dates and times are shown in Berlin timezone and must also be entered as such.",
"optional-note": "Optional note",
"note": "Note",
- "user-info-desc": "Here you can view and edit your personal information.",
+ "user-info-desc": "Here you can view your personal information and change your password. If you need to make further changes, please contact an administrator.",
"role": "Role",
"admin-status": "Admin status",
"first-name": "First name",
diff --git a/admin/nginx.conf b/admin/nginx.conf
index 4aa4fa8..cbb9122 100644
--- a/admin/nginx.conf
+++ b/admin/nginx.conf
@@ -9,6 +9,14 @@ server {
try_files $uri $uri/ /index.html;
}
+ location = /backend {
+ return 301 /backend/;
+ }
+
+ location /backend/ {
+ proxy_pass http://borrow_system-backend_v2:8004/;
+ }
+
location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 1y;
access_log off;
diff --git a/docker-compose.yml b/docker-compose.yml
index ea6314a..b8e5953 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -22,8 +22,6 @@ services:
networks:
- proxynet
build: ./backendV2
- ports:
- - "8102:8102"
environment:
NODE_ENV: production
DB_HOST: mysql_v2