Files
Kino-Website/cart.js
Jannis Heydemann 9e599e496c Aarons Erster Commit
2026-04-29 09:35:10 +02:00

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("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#39;");
}
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();
};