diff --git a/admin/src/Layout/Layout.tsx b/admin/src/Layout/Layout.tsx index e64af0f..baca51f 100644 --- a/admin/src/Layout/Layout.tsx +++ b/admin/src/Layout/Layout.tsx @@ -5,6 +5,11 @@ import Login from "./Login"; import Cookies from "js-cookie"; import Landingpage from "@/components/API/Landingpage"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + const Layout: React.FC = () => { const [isLoggedIn, setIsLoggedIn] = useState(false); const [showAPI, setShowAPI] = useState(false); @@ -19,7 +24,7 @@ const Layout: React.FC = () => { if (Cookies.get("token")) { const verifyToken = async () => { - const response = await fetch("https://backend.insta.the1s.de/api/verifyToken", { + const response = await fetch(`${API_BASE}/api/verifyToken`, { method: "GET", headers: { Authorization: `Bearer ${Cookies.get("token")}`, diff --git a/admin/src/components/API/Landingpage.tsx b/admin/src/components/API/Landingpage.tsx index 0530a7b..5388f7f 100644 --- a/admin/src/components/API/Landingpage.tsx +++ b/admin/src/components/API/Landingpage.tsx @@ -14,6 +14,11 @@ import { Lock, LockOpen } from "lucide-react"; import MyAlert from "../myChakra/MyAlert"; import { formatDateTime } from "@/utils/userFuncs"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + type Loan = { id: number; username: string; @@ -57,9 +62,7 @@ const Landingpage: React.FC = () => { const fetchData = async () => { setIsLoading(true); try { - const loanRes = await fetch( - "https://backend.insta.the1s.de/apiV2/allLoans" - ); + const loanRes = await fetch(`${API_BASE}/apiV2/allLoans`); const loanData = await loanRes.json(); if (Array.isArray(loanData)) { setLoans(loanData); @@ -71,9 +74,7 @@ const Landingpage: React.FC = () => { ); } - const deviceRes = await fetch( - "https://backend.insta.the1s.de/apiV2/allItems" - ); + const deviceRes = await fetch(`${API_BASE}/apiV2/allItems`); const deviceData = await deviceRes.json(); if (Array.isArray(deviceData)) { setDevices(deviceData); diff --git a/admin/src/components/APIKeyTable.tsx b/admin/src/components/APIKeyTable.tsx index 184995e..f90769d 100644 --- a/admin/src/components/APIKeyTable.tsx +++ b/admin/src/components/APIKeyTable.tsx @@ -18,6 +18,11 @@ import { deleteAPKey } from "@/utils/userActions"; import AddAPIKey from "./AddAPIKey"; import { formatDateTime } from "@/utils/userFuncs"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + type Items = { id: number; apiKey: string; @@ -51,7 +56,7 @@ const APIKeyTable: React.FC = () => { const fetchData = async () => { setIsLoading(true); try { - const response = await fetch("https://backend.insta.the1s.de/api/apiKeys", { + const response = await fetch(`${API_BASE}/api/apiKeys`, { method: "GET", headers: { Authorization: `Bearer ${Cookies.get("token")}`, diff --git a/admin/src/components/AddItemForm.tsx b/admin/src/components/AddItemForm.tsx index 5780a94..19336df 100644 --- a/admin/src/components/AddItemForm.tsx +++ b/admin/src/components/AddItemForm.tsx @@ -33,7 +33,7 @@ const AddItemForm: React.FC = ({ onClose, alert }) => { diff --git a/admin/src/components/ItemTable.tsx b/admin/src/components/ItemTable.tsx index da45f16..8c2b3b4 100644 --- a/admin/src/components/ItemTable.tsx +++ b/admin/src/components/ItemTable.tsx @@ -31,6 +31,11 @@ import { import AddItemForm from "./AddItemForm"; import { formatDateTime } from "@/utils/userFuncs"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + type Items = { id: number; item_name: string; @@ -77,7 +82,7 @@ const ItemTable: React.FC = () => { const fetchData = async () => { setIsLoading(true); try { - const response = await fetch("https://backend.insta.the1s.de/api/allItems", { + const response = await fetch(`${API_BASE}/api/allItems`, { method: "GET", headers: { Authorization: `Bearer ${Cookies.get("token")}`, diff --git a/admin/src/components/LoanTable.tsx b/admin/src/components/LoanTable.tsx index 5498cf6..8523ae4 100644 --- a/admin/src/components/LoanTable.tsx +++ b/admin/src/components/LoanTable.tsx @@ -18,6 +18,11 @@ import { formatDateTime } from "@/utils/userFuncs"; import { Trash2, RefreshCcwDot } from "lucide-react"; import { deleteLoan } from "@/utils/userActions"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + const LoanTable: React.FC = () => { const [items, setItems] = useState([]); const [errorStatus, setErrorStatus] = useState<"error" | "success">("error"); @@ -55,7 +60,7 @@ const LoanTable: React.FC = () => { const fetchData = async () => { setIsLoading(true); try { - const response = await fetch("https://backend.insta.the1s.de/api/allLoans", { + const response = await fetch(`${API_BASE}/api/allLoans`, { method: "GET", headers: { Authorization: `Bearer ${Cookies.get("token")}`, diff --git a/admin/src/utils/fetcher.ts b/admin/src/utils/fetcher.ts index fbab133..9b9ab80 100644 --- a/admin/src/utils/fetcher.ts +++ b/admin/src/utils/fetcher.ts @@ -1,7 +1,12 @@ import Cookies from "js-cookie"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + export const fetchUserData = async () => { - const response = await fetch("https://backend.insta.the1s.de/api/allUsers", { + const response = await fetch(`${API_BASE}/api/allUsers`, { headers: { Authorization: `Bearer ${Cookies.get("token")}`, }, diff --git a/admin/src/utils/loginUser.ts b/admin/src/utils/loginUser.ts index d72cc58..7d18cd5 100644 --- a/admin/src/utils/loginUser.ts +++ b/admin/src/utils/loginUser.ts @@ -1,5 +1,10 @@ import Cookies from "js-cookie"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + export type LoginSuccess = { success: true }; export type LoginFailure = { success: false; @@ -13,7 +18,7 @@ export const loginFunc = async ( password: string ): Promise => { try { - const response = await fetch("https://backend.insta.the1s.de/api/loginAdmin", { + const response = await fetch(`${API_BASE}/api/loginAdmin`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), diff --git a/admin/src/utils/userActions.ts b/admin/src/utils/userActions.ts index dbbea17..c3644fc 100644 --- a/admin/src/utils/userActions.ts +++ b/admin/src/utils/userActions.ts @@ -1,9 +1,14 @@ import Cookies from "js-cookie"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + export const handleDelete = async (userId: number) => { try { const response = await fetch( - `https://backend.insta.the1s.de/api/deleteUser/${userId}`, + `${API_BASE}/api/deleteUser/${userId}`, { method: "DELETE", headers: { @@ -28,7 +33,7 @@ export const handleEdit = async ( ) => { try { const response = await fetch( - `https://backend.insta.the1s.de/api/editUser/${userId}`, + `${API_BASE}/api/editUser/${userId}`, { method: "POST", headers: { @@ -54,17 +59,14 @@ export const createUser = async ( password: string ) => { try { - const response = await fetch( - `https://backend.insta.the1s.de/api/createUser`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${Cookies.get("token")}`, - }, - body: JSON.stringify({ username, role, password }), - } - ); + const response = await fetch(`${API_BASE}/api/createUser`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${Cookies.get("token")}`, + }, + body: JSON.stringify({ username, role, password }), + }); if (!response.ok) { throw new Error("Failed to create user"); } @@ -77,17 +79,14 @@ export const createUser = async ( export const changePW = async (newPassword: string, username: string) => { try { - const response = await fetch( - `https://backend.insta.the1s.de/api/changePWadmin`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${Cookies.get("token")}`, - }, - body: JSON.stringify({ newPassword, username }), - } - ); + const response = await fetch(`${API_BASE}/api/changePWadmin`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${Cookies.get("token")}`, + }, + body: JSON.stringify({ newPassword, username }), + }); if (!response.ok) { throw new Error("Failed to change password"); } @@ -101,7 +100,7 @@ export const changePW = async (newPassword: string, username: string) => { export const deleteLoan = async (loanId: number) => { try { const response = await fetch( - `https://backend.insta.the1s.de/api/deleteLoan/${loanId}`, + `${API_BASE}/api/deleteLoan/${loanId}`, { method: "DELETE", headers: { @@ -122,7 +121,7 @@ export const deleteLoan = async (loanId: number) => { export const deleteItem = async (itemId: number) => { try { const response = await fetch( - `https://backend.insta.the1s.de/api/deleteItem/${itemId}`, + `${API_BASE}/api/deleteItem/${itemId}`, { method: "DELETE", headers: { @@ -145,17 +144,14 @@ export const createItem = async ( can_borrow_role: number ) => { try { - const response = await fetch( - `https://backend.insta.the1s.de/api/createItem`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${Cookies.get("token")}`, - }, - body: JSON.stringify({ item_name, can_borrow_role }), - } - ); + const response = await fetch(`${API_BASE}/api/createItem`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${Cookies.get("token")}`, + }, + body: JSON.stringify({ item_name, can_borrow_role }), + }); if (!response.ok) { return { success: false, @@ -176,17 +172,14 @@ export const handleEditItems = async ( can_borrow_role: string ) => { try { - const response = await fetch( - "https://backend.insta.the1s.de/api/updateItemByID", - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${Cookies.get("token")}`, - }, - body: JSON.stringify({ itemId, item_name, can_borrow_role }), - } - ); + const response = await fetch(`${API_BASE}/api/updateItemByID`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${Cookies.get("token")}`, + }, + body: JSON.stringify({ itemId, item_name, can_borrow_role }), + }); if (!response.ok) { throw new Error("Failed to edit item"); } @@ -200,7 +193,7 @@ export const handleEditItems = async ( export const changeSafeState = async (itemId: number) => { try { const response = await fetch( - `https://backend.insta.the1s.de/api/changeSafeState/${itemId}`, + `${API_BASE}/api/changeSafeState/${itemId}`, { method: "PUT", headers: { @@ -220,7 +213,7 @@ export const changeSafeState = async (itemId: number) => { export const createAPIentry = async (apiKey: string, user: string) => { try { - const response = await fetch(`https://backend.insta.the1s.de/api/createAPIentry`, { + const response = await fetch(`${API_BASE}/api/createAPIentry`, { method: "POST", headers: { "Content-Type": "application/json", @@ -245,7 +238,7 @@ export const createAPIentry = async (apiKey: string, user: string) => { export const deleteAPKey = async (apiKeyId: number) => { try { const response = await fetch( - `https://backend.insta.the1s.de/api/deleteAPKey/${apiKeyId}`, + `${API_BASE}/api/deleteAPKey/${apiKeyId}`, { method: "DELETE", headers: { diff --git a/backend/routes/api.js b/backend/routes/api.js index 103eeef..64e9a06 100644 --- a/backend/routes/api.js +++ b/backend/routes/api.js @@ -91,6 +91,11 @@ function buildLoanEmail({ user, items, startDate, endDate, createdDate }) { )} +

+ + Zur Übersicht aller Ausleihen + +

Diese E-Mail wurde automatisch vom Ausleihsystem gesendet. Bitte nicht antworten.

@@ -145,7 +150,6 @@ function sendMailLoan(user, items, startDate, endDate, createdDate) { console.log("sendMailLoan called"); } -// ...existing code... const formatDateTime = (value) => { if (value == null) return "N/A"; @@ -177,7 +181,6 @@ const formatDateTime = (value) => { return "N/A"; }; -// ...existing code... router.post("/login", async (req, res) => { const result = await loginFunc(req.body.username, req.body.password); diff --git a/frontend/src/components/Form4.tsx b/frontend/src/components/Form4.tsx index f3e47de..bcc023c 100644 --- a/frontend/src/components/Form4.tsx +++ b/frontend/src/components/Form4.tsx @@ -19,6 +19,11 @@ type Loan = { loaned_items_name: string[]; }; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + const formatDate = (iso: string | null) => { if (!iso) return "-"; const m = iso.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/); @@ -28,7 +33,7 @@ const formatDate = (iso: string | null) => { }; async function fetchUserLoans(): Promise { - const res = await fetch("https://backend.insta.the1s.de/api/userLoans", { + const res = await fetch(`${API_BASE}/api/userLoans`, { method: "GET", headers: { Authorization: `Bearer ${Cookies.get("token") || ""}` }, }); diff --git a/frontend/src/utils/fetchData.ts b/frontend/src/utils/fetchData.ts index c8a92ad..fe56a00 100644 --- a/frontend/src/utils/fetchData.ts +++ b/frontend/src/utils/fetchData.ts @@ -6,6 +6,11 @@ export const ALL_ITEMS_UPDATED_EVENT = "allItemsUpdated"; export const BORROWABLE_ITEMS_UPDATED_EVENT = "borrowableItemsUpdated"; export const AUTH_LOGOUT_EVENT = "authLogout"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + let sendError = false; function logout() { @@ -25,7 +30,7 @@ export const fetchAllData = async (token: string | undefined) => { if (!token) return; // First we fetch all items that are potentially available for borrowing try { - const response = await fetch("https://backend.insta.the1s.de/api/items", { + const response = await fetch(`${API_BASE}/api/items`, { method: "GET", headers: { Authorization: `Bearer ${token}`, @@ -57,7 +62,7 @@ export const fetchAllData = async (token: string | undefined) => { // get all loans try { - const response = await fetch("https://backend.insta.the1s.de/api/loans", { + const response = await fetch(`${API_BASE}/api/loans`, { method: "GET", headers: { Authorization: `Bearer ${token}`, @@ -89,7 +94,7 @@ export const fetchAllData = async (token: string | undefined) => { // get user loans try { - const response = await fetch("https://backend.insta.the1s.de/api/userLoans", { + const response = await fetch(`${API_BASE}/api/userLoans`, { method: "GET", headers: { Authorization: `Bearer ${token}`, @@ -122,7 +127,7 @@ export const fetchAllData = async (token: string | undefined) => { export const loginUser = async (username: string, password: string) => { try { - const response = await fetch("https://backend.insta.the1s.de/api/login", { + const response = await fetch(`${API_BASE}/api/login`, { method: "POST", headers: { "Content-Type": "application/json", @@ -158,7 +163,7 @@ export const getBorrowableItems = async () => { } try { - const response = await fetch("https://backend.insta.the1s.de/api/borrowableItems", { + const response = await fetch(`${API_BASE}/api/borrowableItems`, { method: "POST", headers: { Authorization: `Bearer ${Cookies.get("token") || ""}`, diff --git a/frontend/src/utils/userHandler.ts b/frontend/src/utils/userHandler.ts index 2491199..0be8440 100644 --- a/frontend/src/utils/userHandler.ts +++ b/frontend/src/utils/userHandler.ts @@ -2,10 +2,15 @@ import { myToast } from "./toastify"; import Cookies from "js-cookie"; import { queryClient } from "./queryClient"; +const API_BASE = + (import.meta as any).env?.VITE_BACKEND_URL || + import.meta.env.VITE_BACKEND_URL || + "http://localhost:8002"; + export const handleDeleteLoan = async (loanID: number): Promise => { try { const response = await fetch( - `https://backend.insta.the1s.de/api/deleteLoan/${loanID}`, + `${API_BASE}/api/deleteLoan/${loanID}`, { method: "DELETE", headers: { @@ -75,17 +80,14 @@ export const rmFromRemove = (itemID: number) => { export const createLoan = async (startDate: string, endDate: string) => { const items = removeArr; - const response = await fetch( - "https://backend.insta.the1s.de/api/createLoan", - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${Cookies.get("token") || ""}`, - }, - body: JSON.stringify({ items, startDate, endDate }), - } - ); + const response = await fetch(`${API_BASE}/api/createLoan`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${Cookies.get("token") || ""}`, + }, + body: JSON.stringify({ items, startDate, endDate }), + }); if (!response.ok) { myToast("Fehler beim Erstellen der Ausleihe", "error"); @@ -106,7 +108,7 @@ export const createLoan = async (startDate: string, endDate: string) => { export const onReturn = async (loanID: number) => { const response = await fetch( - `https://backend.insta.the1s.de/api/returnLoan/${loanID}`, + `${API_BASE}/api/returnLoan/${loanID}`, { method: "POST", headers: { @@ -125,15 +127,12 @@ export const onReturn = async (loanID: number) => { }; export const onTake = async (loanID: number) => { - const response = await fetch( - `https://backend.insta.the1s.de/api/takeLoan/${loanID}`, - { - method: "POST", - headers: { - Authorization: `Bearer ${Cookies.get("token") || ""}`, - }, - } - ); + const response = await fetch(`${API_BASE}/api/takeLoan/${loanID}`, { + method: "POST", + headers: { + Authorization: `Bearer ${Cookies.get("token") || ""}`, + }, + }); if (!response.ok) { myToast("Fehler beim Ausleihen der Ausleihe", "error"); @@ -145,17 +144,14 @@ export const onTake = async (loanID: number) => { }; export const changePW = async (oldPassword: string, newPassword: string) => { - const response = await fetch( - "https://backend.insta.the1s.de/api/changePassword", - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${Cookies.get("token") || ""}`, - }, - body: JSON.stringify({ oldPassword, newPassword }), - } - ); + const response = await fetch(`${API_BASE}/api/changePassword`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${Cookies.get("token") || ""}`, + }, + body: JSON.stringify({ oldPassword, newPassword }), + }); if (!response.ok) { myToast("Fehler beim Ändern des Passworts", "error");