Cart timer update

User
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 {
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

Assistant
You’re resetting the timer because you **remove** `DEADLINE_KEY` on expiry—so on reload it doesn’t exist and a new 20-min deadline gets created.

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.

User
<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

Assistant
Got it — you want a **fresh 20-minute timer after the user reloads** once the cart expires.

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.

Leave a Comment

Your email address will not be published. Required fields are marked *