live seat availability: fetch from server webhook, orange/red styling when <10/0 seats, disable sold-out locations

This commit is contained in:
Oliver
2026-06-14 16:54:13 -03:00
parent ea58be1d97
commit 19183b42a8
5 changed files with 136 additions and 18 deletions
+64
View File
@@ -287,6 +287,7 @@ document
.getElementById("pricing-period")
.addEventListener("change", updatePeriodDisplay);
updatePeriodDisplay(); // fire on load so yearly bonuses show by default
initServerLocations(); // fetch live server availability
/* ── Capture UTM params from URL ──────────────────────────── */
(function () {
@@ -638,6 +639,69 @@ async function chatSend() {
});
})();
/* ── Server Locations (live seat availability) ──────── */
const SERVER_WEBHOOK = "https://n8n.derez.ai/webhook/server";
async function initServerLocations() {
const sel = document.getElementById("pricing-location");
if (!sel) return;
try {
const res = await fetch(SERVER_WEBHOOK);
const data = await res.json();
const servers = Array.isArray(data) ? data : [data];
// Clear existing options
sel.innerHTML = "";
servers.forEach(function (s) {
const server = s.server || "";
const available = parseInt(s["Seats Available"], 10) || 0;
const label = server.charAt(0).toUpperCase() + server.slice(1);
const opt = document.createElement("option");
opt.value = server.toLowerCase().replace(/\s+/g, "-");
if (available <= 0) {
// No seats — red, disabled, cannot select
opt.textContent = label + " (sold out)";
opt.disabled = true;
opt.style.color = "#ff4444";
opt.style.fontWeight = "600";
sel.classList.remove("low-seats");
sel.classList.add("no-seats");
} else if (available < 10) {
// Low seats — orange with count
opt.textContent = label + " (available " + available + ")";
opt.style.color = "#ff9900";
opt.style.fontWeight = "600";
sel.classList.add("low-seats");
sel.classList.remove("no-seats");
} else {
// Plenty of seats
opt.textContent = label + " (available " + available + ")";
opt.style.color = "";
opt.style.fontWeight = "";
sel.classList.remove("low-seats", "no-seats");
}
sel.appendChild(opt);
});
// Default to first available option
for (var i = 0; i < sel.options.length; i++) {
if (!sel.options[i].disabled) {
sel.selectedIndex = i;
break;
}
}
} catch (err) {
console.error("Failed to load server locations:", err);
// Fallback: leave the placeholder option
sel.innerHTML =
'<option value="france" style="color:#ff9900;font-weight:600">France (available ?)</option>';
}
}
/* ── Coupon Badges ──────────────────────────────────── */
const COUPONS = {
// 499