"use strict"; /** * Globale UI die op elke pagina aanwezig is: winkelmandje-lade, afrekenmodal * en toast-meldingen. Deze module praat uitsluitend met CL.store, zodat de * mandjestoestand consistent blijft tijdens het navigeren. */ (function () { const CL = (window.CL = window.CL || {}); const { formatPrice, escapeHtml } = CL.fmt; const store = CL.store; const PRODUCTS = window.PRODUCTS || []; const findProduct = (id) => PRODUCTS.find((p) => p.id === id); const els = {}; let toastTimer; function init() { els.overlay = document.getElementById("overlay"); els.drawer = document.getElementById("drawer"); els.closeCart = document.getElementById("closeCart"); els.cartItems = document.getElementById("cartItems"); els.cartSub = document.getElementById("cartSub"); els.cartTax = document.getElementById("cartTax"); els.cartTotal = document.getElementById("cartTotal"); els.checkoutBtn = document.getElementById("checkoutBtn"); els.modalWrap = document.getElementById("modalWrap"); els.modalContent = document.getElementById("modalContent"); els.toast = document.getElementById("toast"); els.closeCart.addEventListener("click", closeCart); els.overlay.addEventListener("click", closeCart); els.checkoutBtn.addEventListener("click", () => { if (store.size() === 0) return; closeCart(); renderCheckoutForm(); openModal(); }); // Aantal aanpassen in de lade (delegatie). els.cartItems.addEventListener("click", (e) => { const btn = e.target.closest("[data-step]"); if (btn) store.step(btn.dataset.id, Number(btn.dataset.step)); }); // "Toevoegen" werkt overal: catalogus, productpagina, aanbiedingen. document.addEventListener("click", (e) => { const add = e.target.closest("[data-add]"); if (!add) return; e.preventDefault(); const product = findProduct(add.dataset.add); if (!product) return; store.add(product.id); showToast(product.name + " toegevoegd aan het mandje."); }); els.modalWrap.addEventListener("click", (e) => { if (e.target === els.modalWrap) closeModal(); }); document.addEventListener("keydown", (e) => { if (e.key === "Escape") { closeModal(); closeCart(); } }); } // Koppelt knoppen die per route opnieuw worden gerenderd (in de header). function bindHeader() { const openCartBtn = document.getElementById("openCart"); if (openCartBtn) openCartBtn.addEventListener("click", openCart); const toggle = document.getElementById("navToggle"); const links = document.getElementById("navLinks"); if (toggle && links) { toggle.addEventListener("click", () => { const open = links.classList.toggle("open"); toggle.setAttribute("aria-expanded", String(open)); }); // Sluit het mobiele menu na een keuze. links.addEventListener("click", (e) => { if (e.target.closest("a")) { links.classList.remove("open"); toggle.setAttribute("aria-expanded", "false"); } }); } } function updateCartCount() { const { count } = store.totals(); document.querySelectorAll("[data-cart-count]").forEach((el) => (el.textContent = String(count))); } function renderCart() { const { count, subtotal, tax, total } = store.totals(); els.cartSub.innerHTML = formatPrice(subtotal); els.cartTax.innerHTML = formatPrice(tax); els.cartTotal.innerHTML = formatPrice(total); els.checkoutBtn.disabled = count === 0; const entries = store.entries(); if (entries.length === 0) { els.cartItems.innerHTML = '
Uw winkelmandje is leeg.
'; return; } const rows = []; for (const [id, qty] of entries) { const p = findProduct(id); if (!p) continue; const tile = p.image ? `` : escapeHtml(p.from); rows.push(`
${escapeHtml(p.name)} ${formatPrice(p.price)} per stuk
${qty}
${formatPrice(p.price * qty)}
`); } els.cartItems.innerHTML = rows.join(""); } function openCart() { els.overlay.classList.add("open"); els.drawer.classList.add("open"); } function closeCart() { els.overlay.classList.remove("open"); els.drawer.classList.remove("open"); } function openModal() { els.modalWrap.classList.add("open"); } function closeModal() { els.modalWrap.classList.remove("open"); } function showToast(message) { els.toast.textContent = message; els.toast.classList.add("show"); clearTimeout(toastTimer); toastTimer = setTimeout(() => els.toast.classList.remove("show"), 2200); } function renderCheckoutForm() { const { total } = store.totals(); els.modalContent.innerHTML = `

Afrekenen

Dit formulier verwerkt geen gegevens. Ingevoerde waarden worden niet opgeslagen of verzonden.

Demonstratieformulier. Er wordt geen betaling uitgevoerd.

`; document.getElementById("payForm").addEventListener("submit", (event) => { event.preventDefault(); const form = event.currentTarget; if (!form.checkValidity()) { form.reportValidity(); return; } renderSuccess(); }); } function renderSuccess() { const { count } = store.totals(); const orderId = "CL-" + Math.floor(100000 + Math.random() * 900000); els.modalContent.innerHTML = `

Bestelling geregistreerd

${count} fictief artikel(en) zijn vastgelegd in deze demonstratie.

Referentie: ${escapeHtml(orderId)}

Verwachte levering: niet van toepassing.

`; store.clear(); document.getElementById("doneBtn").addEventListener("click", () => { closeModal(); showToast("Winkelmandje geleegd."); }); } CL.ui = { init, bindHeader, updateCartCount, renderCart, openCart, closeCart, showToast }; })();