From 478f03452d46018ac39e9b02b5ddb605c4575b32 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Thu, 28 Aug 2025 21:12:58 +0200 Subject: [PATCH] added take and return setter buttons --- backend/routes/api.js | 22 ++++++++++ backend/services/database.js | 26 ++++++++++++ frontend/src/components/Form4.tsx | 67 ++++++++++++++++++++++++++++--- frontend/src/utils/userHandler.ts | 37 +++++++++++++++++ 4 files changed, 147 insertions(+), 5 deletions(-) diff --git a/backend/routes/api.js b/backend/routes/api.js index 4b23e96..f0e7a2a 100644 --- a/backend/routes/api.js +++ b/backend/routes/api.js @@ -7,6 +7,8 @@ import { deleteLoanFromDatabase, getBorrowableItemsFromDatabase, createLoanInDatabase, + onTake, + onReturn, } from "../services/database.js"; import { authenticate, generateToken } from "../services/tokenService.js"; const router = express.Router(); @@ -85,6 +87,26 @@ router.post("/borrowableItems", authenticate, async (req, res) => { } }); +router.post("/takeLoan/:id", authenticate, async (req, res) => { + const loanId = req.params.id; + const result = await onTake(loanId); + if (result.success) { + res.status(200).json({ message: "Loan taken successfully" }); + } else { + res.status(500).json({ message: "Failed to take loan" }); + } +}); + +router.post("/returnLoan/:id", authenticate, async (req, res) => { + const loanId = req.params.id; + const result = await onReturn(loanId); + if (result.success) { + res.status(200).json({ message: "Loan returned successfully" }); + } else { + res.status(500).json({ message: "Failed to return loan" }); + } +}); + router.post("/createLoan", authenticate, async (req, res) => { try { const { items, startDate, endDate } = req.body || {}; diff --git a/backend/services/database.js b/backend/services/database.js index fb7e57a..5326268 100644 --- a/backend/services/database.js +++ b/backend/services/database.js @@ -293,3 +293,29 @@ export const createLoanInDatabase = async ( conn.release(); } }; + +// These functions are only temporary, and will be deleted when the full bin is set up. + +export const onTake = async (loanId) => { + const [result] = await pool.query( + "UPDATE loans SET take_date = NOW() WHERE id = ?", + [loanId] + ); + + if (result.affectedRows > 0) { + return { success: true }; + } + return { success: false }; +}; + +export const onReturn = async (loanId) => { + const [result] = await pool.query( + "UPDATE loans SET returned_date = NOW() WHERE id = ?", + [loanId] + ); + + if (result.affectedRows > 0) { + return { success: true }; + } + return { success: false }; +}; diff --git a/frontend/src/components/Form4.tsx b/frontend/src/components/Form4.tsx index c4ed1f7..06832e6 100644 --- a/frontend/src/components/Form4.tsx +++ b/frontend/src/components/Form4.tsx @@ -4,6 +4,7 @@ import { handleDeleteLoan } from "../utils/userHandler"; import { useMutation, useQuery } from "@tanstack/react-query"; import Cookies from "js-cookie"; import { queryClient } from "../utils/queryClient"; +import { onTake, onReturn } from "../utils/userHandler"; type Loan = { id: number; @@ -49,6 +50,20 @@ const Form4: React.FC = () => { }, }); + const takeMutation = useMutation({ + mutationFn: (loanID: number) => onTake(loanID), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["userLoans"] }); + }, + }); + + const returnMutation = useMutation({ + mutationFn: (loanID: number) => onReturn(loanID), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["userLoans"] }); + }, + }); + const onDelete = (loanID: number) => deleteMutation.mutate(loanID); if (isFetching) { @@ -99,11 +114,32 @@ const Form4: React.FC = () => {
Abgeholt:{" "} - {formatDate(loan.take_date)} + {loan.take_date ? ( + formatDate(loan.take_date) + ) : ( + + )}
Zurück:{" "} - {formatDate(loan.returned_date)} + {loan.returned_date ? ( + formatDate(loan.returned_date) + ) : ( + + )}
@@ -170,10 +206,31 @@ const Form4: React.FC = () => { {formatDate(loan.end_date)} - {formatDate(loan.take_date)} + {loan.take_date ? ( + formatDate(loan.take_date) + ) : ( + + )} - {formatDate(loan.returned_date)} + {loan.returned_date ? ( + formatDate(loan.returned_date) + ) : ( + + )} {formatDate(loan.created_at)} @@ -182,7 +239,7 @@ const Form4: React.FC = () => {
{Array.isArray(loan.loaned_items_name) ? loan.loaned_items_name.join(", ") - : "-"} + : ""}
diff --git a/frontend/src/utils/userHandler.ts b/frontend/src/utils/userHandler.ts index d589d17..625803c 100644 --- a/frontend/src/utils/userHandler.ts +++ b/frontend/src/utils/userHandler.ts @@ -100,3 +100,40 @@ export const createLoan = async (startDate: string, endDate: string) => { return true; }; + +export const onReturn = async (loanID: number) => { + const response = await fetch( + `http://localhost:8002/api/returnLoan/${loanID}`, + { + method: "POST", + headers: { + Authorization: `Bearer ${Cookies.get("token") || ""}`, + }, + } + ); + + if (!response.ok) { + myToast("Fehler beim Zurückgeben der Ausleihe", "error"); + return false; + } + + myToast("Ausleihe erfolgreich zurückgegeben!", "success"); + return true; +}; + +export const onTake = async (loanID: number) => { + const response = await fetch(`http://localhost:8002/api/takeLoan/${loanID}`, { + method: "POST", + headers: { + Authorization: `Bearer ${Cookies.get("token") || ""}`, + }, + }); + + if (!response.ok) { + myToast("Fehler beim Ausleihen der Ausleihe", "error"); + return false; + } + + myToast("Ausleihe erfolgreich ausgeliehen!", "success"); + return true; +};