diff --git a/backend/controllers/transaction.js b/backend/controllers/transaction.js index 1c0fe58..a641786 100644 --- a/backend/controllers/transaction.js +++ b/backend/controllers/transaction.js @@ -96,7 +96,7 @@ exports.getTransactionsByProduct = async (req, res) => { MIN(I.URL) AS Image_URL FROM Transaction T JOIN Product P ON T.ProductID = P.ProductID - LEFT JOIN Image_URL I ON P.ProductID = I.ProductID + JOIN Image_URL I ON I.ProductID = T.ProductID GROUP BY T.TransactionID, T.UserID, T.ProductID, T.Date, T.PaymentStatus, P.Name`, ); @@ -123,11 +123,19 @@ exports.getTransactionsByUser = async (req, res) => { T.Date, T.PaymentStatus, P.Name AS ProductName, - I.URL AS Image_URL + MIN(I.URL) AS Image_URL FROM Transaction T JOIN Product P ON T.ProductID = P.ProductID - LEFT JOIN Image_URL I ON P.ProductID = I.ProductID - WHERE T.UserID = ?`, + JOIN Image_URL I ON I.ProductID = T.ProductID + WHERE T.UserID = ? + GROUP BY + T.TransactionID, + T.UserID, + T.ProductID, + T.Date, + T.PaymentStatus, + P.Name; + `, [userID], ); @@ -155,7 +163,7 @@ exports.getAllTransactions = async (req, res) => { MIN(I.URL) AS Image_URL FROM Transaction T JOIN Product P ON T.ProductID = P.ProductID - LEFT JOIN Image_URL I ON P.ProductID = I.ProductID + JOIN Image_URL I ON P.ProductID = I.ProductID GROUP BY T.TransactionID, T.UserID, T.ProductID, T.Date, T.PaymentStatus, P.Name`, ); @@ -169,34 +177,6 @@ exports.getAllTransactions = async (req, res) => { } }; -// Update the payment status of a transaction -exports.updatePaymentStatus = async (req, res) => { - const { transactionID, paymentStatus } = req.body; - - try { - const [result] = await db.execute( - `UPDATE Transaction - SET PaymentStatus = ? - WHERE TransactionID = ?`, - [paymentStatus, transactionID], - ); - - if (result.affectedRows === 0) { - return res - .status(404) - .json({ success: false, message: "Transaction not found" }); - } - - res.json({ - success: true, - message: "Payment status updated successfully", - }); - } catch (error) { - console.error("Error updating payment status:", error); - res.status(500).json({ error: "Could not update payment status" }); - } -}; - // Delete a transaction exports.deleteTransaction = async (req, res) => { const { transactionID } = req.body; @@ -223,3 +203,24 @@ exports.deleteTransaction = async (req, res) => { res.status(500).json({ error: "Could not delete transaction" }); } }; + +exports.updateTransactionStatus = async (req, res) => { + const { transactionID } = req.body; + + try { + const [result] = await db.execute( + `UPDATE Transaction + SET PaymentStatus = 'completed' + WHERE TransactionID = ?;`, + [transactionID], + ); + + res.json({ + success: true, + message: "Transaction updated successfully", + }); + } catch (error) { + console.error("Error deleting transaction:", error); + res.status(500).json({ error: "Could not delete transaction" }); + } +}; diff --git a/backend/routes/transaction.js b/backend/routes/transaction.js index 30d4453..8817731 100644 --- a/backend/routes/transaction.js +++ b/backend/routes/transaction.js @@ -5,10 +5,10 @@ const { getTransactionsByProduct, getTransactionsByUser, getAllTransactions, - updatePaymentStatus, deleteTransaction, getTransactionWithPagination, removeTransation, + updateTransactionStatus, } = require("../controllers/transaction"); const router = express.Router(); @@ -18,24 +18,12 @@ router.use((req, res, next) => { next(); }); -// Create a new transaction router.post("/createTransaction", createTransaction); - -// Get all transactions for a specific product router.get("/getTransactionsByProduct/:productID", getTransactionsByProduct); - -// Get all transactions for a specific user router.post("/getTransactionsByUser", getTransactionsByUser); - -// Get all transactions in the system +router.post("/updateStatus", updateTransactionStatus); router.post("/getAllTransactions", getAllTransactions); - -// Update payment status on a transaction -router.patch("/updatePaymentStatus", updatePaymentStatus); - -// Delete a transaction router.delete("/deleteTransaction", deleteTransaction); - router.get("/getTransactions", getTransactionWithPagination); router.delete("/:id", removeTransation); diff --git a/frontend/src/pages/Transactions.jsx b/frontend/src/pages/Transactions.jsx index 84fff33..ea517eb 100644 --- a/frontend/src/pages/Transactions.jsx +++ b/frontend/src/pages/Transactions.jsx @@ -1,32 +1,45 @@ import { useState, useEffect } from "react"; import { Link } from "react-router-dom"; import { Calendar, CreditCard, Trash2 } from "lucide-react"; +import FloatingAlert from "../components/FloatingAlert"; // adjust path if needed const Transactions = () => { const [transactions, setTransactions] = useState([]); + const [showAlert, setShowAlert] = useState(false); + const storedUser = JSON.parse(sessionStorage.getItem("user")); + + function reloadPage() { + const docTimestamp = new Date(performance.timing.domLoading).getTime(); + const now = Date.now(); + if (now > docTimestamp) { + location.reload(); + } + } useEffect(() => { const fetchTransactions = async () => { try { const response = await fetch( - "http://localhost:3030/api/transaction/getAllTransactions", + "http://localhost:3030/api/transaction/getTransactionsByUser", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ userID: 1 }), // replace with actual userID + body: JSON.stringify({ userID: storedUser.ID }), }, ); if (!response.ok) throw new Error(`HTTP ${response.status}`); const { transactions: txData } = await response.json(); if (!Array.isArray(txData)) return; + console.log(txData); + setTransactions( txData.map((tx) => ({ id: tx.TransactionID, productId: tx.ProductID, - name: tx.ProductName || "Unnamed Product", + name: tx.ProductName, price: tx.Price != null ? parseFloat(tx.Price) : null, - image: tx.Image_URL || "/default-image.jpg", + image: tx.Image_URL, date: tx.Date, status: tx.PaymentStatus, })), @@ -52,6 +65,7 @@ const Transactions = () => { const data = await res.json(); if (data.success) { setTransactions((prev) => prev.filter((tx) => tx.id !== id)); + reloadPage(); } else { console.error("Delete failed:", data.message); } @@ -60,6 +74,26 @@ const Transactions = () => { } }; + const updateTransaction = async (id) => { + try { + const res = await fetch( + "http://localhost:3030/api/transaction/updateStatus", + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ transactionID: id }), + }, + ); + const data = await res.json(); + if (data) { + setShowAlert(true); + reloadPage(); + } + } catch (err) { + console.error("Error deleting transaction:", err); + } + }; + const formatDate = (dateString) => { const d = new Date(dateString); return d.toLocaleDateString("en-US", { @@ -71,6 +105,12 @@ const Transactions = () => { return (
+ {showAlert && ( + setShowAlert(false)} + /> + )}

My Transactions

@@ -99,28 +139,34 @@ const Transactions = () => { key={tx.id} className="relative border-2 border-gray-200 overflow-hidden hover:shadow-md transition-shadow" > - {/* Delete Button */} - +
+ + +
- {tx.image ? ( - {tx.name} - ) : ( -
No image
- )} + {tx.name}

diff --git a/mysql-code/Init-Data.sql b/mysql-code/Init-Data.sql index 620f066..d0ae96c 100644 --- a/mysql-code/Init-Data.sql +++ b/mysql-code/Init-Data.sql @@ -370,7 +370,6 @@ VALUES (1, 5), -- User 4 likes Basketball (2, 8); --- User 5 likes Mini Fridge -- Insert Transactions INSERT INTO Transaction (