Add shopping cart system on event detail billetterie
- Each billet has +/- quantity buttons with max quantity enforcement - Line total per billet updated in real-time - Cart total and article count at the bottom - Commander button disabled when cart is empty - Full billet description displayed - JS module cart.js with 10 tests covering all cases Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
64
assets/modules/cart.js
Normal file
64
assets/modules/cart.js
Normal file
@@ -0,0 +1,64 @@
|
||||
function formatEur(value) {
|
||||
return value.toFixed(2).replace('.', ',') + ' \u20AC'
|
||||
}
|
||||
|
||||
export function initCart() {
|
||||
const billetterie = document.getElementById('billetterie')
|
||||
if (!billetterie) return
|
||||
|
||||
const items = billetterie.querySelectorAll('[data-cart-item]')
|
||||
const totalEl = document.getElementById('cart-total')
|
||||
const countEl = document.getElementById('cart-count')
|
||||
const checkoutBtn = document.getElementById('cart-checkout')
|
||||
if (!totalEl || !countEl) return
|
||||
|
||||
function updateTotals() {
|
||||
let total = 0
|
||||
let count = 0
|
||||
|
||||
for (const item of items) {
|
||||
const price = Number.parseFloat(item.dataset.price) || 0
|
||||
const qtyInput = item.querySelector('[data-cart-qty]')
|
||||
const lineTotalEl = item.querySelector('[data-cart-line-total]')
|
||||
const qty = Number.parseInt(qtyInput.value, 10) || 0
|
||||
|
||||
const lineTotal = price * qty
|
||||
total += lineTotal
|
||||
count += qty
|
||||
|
||||
lineTotalEl.textContent = formatEur(lineTotal)
|
||||
}
|
||||
|
||||
totalEl.textContent = formatEur(total)
|
||||
countEl.textContent = String(count)
|
||||
|
||||
if (checkoutBtn) {
|
||||
checkoutBtn.disabled = count === 0
|
||||
}
|
||||
}
|
||||
|
||||
for (const item of items) {
|
||||
const qtyInput = item.querySelector('[data-cart-qty]')
|
||||
const minusBtn = item.querySelector('[data-cart-minus]')
|
||||
const plusBtn = item.querySelector('[data-cart-plus]')
|
||||
const max = Number.parseInt(item.dataset.max, 10) || 0
|
||||
|
||||
minusBtn.addEventListener('click', () => {
|
||||
const current = Number.parseInt(qtyInput.value, 10) || 0
|
||||
if (current > 0) {
|
||||
qtyInput.value = current - 1
|
||||
updateTotals()
|
||||
}
|
||||
})
|
||||
|
||||
plusBtn.addEventListener('click', () => {
|
||||
const current = Number.parseInt(qtyInput.value, 10) || 0
|
||||
if (max === 0 || current < max) {
|
||||
qtyInput.value = current + 1
|
||||
updateTotals()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateTotals()
|
||||
}
|
||||
Reference in New Issue
Block a user