200 lines
5.9 KiB
JavaScript
200 lines
5.9 KiB
JavaScript
function formatEuro(value) {
|
|
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
|
}
|
|
|
|
function escapeHtml(value) {
|
|
return String(value || "")
|
|
.replaceAll("&", "&")
|
|
.replaceAll("<", "<")
|
|
.replaceAll(">", ">")
|
|
.replaceAll('"', """)
|
|
.replaceAll("'", "'");
|
|
}
|
|
|
|
function buildCartKey(item) {
|
|
const infoText = item.category === "movie"
|
|
? `Sitz: ${item.seatId} (${item.hall})`
|
|
: item.time;
|
|
return `${item.title}-${item.hall}-${infoText}`;
|
|
}
|
|
|
|
function isDrinkItem(item) {
|
|
if (item.category !== "snack") {
|
|
return false;
|
|
}
|
|
|
|
const title = String(item.title || "").toLowerCase();
|
|
const size = String(item.hall || "").toLowerCase();
|
|
const drinkKeywords = [
|
|
"cola",
|
|
"sprite",
|
|
"fanta",
|
|
"mezzo",
|
|
"fuze",
|
|
"wasser",
|
|
"getraenk",
|
|
"drink"
|
|
];
|
|
|
|
return drinkKeywords.some((word) => title.includes(word)) || size.includes("l");
|
|
}
|
|
|
|
function buildItemInfo(item) {
|
|
if (item.category === "movie") {
|
|
return `
|
|
<div>Sitzplatz: ${escapeHtml(item.seatId || "-")}</div>
|
|
<div>Saal: ${escapeHtml(item.hall || "-")}</div>
|
|
<div>Uhrzeit: ${escapeHtml(item.time || "-")} Uhr</div>
|
|
`;
|
|
}
|
|
|
|
if (isDrinkItem(item)) {
|
|
return `
|
|
<div>Variante: ${escapeHtml(item.time || "-")}</div>
|
|
<div>Groesse: ${escapeHtml(item.hall || "-")}</div>
|
|
`;
|
|
}
|
|
|
|
return `
|
|
<div>Kategorie: Snack</div>
|
|
<div>Variante: ${escapeHtml(item.time || "-")}</div>
|
|
<div>Groesse: ${escapeHtml(item.hall || "-")}</div>
|
|
`;
|
|
}
|
|
|
|
function groupCartItems() {
|
|
const groups = new Map();
|
|
|
|
cart.forEach((item) => {
|
|
const key = buildCartKey(item);
|
|
|
|
if (!groups.has(key)) {
|
|
groups.set(key, {
|
|
key,
|
|
quantity: 0,
|
|
total: 0,
|
|
item
|
|
});
|
|
}
|
|
|
|
const group = groups.get(key);
|
|
group.quantity += 1;
|
|
group.total += Number(item.price || 0);
|
|
});
|
|
|
|
return Array.from(groups.values());
|
|
}
|
|
|
|
function saveCart() {
|
|
localStorage.setItem("eagleCart", JSON.stringify(cart));
|
|
updateCartBadge();
|
|
}
|
|
|
|
function updateCartBadge() {
|
|
const cartBadge = document.getElementById("cart-badge");
|
|
|
|
if (!cartBadge) {
|
|
return;
|
|
}
|
|
|
|
cartBadge.innerText = cart.length;
|
|
cartBadge.classList.toggle("hidden", cart.length === 0);
|
|
}
|
|
|
|
function renderCart() {
|
|
const cartList = document.getElementById("cart-items-list");
|
|
const totalEl = document.getElementById("cart-total-right");
|
|
const vatEl = document.getElementById("cart-vat-right");
|
|
|
|
if (!cartList || !totalEl || !vatEl) {
|
|
return;
|
|
}
|
|
|
|
if (!Array.isArray(cart) || cart.length === 0) {
|
|
cartList.innerHTML = '<p>Dein Warenkorb ist leer.</p>';
|
|
totalEl.innerText = formatEuro(0);
|
|
vatEl.innerText = `inkl. 19% MwSt: ${formatEuro(0)}`;
|
|
return;
|
|
}
|
|
|
|
const groupedItems = groupCartItems();
|
|
|
|
const header = `
|
|
<div class="cart-header-row">
|
|
<div class="col-amount">MENGE</div>
|
|
<div class="col-img">VORSCHAU</div>
|
|
<div class="col-product">NAME</div>
|
|
<div class="col-details">INFO</div>
|
|
<div class="col-price">PREIS</div>
|
|
<div class="col-action">AKTION</div>
|
|
</div>
|
|
`;
|
|
|
|
const rows = groupedItems
|
|
.map((group) => {
|
|
const imageHtml = group.item.img
|
|
? `<img class="cart-img-small" src="${escapeHtml(group.item.img)}" alt="${escapeHtml(group.item.title)}">`
|
|
: `<div class="cart-img-fallback">Kein Bild</div>`;
|
|
const quantityHtml = group.item.category === "movie"
|
|
? `<div class="qty-static" aria-label="Feste Ticketanzahl">${group.quantity}x</div>`
|
|
: `
|
|
<div class="qty-stepper">
|
|
<button class="btn-qty" data-action="minus" data-key="${escapeHtml(group.key)}">-</button>
|
|
<span>${group.quantity}</span>
|
|
<button class="btn-qty" data-action="plus" data-key="${escapeHtml(group.key)}">+</button>
|
|
</div>
|
|
`;
|
|
|
|
return `
|
|
<div class="cart-item-row">
|
|
<div class="col-amount">
|
|
${quantityHtml}
|
|
</div>
|
|
<div class="col-img">${imageHtml}</div>
|
|
<div class="col-product">${escapeHtml(group.item.title)}</div>
|
|
<div class="col-details cart-item-info">${buildItemInfo(group.item)}</div>
|
|
<div class="col-price">${formatEuro(group.total)}</div>
|
|
<div class="col-action">
|
|
<button class="btn-delete-item" data-key="${escapeHtml(group.key)}" aria-label="Eintrag entfernen"><span aria-hidden="true">🗑️</span></button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
})
|
|
.join("");
|
|
|
|
cartList.innerHTML = header + rows;
|
|
|
|
const total = cart.reduce((sum, item) => sum + Number(item.price || 0), 0);
|
|
const vat = total - total / 1.19;
|
|
|
|
totalEl.innerText = formatEuro(total);
|
|
vatEl.innerText = `inkl. 19% MwSt: ${formatEuro(vat)}`;
|
|
|
|
saveCart();
|
|
}
|
|
|
|
window.removeItem = function removeItem(id) {
|
|
cart = cart.filter((item) => item.id !== id);
|
|
saveCart();
|
|
renderCart();
|
|
};
|
|
|
|
window.changeQty = function changeQty(title, delta) {
|
|
if (delta > 0) {
|
|
const item = cart.find((entry) => entry.title === title);
|
|
if (item) {
|
|
cart.push({ ...item, id: Date.now() + Math.random() });
|
|
}
|
|
} else {
|
|
const index = cart
|
|
.map((entry) => entry.title)
|
|
.lastIndexOf(title);
|
|
if (index !== -1) {
|
|
cart.splice(index, 1);
|
|
}
|
|
}
|
|
|
|
saveCart();
|
|
renderCart();
|
|
};
|