diff --git a/footer.php b/footer.php
index 655a6742..0c4364cf 100644
--- a/footer.php
+++ b/footer.php
@@ -15,6 +15,7 @@
+
@@ -26,6 +27,7 @@
+
diff --git a/js/header_timers.js b/js/header_timers.js
new file mode 100644
index 00000000..b7059480
--- /dev/null
+++ b/js/header_timers.js
@@ -0,0 +1,147 @@
+// ticketCounter.js
+(function() {
+ function getRunningTicketCount() {
+ let count = 0;
+ for (let i = 0; i < localStorage.length; i++) {
+ let key = localStorage.key(i);
+ if (key.includes("ticket-timer-running")) {
+ let isRunning = JSON.parse(localStorage.getItem(key));
+ if (isRunning) {
+ count++;
+ }
+ }
+ }
+ return count;
+ }
+
+ function updateTicketCountDisplay() {
+ let count = getRunningTicketCount();
+ let countDisplay = document.getElementById("runningTicketsCount");
+ if (countDisplay) {
+ countDisplay.innerText = count;
+ }
+ if (count == 0) {
+ countDisplay.classList.remove('badge-danger');
+ } else {
+ //check to see if more than one ticket
+ if (count > 1) {
+ countDisplay.classList.add('badge-danger');
+ }
+ //if count is one, check to see if its open in the current window by looking at the post variable ticket_id in url
+ if (count == 1) {
+ let urlParams = new URLSearchParams(window.location.search);
+ let ticketID = urlParams.get('ticket_id');
+ console.log(ticketID);
+ // If ticket number equals one in local storage, then add badge-danger class
+ if (localStorage.getItem("ticket-timer-running-") == ticketID) {
+ countDisplay.classList.add('badge-danger');
+ } else {
+ countDisplay.classList.remove('badge-danger');
+ }
+ }
+ }
+ }
+
+ function getElapsedSeconds(ticketID) {
+ let storedStartTime = parseInt(localStorage.getItem(ticketID + "-startTime") || "0");
+ let pausedTime = parseInt(localStorage.getItem(ticketID + "-pausedTime") || "0");
+ if (!storedStartTime) return pausedTime;
+ let timeSinceStart = Math.floor((Date.now() - storedStartTime) / 1000);
+ return pausedTime + timeSinceStart;
+ }
+
+ function formatTime(seconds) {
+ let hours = Math.floor(seconds / 3600);
+ let minutes = Math.floor((seconds % 3600) / 60);
+ let secs = seconds % 60;
+ return `${hours}h ${minutes}m ${secs}s`;
+ }
+
+ function loadOpenTickets() {
+ let openTicketsContainer = document.getElementById('openTicketsContainer');
+ openTicketsContainer.innerHTML = ''; // Clear existing content
+
+ for (let i = 0; i < localStorage.length; i++) {
+ let key = localStorage.key(i);
+
+ if (key.startsWith("ticket-timer-running-")) {
+ let ticketID = key.replace("ticket-timer-running-", "");
+ let isRunning = JSON.parse(localStorage.getItem(key));
+
+ let ticketDiv = document.createElement('div');
+ ticketDiv.classList.add('card', 'card-outline', 'mb-3');
+ // Add class based on ticket status
+ ticketDiv.classList.add(isRunning ? 'card-info' : 'card-warning');
+ ticketDiv.id = 'ticket-' + ticketID;
+
+ let elapsedSecs = getElapsedSeconds(ticketID);
+ let timeString = formatTime(elapsedSecs);
+
+ ticketDiv.innerHTML = `
+
+
+
Total Time: ${timeString}
+
+ `;
+
+ openTicketsContainer.appendChild(ticketDiv);
+ }
+ }
+
+ requestAnimationFrame(() => updateRunningTickets());
+ }
+
+ function updateRunningTickets() {
+ let runningTickets = document.querySelectorAll('[id^="ticket-"]');
+ runningTickets.forEach(ticket => {
+ let ticketID = ticket.id.replace("ticket-", "");
+ let isRunning = JSON.parse(localStorage.getItem("ticket-timer-running-" + ticketID));
+
+ if (isRunning) {
+ let updatedTime = formatTime(getElapsedSeconds(ticketID));
+ document.getElementById('time-' + ticketID).innerText = 'Total Time: ' + updatedTime;
+ }
+ });
+
+ requestAnimationFrame(updateRunningTickets);
+ }
+
+ function clearAllTimers() {
+ // Collect keys to be removed
+ let keysToRemove = [];
+ for (let i = 0; i < localStorage.length; i++) {
+ let key = localStorage.key(i);
+ if (key.startsWith("ticket-timer-running-") || key.endsWith("-startTime") || key.endsWith("-pausedTime")) {
+ keysToRemove.push(key);
+ }
+ }
+
+ // Remove collected keys
+ keysToRemove.forEach(key => localStorage.removeItem(key));
+
+ // Update the display and redirect
+ updateTicketCountDisplay();
+ window.location.href = "/tickets.php";
+ }
+
+ // Initial update on script load
+ updateTicketCountDisplay();
+
+ // update every 10 seconds
+ setInterval(updateTicketCountDisplay, 10000);
+
+ // Add event listener to modal
+ document.addEventListener('DOMContentLoaded', function() {
+ let modal = document.getElementById('openTicketsModal');
+ if (modal) {
+ $('#openTicketsModal').on('show.bs.modal', loadOpenTickets);
+ }
+ });
+
+ // Add event listener to clear all timers button
+ document.getElementById('clearAllTimers').addEventListener('click', clearAllTimers);
+
+})();
diff --git a/js/ticket_time_tracking.js b/js/ticket_time_tracking.js
index c50bf1a9..f60a7016 100644
--- a/js/ticket_time_tracking.js
+++ b/js/ticket_time_tracking.js
@@ -8,6 +8,8 @@
var ticketID = getCurrentTicketID();
var elapsedSecs = getElapsedSeconds();
+ updateRunningTicketsCount();
+
function getCurrentTicketID() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get('ticket_id');
@@ -53,6 +55,9 @@
timerInterval = setInterval(countTime, 1000);
isPaused = false;
document.getElementById("startStopTimer").innerText = "Pause";
+ updateRunningTicketsCount();
+ localStorage.setItem("ticket-timer-running-" + ticketID, "true");
+
}
function pauseTimer() {
@@ -65,11 +70,15 @@
localStorage.removeItem(getLocalStorageKey("startTime"));
isPaused = true;
document.getElementById("startStopTimer").innerText = "Start";
+ updateRunningTicketsCount();
+ localStorage.setItem("ticket-timer-running-" + ticketID, "false");
+
}
function clearTimeStorage() {
localStorage.removeItem(getLocalStorageKey("startTime"));
localStorage.removeItem(getLocalStorageKey("pausedTime"));
+ localStorage.removeItem("ticket-timer-running-" + ticketID);
}
function resetTimer() {
@@ -81,6 +90,8 @@
displayTime();
document.getElementById("startStopTimer").innerText = "Start";
}
+ localStorage.setItem("ticket-timer-running-" + ticketID, "false");
+ updateRunningTicketsCount();
}
function forceResetTimer() {
@@ -116,6 +127,18 @@
}
+ function updateRunningTicketsCount() {
+ let runningTickets = parseInt(document.getElementById('runningTicketsCount').innerText, 10);
+
+ if (!isPaused && timerInterval) {
+ runningTickets += 1;
+ } else {
+ runningTickets = Math.max(0, runningTickets - 1);
+ }
+
+ document.getElementById('runningTicketsCount').innerText = runningTickets.toString();
+ }
+
// Function to check status and pause timer
function checkStatusAndPauseTimer() {
var status = document.querySelector('select[name="status"]').value;
@@ -124,6 +147,7 @@
}
}
+
document.getElementById("hours").addEventListener('change', updateTimeFromInput);
document.getElementById("minutes").addEventListener('change', updateTimeFromInput);
@@ -153,7 +177,12 @@
// Wait for other synchronous actions (if any) to complete before resetting the timer.
setTimeout(forceResetTimer, 100); // 100ms delay should suffice, but you can adjust as needed.
});
-
+
+ document.getElementById("ticket_close").addEventListener('click', function() {
+ // Wait for other synchronous actions (if any) to complete before resetting the timer.
+ setTimeout(clearTimeStorage, 100); // 100ms delay should suffice, but you can adjust as needed.
+ });
+
try {
displayTime();
if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) {
diff --git a/ticket.php b/ticket.php
index 3a6d0a9f..b442057e 100644
--- a/ticket.php
+++ b/ticket.php
@@ -315,6 +315,7 @@ if (isset($_GET['ticket_id'])) {
+