Cart timer update
August 26, 2025 · AI Conversations
const TWO_MINUTE_MS = 5 * 60 * 1000;
const DEADLINE_KEY = "cart_deadline"; // localStorage key
const ORDER_KEY = "fossettsOrderData"; // your order data key
// Get deadline from localStorage or set new
let deadline = localStorage.getItem(DEADLINE_KEY);
if (!deadline) {
deadline = Date.now() + DURATION;
localStorage.setItem(DEADLINE_KEY, deadline);
} else {
deadline = parseInt(deadline, 10);
}
const WARNED_KEY = `cart_20min_warned_${deadline}`;
function updateTimers() {
const now = Date.now();
let remaining = deadline – now;
// Show 2-minute warning (once)
if (remaining > 0 && remaining {
el.value = "0"; // reset each input’s value
});
if (orderData) {
try {
// normalize to your expected structure
orderData.tickets = Array.isArray(orderData.tickets) ? [] : [];
orderData.addOns = Array.isArray(orderData.addOns) ? [] : [];
orderData.total = 0;
} catch (e) {
// fallback: hard reset
orderData = { tickets: [], addOns: [], total: 0 };
}
}
// Call custom UI updater if available
if (typeof updateOrderSummary === "function") {
try { updateOrderSummary(); } catch (_) {}
}
console.log("⏰ Time's up — fossettsOrderData cleared");
//window.location.href = "/";
return;
}
const minutes = Math.floor(remaining / 1000 / 60);
const seconds = Math.floor((remaining / 1000) % 60);
const formatted =
`Complete your order in ${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")} minutes`;
document.querySelectorAll(".order_timer").forEach(el => {
el.innerHTML = formatted;
});
}
// Start ticking
updateTimers();
const timerInterval = setInterval(updateTimers, 1000);
})();
when cart expire and reload the page then again start counter
Use this drop-in update (key changes marked in comments):
<script>
(function () {
const DURATION = 20 * 60 * 1000; // 20 minutes
const TWO_MINUTE_MS = 2 * 60 * 1000; // ✅ real 2 minutes
const DEADLINE_KEY = "cart_deadline";
const ORDER_KEY = "fossettsOrderData";
// Helper to hard-reset & start a fresh cart (call from a "Start new order" button)
window.resetCartAndTimer = function () {
localStorage.removeItem(DEADLINE_KEY);
localStorage.removeItem(ORDER_KEY);
// clear any per-deadline warning flag(s)
Object.keys(localStorage).forEach(k => {
if (k.startsWith("cart_20min_warned_")) localStorage.removeItem(k);
});
location.reload();
};
// Get deadline from localStorage or set new
let deadline = localStorage.getItem(DEADLINE_KEY);
if (!deadline) {
deadline = Date.now() + DURATION;
localStorage.setItem(DEADLINE_KEY, String(deadline));
} else {
deadline = parseInt(deadline, 10);
}
const WARNED_KEY = `cart_20min_warned_${deadline}`;
function updateTimers() {
const now = Date.now();
let remaining = deadline - now;
// 2-minute warning (once)
if (remaining > 0 && remaining <= TWO_MINUTE_MS && !localStorage.getItem(WARNED_KEY)) {
try {
if (typeof Swal !== "undefined" && Swal && typeof Swal.fire === "function") {
Swal.fire({
title: "Cart expiring!",
text: "Your cart will expire in 2 minutes. Please complete your order now.",
icon: "info",
confirmButtonText: "Okay"
});
}
} catch (_) {}
localStorage.setItem(WARNED_KEY, "1");
}
if (remaining <= 0) {
// ❌ DO NOT remove DEADLINE_KEY here — keep the past timestamp so reload stays expired
// localStorage.removeItem(DEADLINE_KEY);
// Clear stored order
localStorage.removeItem(ORDER_KEY);
// Reset in-page inputs/UI
const quantitySelectors = document.querySelectorAll(".quantity-value");
quantitySelectors.forEach(el => { try { el.value = "0"; el.dispatchEvent(new Event('change')); } catch(_) {} });
if (typeof orderData !== "undefined" && orderData) {
try {
orderData.tickets = [];
orderData.addOns = [];
orderData.total = 0;
} catch (_) {
// ignore
}
}
if (typeof updateOrderSummary === "function") {
try { updateOrderSummary(); } catch (_) {}
}
document.querySelectorAll(".order_timer").forEach(el => {
el.innerHTML = `
<div style="font-weight:bold;font-size:24px">
Cart expired — please
<a href="javascript:void(0);" onclick="resetCartAndTimer()">start a new order</a>
</div>`;
});
clearInterval(timerInterval);
console.log("⏰ Time's up — fossettsOrderData cleared; deadline kept to prevent restart");
return;
}
// Show ticking timer
const minutes = Math.floor(remaining / 60000);
const seconds = Math.floor((remaining % 60000) / 1000);
const formatted = `<div style="font-weight:bold;font-size:24px">
Complete your order in ${String(minutes).padStart(2,'0')}:${String(seconds).padStart(2,'0')} minutes
</div>`;
document.querySelectorAll(".order_timer").forEach(el => { el.innerHTML = formatted; });
}
// Start ticking
updateTimers();
const timerInterval = setInterval(updateTimers, 1000);
})();
</script>
**What changed:**
– Don’t `removeItem(DEADLINE_KEY)` on expiry—this keeps the past deadline so a reload stays expired.
– Fixed `TWO_MINUTE_MS` to 2 minutes.
– Added `resetCartAndTimer()` you can call from a link/button to truly start a new 20-minute session.
<script>
(function () {
const DURATION = 20 * 60 * 1000; // 20 minutes
const TWO_MINUTE_MS = 5 * 60 * 1000;
const DEADLINE_KEY = "cart_deadline"; // localStorage key
const ORDER_KEY = "fossettsOrderData"; // your order data key
// Get deadline from localStorage or set new
let deadline = localStorage.getItem(DEADLINE_KEY);
if (!deadline) {
deadline = Date.now() + DURATION;
localStorage.setItem(DEADLINE_KEY, deadline);
} else {
deadline = parseInt(deadline, 10);
}
const WARNED_KEY = `cart_20min_warned_${deadline}`;
function updateTimers() {
const now = Date.now();
let remaining = deadline - now;
// Show 2-minute warning (once)
if (remaining > 0 && remaining <= TWO_MINUTE_MS && !localStorage.getItem(WARNED_KEY)) {
try {
if (typeof Swal !== "undefined" && Swal && typeof Swal.fire === "function") {
Swal.fire({
title: "Cart expiring!",
text: "Your cart will expire in 2 minutes. Please complete your order now.",
icon: "info",
confirmButtonText: "Okay"
});
}
} catch (_) {}
localStorage.setItem(WARNED_KEY, "1");
}
if (remaining <= 0) {
document.querySelectorAll(".order_timer").forEach(el => {
el.innerHTML = `<span style="font-weight: bold;font-size:24px">Cart expired - please <a href="javascript:void(0);" onclick="location.reload();">refresh</a> and start again</span>`;
});
clearInterval(timerInterval);
// Clear storage after time up
localStorage.removeItem(DEADLINE_KEY);
localStorage.removeItem(ORDER_KEY);
// Clear in-memory JS orderData, if present
const quantitySelectors = document.querySelectorAll(".quantity-value");
quantitySelectors.forEach(el => {
el.value = "0"; // reset each input’s value
});
if (orderData) {
try {
// normalize to your expected structure
orderData.tickets = Array.isArray(orderData.tickets) ? [] : [];
orderData.addOns = Array.isArray(orderData.addOns) ? [] : [];
orderData.total = 0;
} catch (e) {
// fallback: hard reset
orderData = { tickets: [], addOns: [], total: 0 };
}
}
// Call custom UI updater if available
if (typeof updateOrderSummary === "function") {
try { updateOrderSummary(); } catch (_) {}
}
console.log("⏰ Time's up — fossettsOrderData cleared");
//window.location.href = "/";
return;
}
const minutes = Math.floor(remaining / 1000 / 60);
const seconds = Math.floor((remaining / 1000) % 60);
const formatted =
`<div style="font-weight: bold;font-size:24px">Complete your order in ${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")} minutes</div>`;
document.querySelectorAll(".order_timer").forEach(el => {
el.innerHTML = formatted;
});
}
// Start ticking
updateTimers();
const timerInterval = setInterval(updateTimers, 1000);
})();
</script>
this working fine but once cart expires and page reload then is till shows Card expires, I want tie again start
Right now you `removeItem(DEADLINE_KEY)`, but depending on how the page reloads/caches, you can still see the expired DOM until the next tick. Easiest fix: **set a brand-new deadline at expiry** (instead of removing it), so the next load immediately sees a fresh timer.
Drop-in change (only the expiry block is different):
<script>
(function () {
const DURATION = 20 * 60 * 1000; // 20 minutes
const TWO_MINUTE_MS = 2 * 60 * 1000; // optional: real 2 minutes
const DEADLINE_KEY = "cart_deadline";
const ORDER_KEY = "fossettsOrderData";
// Get deadline from localStorage or set new
let deadline = localStorage.getItem(DEADLINE_KEY);
if (!deadline) {
deadline = Date.now() + DURATION;
localStorage.setItem(DEADLINE_KEY, String(deadline));
} else {
deadline = parseInt(deadline, 10);
}
const WARNED_KEY = `cart_20min_warned_${deadline}`;
function updateTimers() {
const now = Date.now();
let remaining = deadline - now;
// 2-minute warning (once)
if (remaining > 0 && remaining <= TWO_MINUTE_MS && !localStorage.getItem(WARNED_KEY)) {
try {
if (typeof Swal !== "undefined" && Swal && typeof Swal.fire === "function") {
Swal.fire({
title: "Cart expiring!",
text: "Your cart will expire in 2 minutes. Please complete your order now.",
icon: "info",
confirmButtonText: "Okay"
});
}
} catch (_) {}
localStorage.setItem(WARNED_KEY, "1");
}
if (remaining <= 0) {
// ✅ Create a fresh 20-min deadline so a reload starts the counter again
const newDeadline = Date.now() + DURATION;
localStorage.setItem(DEADLINE_KEY, String(newDeadline));
// clear any old warned flags
Object.keys(localStorage).forEach(k => {
if (k.startsWith("cart_20min_warned_")) localStorage.removeItem(k);
});
// Clear stored order
localStorage.removeItem(ORDER_KEY);
// Reset in-page inputs/UI
document.querySelectorAll(".quantity-value").forEach(el => {
try { el.value = "0"; el.dispatchEvent(new Event('change')); } catch(_) {}
});
if (typeof orderData !== "undefined" && orderData) {
orderData.tickets = [];
orderData.addOns = [];
orderData.total = 0;
}
if (typeof updateOrderSummary === "function") {
try { updateOrderSummary(); } catch (_) {}
}
// Show message with a reload (fresh timer will be used on load)
document.querySelectorAll(".order_timer").forEach(el => {
el.innerHTML = `<span style="font-weight:bold;font-size:24px">
Cart expired — <a href="javascript:location.href=location.href">reload</a> to start again
</span>`;
});
clearInterval(timerInterval);
console.log("⏰ Expired: new deadline seeded so reload starts fresh.");
return;
}
// ticking UI
const minutes = Math.floor(remaining / 60000);
const seconds = Math.floor((remaining % 60000) / 1000);
const formatted = `<div style="font-weight:bold;font-size:24px">
Complete your order in ${String(minutes).padStart(2,"0")}:${String(seconds).padStart(2,"0")} minutes
</div>`;
document.querySelectorAll(".order_timer").forEach(el => { el.innerHTML = formatted; });
}
updateTimers();
const timerInterval = setInterval(updateTimers, 1000);
})();
</script>
**Why this works**
– On expiry we immediately **seed a fresh deadline** in `localStorage`.
– After the user reloads, your “get or set deadline” logic sees a valid future timestamp and the counter **starts again**.
– We also clear any `cart_20min_warned_*` flags so the new session can show the 2-minute warning again.