From cffe8fd252509e66892a78af5c63915d79ffabd7 Mon Sep 17 00:00:00 2001 From: ssbg04 Date: Fri, 24 Apr 2026 15:36:13 +0800 Subject: [PATCH] add issued logs --- assets/js/issued.js | 120 +++++++++++++++++++++++++++++++++++++++++++ assets/js/main.js | 14 ++++- includes/api/api.php | 22 ++++++++ includes/db/db.php | 6 +-- includes/footer.php | 3 +- pages/issued.php | 47 +++++++++++++++++ partials/navbar.php | 5 ++ 7 files changed, 212 insertions(+), 5 deletions(-) create mode 100644 assets/js/issued.js create mode 100644 pages/issued.php diff --git a/assets/js/issued.js b/assets/js/issued.js new file mode 100644 index 0000000..4e13f2d --- /dev/null +++ b/assets/js/issued.js @@ -0,0 +1,120 @@ +// ========================================== +// ISSUED ITEMS LOGIC (issued.js) +// ========================================== +$(document).ready(function () { + + let allIssuedData = []; + let filteredIssuedData = []; + let issuedCurrentPage = 1; + const issuedItemsPerPage = 5; // Show 10 rows per page + + window.loadIssuedItems = function (btn = null) { + let originalText = ""; + if (btn) { + originalText = $(btn).html(); + $(btn).prop("disabled", true).html(' Refreshing...'); + } + + $.ajax({ + url: "includes/api/api.php?action=get_issued_items", + type: "GET", + cache: false, + dataType: "json", + success: function (res) { + if (btn) $(btn).prop("disabled", false).html(originalText); + if (res.status === "success") { + allIssuedData = res.data; + applyIssuedFilters(); + } else { + showAlert("Error loading issued items.", "danger"); + } + }, + error: function() { + if (btn) $(btn).prop("disabled", false).html(originalText); + showAlert("Network error.", "danger"); + } + }); + }; + + function applyIssuedFilters() { + if ($("#searchIssuedInput").length === 0) return; // Failsafe + + let search = $("#searchIssuedInput").val().toLowerCase(); + let dateFrom = $("#filterIssuedDateFrom").val(); + let dateTo = $("#filterIssuedDateTo").val(); + + filteredIssuedData = allIssuedData.filter(function (txn) { + let matchesSearch = txn.name.toLowerCase().includes(search) || + txn.transaction_id.toString().includes(search) || + (txn.description && txn.description.toLowerCase().includes(search)); + + // Convert dates to YYYY-MM-DD for accurate comparison + let txnDate = txn.transaction_date.split(' ')[0]; + + let matchesDateFrom = dateFrom === "" || txnDate >= dateFrom; + let matchesDateTo = dateTo === "" || txnDate <= dateTo; + + return matchesSearch && matchesDateFrom && matchesDateTo; + }); + + issuedCurrentPage = 1; + renderIssuedTable(); + } + + $(document).on("keyup", "#searchIssuedInput", applyIssuedFilters); + $(document).on("change", "#filterIssuedDateFrom, #filterIssuedDateTo", applyIssuedFilters); + + function renderIssuedTable() { + let rows = ""; + let totalItems = filteredIssuedData.length; + let totalPages = Math.ceil(totalItems / issuedItemsPerPage) || 1; + let startIndex = (issuedCurrentPage - 1) * issuedItemsPerPage; + let endIndex = Math.min(startIndex + issuedItemsPerPage, totalItems); + let pageData = filteredIssuedData.slice(startIndex, endIndex); + + if (pageData.length === 0) { + rows = `No transactions found matching your criteria.`; + } else { + pageData.forEach(function (txn) { + // Format date to look nice (e.g., "April 24, 2026 - 3:21 PM") + let dateObj = new Date(txn.transaction_date); + let formattedDate = dateObj.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) + + " " + dateObj.toLocaleTimeString('en-US', { hour: '2-digit', minute:'2-digit' }) + ""; + + rows += ` + #TXN-${txn.transaction_id} + ${formattedDate} + +
${txn.name}
+
Item ID: #${txn.inventory_id}
+ + + + ${txn.qty_issued} + + + `; + }); + } + + $("#issuedTableBody").html(rows); + if (totalItems > 0) $("#issuedPaginationInfo").text(`Showing ${startIndex + 1} to ${endIndex} of ${totalItems} entries`); + else $("#issuedPaginationInfo").text("Showing 0 entries"); + + renderIssuedPagination(totalPages); + } + + function renderIssuedPagination(totalPages) { + let html = `
  • Previous
  • `; + for (let i = 1; i <= totalPages; i++) { + html += `
  • ${i}
  • `; + } + html += `
  • Next
  • `; + $("#issuedPaginationControls").html(html); + } + + window.changeIssuedPage = function(newPage) { + issuedCurrentPage = newPage; + renderIssuedTable(); + }; +}); \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index bf55bd6..34669dc 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -25,12 +25,22 @@ let spendChartInstance = null; // 2. GLOBAL HELPER FUNCTIONS // ========================================== function showAlert(msg, type) { + // Create a unique ID for this alert so the timer doesn't accidentally hide a newer alert + let alertId = 'alert-' + Date.now(); + $("#alertBox").html(` -
    +
    ${msg}
    `); + + // Auto-hide the alert after 4 seconds (4000 milliseconds) + setTimeout(function() { + $("#" + alertId).fadeOut(400, function() { + $(this).remove(); // Completely removes it from the screen + }); + }, 4000); } // ========================================== @@ -48,6 +58,8 @@ function initPageScripts(page) { if (typeof loadAnalytics === "function") loadAnalytics(); } else if (page === "vendors") { if (typeof loadVendors === "function") loadVendors(); + } else if (page === "issued") { + if (typeof loadIssuedItems === "function") loadIssuedItems(); } } diff --git a/includes/api/api.php b/includes/api/api.php index df8c199..858b63a 100644 --- a/includes/api/api.php +++ b/includes/api/api.php @@ -144,6 +144,28 @@ switch ($action) { echo json_encode(['status' => 'success', 'data' => $items]); break; + case 'get_issued_items': + try { + // Join transactions with inventory to get the item names + $stmt = $pdo->query(" + SELECT + t.transaction_id, + t.transaction_date, + t.qty_issued, + i.inventory_id, + i.name, + i.description + FROM inventory_transactions t + JOIN inventory_items i ON t.inventory_id = i.inventory_id + ORDER BY t.transaction_date DESC + "); + $data = $stmt->fetchAll(PDO::FETCH_ASSOC); + echo json_encode(['status' => 'success', 'data' => $data]); + } catch (Exception $e) { + echo json_encode(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]); + } + break; + // --------------------------------------------------------- // NEW VENDOR MANAGEMENT ENDPOINTS // --------------------------------------------------------- diff --git a/includes/db/db.php b/includes/db/db.php index 41be8cd..946ad83 100644 --- a/includes/db/db.php +++ b/includes/db/db.php @@ -5,9 +5,6 @@ // $username = 'root'; // Change if your DB user is different // $password = ''; // Change if your DB has a password // $port = 3306; -// require_once __DIR__ . "/../env_loader.php"; -// loadEnv(__DIR__ . "/../../.env"); - // var_dump([ // "DB_HOST" => getenv("DB_HOST"), // "DB_PORT" => getenv("DB_PORT"), @@ -17,6 +14,9 @@ // ]); // exit; +// require_once __DIR__ . "/../env_loader.php"; +// loadEnv(__DIR__ . "/../../.env"); + $host = getenv("DB_HOST"); $port = getenv("DB_PORT"); $db_name = getenv("DB_NAME"); diff --git a/includes/footer.php b/includes/footer.php index 3f68ead..7ce8966 100644 --- a/includes/footer.php +++ b/includes/footer.php @@ -4,4 +4,5 @@ - \ No newline at end of file + + \ No newline at end of file diff --git a/pages/issued.php b/pages/issued.php new file mode 100644 index 0000000..9cb135b --- /dev/null +++ b/pages/issued.php @@ -0,0 +1,47 @@ +
    +

    Issued Items Log

    +
    + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    + +
    +
    + +
    + + + + + + + + + + + +
    Txn IDDate IssuedItem DetailsQty Issued
    +
    + +
    +
    Showing 0 entries
    +
      +
      +
      +
      \ No newline at end of file diff --git a/partials/navbar.php b/partials/navbar.php index d52570a..fb9d08b 100644 --- a/partials/navbar.php +++ b/partials/navbar.php @@ -5,6 +5,11 @@ Inventory View +