Add files via upload
This commit is contained in:
parent
eb4e4b47f2
commit
4f16ac7a44
57
ASAshop.html
57
ASAshop.html
|
|
@ -477,7 +477,7 @@
|
|||
if (u) document.getElementById('whoami').textContent =
|
||||
`Signed in as ${u.global_name || u.username}`;
|
||||
});
|
||||
|
||||
|
||||
/* ===== Products (unique IDs) ===== */
|
||||
const products = [
|
||||
{ id: 'server1', name: 'Server Class 1', price: 25.00, category: 'servers', tag: 'Server monthly', img: 'img/PrivateServerCLASS01.png'},
|
||||
|
|
@ -665,7 +665,7 @@
|
|||
});
|
||||
|
||||
/* ===== Checkout ===== */
|
||||
const API = "https://affiliated-lets-automatic-oak.trycloudflare.com";
|
||||
|
||||
|
||||
async function checkout(cart) {
|
||||
// 1) reserve
|
||||
|
|
@ -692,6 +692,17 @@
|
|||
if (!j2.url) { alert(j2.error || 'create-checkout failed'); return; }
|
||||
location.href = j2.url; // redirect to Stripe
|
||||
}
|
||||
document.getElementById('checkoutBtn').addEventListener('click', async () => {
|
||||
const entries = Object.entries(state.cart || {});
|
||||
if (!entries.length) return alert('Your cart is empty.');
|
||||
|
||||
const items = entries.map(([id, qty]) => {
|
||||
const p = products.find(p => p.id === id);
|
||||
return { id, name: p?.name || id, qty: Number(qty || 1), price: p?.price || 0 };
|
||||
});
|
||||
|
||||
await checkout(items);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
|
@ -716,24 +727,30 @@
|
|||
ctx.fillText(products.find(p => p.id === id)?.name || id, 12, cv.height - 12);
|
||||
});
|
||||
}
|
||||
// client.js (in your existing
|
||||
<script>
|
||||
)
|
||||
let remaining = 12;
|
||||
async function refreshRemaining() {
|
||||
try {
|
||||
const r = await fetch(`${API}/api/inventory`, { credentials: 'include' })
|
||||
document.querySelectorAll('[data-remaining] .remN').forEach(s => s.textContent = remaining);
|
||||
// Disable all three server buttons if none left:
|
||||
if (remaining <= 0) {
|
||||
document.querySelectorAll('[data-add="server1"],[data-add="server2"],[data-add="server3"]').forEach(btn => {
|
||||
btn.disabled = true; btn.textContent = 'Sold out';
|
||||
});
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
refreshRemaining();
|
||||
setInterval(refreshRemaining, 30_000); // stay “24/7” up-to-date
|
||||
|
||||
|
||||
let remaining = 12;
|
||||
|
||||
async function refreshRemaining() {
|
||||
try {
|
||||
const r = await fetch(`${API}/api/inventory`);
|
||||
if (!r.ok) return;
|
||||
const j = await r.json();
|
||||
if (typeof j.remaining === 'number') remaining = j.remaining;
|
||||
|
||||
// update badges
|
||||
document.querySelectorAll('[data-remaining] .remN')
|
||||
.forEach(s => s.textContent = remaining);
|
||||
|
||||
// disable server buttons if sold out relative to what's already in cart
|
||||
const left = Math.max(0, remaining - serversInCart());
|
||||
const disable = left <= 0;
|
||||
document.querySelectorAll('[data-add="server1"],[data-add="server2"],[data-add="server3"]')
|
||||
.forEach(btn => { btn.disabled = disable; btn.textContent = disable ? 'Sold out' : 'Add to cart'; });
|
||||
} catch { }
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Reference in New Issue