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:
@@ -8,6 +8,7 @@ import { initCopyUrl } from "./modules/copy-url.js"
|
||||
import { initSortable } from "./modules/sortable.js"
|
||||
import { initBilletDesigner } from "./modules/billet-designer.js"
|
||||
import { initCommissionCalculator } from "./modules/commission-calculator.js"
|
||||
import { initCart } from "./modules/cart.js"
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initMobileMenu()
|
||||
@@ -19,4 +20,5 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
initSortable()
|
||||
initBilletDesigner()
|
||||
initCommissionCalculator()
|
||||
initCart()
|
||||
})
|
||||
|
||||
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