239 lines
11 KiB
Plaintext
239 lines
11 KiB
Plaintext
<section id="checkout-view" style="padding: 40px 20px;">
|
|
<div class="checkout-container">
|
|
<div class="progress-bar">
|
|
<div class="step active" id="step-1-indicator">1</div>
|
|
<div class="line" id="line-1"></div>
|
|
<div class="step" id="step-2-indicator">2</div>
|
|
<div class="line" id="line-2"></div>
|
|
<div class="step" id="step-3-indicator">3</div>
|
|
</div>
|
|
|
|
<div id="checkout-step-1" class="checkout-step">
|
|
<h2 style="text-align: center; margin-bottom: 20px;">Zahlungsmethode wählen</h2>
|
|
<div class="payment-grid">
|
|
<div class="payment-method" data-method="Apple Pay">
|
|
<img src="/img/applepay.png" alt="Apple Pay" style="height: 20px;">
|
|
<span>Apple Pay</span>
|
|
</div>
|
|
<div class="payment-method" data-method="PayPal">
|
|
<img src="/img/paypal.png" alt="PayPal" style="height: 20px;">
|
|
<span>PayPal</span>
|
|
</div>
|
|
<div class="payment-method" data-method="Google Pay">
|
|
<img src="/img/googlepay.png" alt="Google Pay" style="height: 20px;">
|
|
<span>Google Pay</span>
|
|
</div>
|
|
<div class="payment-method" data-method="Visa">
|
|
<img src="/img/visa.png" alt="Visa" style="height: 20px;">
|
|
<span>Visa</span>
|
|
</div>
|
|
</div>
|
|
<button id="btn-next-step-2" class="hidden" style="margin-top: 25px; width: 100%; padding: 15px; background: #0071e3; color: white; border: none; border-radius: 8px; font-weight: bold; cursor: pointer;">Weiter zur Übersicht</button>
|
|
</div>
|
|
|
|
<div id="checkout-step-2" class="checkout-step hidden">
|
|
<div style="position: relative;">
|
|
<button id="btn-back-to-step1" style="position: absolute; top: -15px; left: 0; background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer; opacity: 0.6; transition: 0.3s;">←</button>
|
|
<h2 style="text-align: center; margin-bottom: 25px;">Persönliche Daten</h2>
|
|
</div>
|
|
<h2 style="text-align: center; margin-bottom: 20px;">Bestellübersicht</h2>
|
|
<div id="checkout-summary-list" style="background: #222; padding: 15px; border-radius: 8px;"></div>
|
|
<h3 id="checkout-total-display" style="text-align: right; margin-top: 15px;"></h3>
|
|
<div id="checkout-vat-display" style="text-align: right; color: #86868b; font-size: 0.8rem;"></div>
|
|
<button id="btn-pay-now" style="margin-top: 25px; width: 100%; padding: 15px; background: #4caf50; color: white; border: none; border-radius: 8px; font-weight: bold; cursor: pointer;">Jetzt Bezahlen</button>
|
|
</div>
|
|
|
|
<div id="checkout-step-3" class="checkout-step hidden">
|
|
<h2 style="color: #4caf50; text-align: center;">Kauf erfolgreich!</h2>
|
|
<div id="ticket-container" style="margin-top: 30px;"></div>
|
|
<button id="btn-back-home" style="margin-top: 30px; width: 100%; padding: 15px; background: #333; color: white; border: none; border-radius: 8px; cursor: pointer;">Zurück zur Startseite</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
import { currentUser, users, cart, emptyCart, occupiedSeatsData, updateCart, updateOccupiedSeats } from "../scripts/bigConstants";
|
|
|
|
function formatCheckoutEuro(value: number) {
|
|
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
|
}
|
|
|
|
let selectedPaymentMethod = "";
|
|
|
|
function setCheckoutStep(step: number) {
|
|
const step1 = document.getElementById("checkout-step-1");
|
|
const step2 = document.getElementById("checkout-step-2");
|
|
const step3 = document.getElementById("checkout-step-3");
|
|
step1?.classList.toggle("hidden", step !== 1);
|
|
step2?.classList.toggle("hidden", step !== 2);
|
|
step3?.classList.toggle("hidden", step !== 3);
|
|
|
|
const line1 = document.getElementById("line-1");
|
|
const line2 = document.getElementById("line-2");
|
|
const indicator1 = document.getElementById("step-1-indicator");
|
|
const indicator2 = document.getElementById("step-2-indicator");
|
|
const indicator3 = document.getElementById("step-3-indicator");
|
|
|
|
indicator1?.classList.add("active");
|
|
indicator2?.classList.toggle("active", step >= 2);
|
|
indicator3?.classList.toggle("active", step >= 3);
|
|
line1?.classList.toggle("active", step >= 2);
|
|
line2?.classList.toggle("active", step >= 3);
|
|
}
|
|
|
|
function renderCheckout() {
|
|
const summaryList = document.getElementById("checkout-summary-list");
|
|
const totalDisplay = document.getElementById("checkout-total-display");
|
|
const vatDisplay = document.getElementById("checkout-vat-display");
|
|
const nextButton = document.getElementById("btn-next-step-2");
|
|
|
|
if (!summaryList) return;
|
|
summaryList.innerHTML = "";
|
|
|
|
const total = cart.reduce((sum: number, item: any) => sum + Number(item.price || 0), 0);
|
|
const vat = total - total / 1.19;
|
|
|
|
cart.forEach((item: any) => {
|
|
const row = document.createElement("div");
|
|
row.style.cssText = "display:flex; justify-content:space-between; gap:12px; margin-bottom:10px; font-size:0.95rem;";
|
|
const infoText = item.category === "movie"
|
|
? `Sitz ${item.seatId || "-"} | ${item.hall || "-"} | ${item.time || "-"} Uhr`
|
|
: `${item.time || "Standard"} | ${item.hall || "-"}`;
|
|
row.innerHTML = `<span>${item.title} (${infoText})</span><span>${formatCheckoutEuro(item.price)}</span>`;
|
|
summaryList.appendChild(row);
|
|
});
|
|
|
|
if (totalDisplay) totalDisplay.innerText = `Gesamtbetrag: ${formatCheckoutEuro(total)}`;
|
|
if (vatDisplay) vatDisplay.innerText = `inkl. 19% MwSt: ${formatCheckoutEuro(vat)}`;
|
|
|
|
selectedPaymentMethod = "";
|
|
document.querySelectorAll(".payment-method").forEach((method) => method.classList.remove("selected"));
|
|
nextButton?.classList.add("hidden");
|
|
setCheckoutStep(1);
|
|
}
|
|
|
|
function generateTicket() {
|
|
const ticketContainer = document.getElementById("ticket-container");
|
|
if (!ticketContainer) return;
|
|
|
|
const moviesInCart = cart.filter((item: any) => item.category === "movie");
|
|
if (!moviesInCart.length) {
|
|
ticketContainer.innerHTML = "<p>Danke für deinen Einkauf!</p>";
|
|
return;
|
|
}
|
|
|
|
const mainMovie = moviesInCart[0];
|
|
const matchingMovieSeats = moviesInCart
|
|
.filter((item: any) => item.title === mainMovie.title && item.time === mainMovie.time)
|
|
.map((item: any) => item.seatId)
|
|
.join(", ");
|
|
|
|
const qrData = encodeURIComponent(`EAGLE-IMAX|${mainMovie.title}|${mainMovie.hall}|${matchingMovieSeats}`);
|
|
const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${qrData}&bgcolor=ffffff`;
|
|
|
|
ticketContainer.innerHTML = `
|
|
<div class="luxury-ticket">
|
|
<div class="ticket-left">
|
|
<img src="${mainMovie.img || mainMovie.poster}" class="ticket-poster" alt="${mainMovie.title}">
|
|
</div>
|
|
<div class="ticket-right">
|
|
<div class="ticket-brand">EAGLE'S IMAX PREMIUM</div>
|
|
<h2 class="ticket-title">${mainMovie.title}</h2>
|
|
<div class="ticket-details">
|
|
<p><span>SAAL</span> <strong>${mainMovie.hall}</strong></p>
|
|
<p><span>ZEIT</span> <strong>${mainMovie.time} Uhr</strong></p>
|
|
<p><span>SITZE</span> <strong>${matchingMovieSeats || "-"}</strong></p>
|
|
</div>
|
|
<div class="ticket-footer">
|
|
<img src="${qrUrl}" class="ticket-qr" alt="QR Code">
|
|
<div class="ticket-code">#${Math.floor(Math.random() * 90000) + 10000}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function completeCheckout() {
|
|
const orderItems = [...cart];
|
|
const orderTotal = orderItems.reduce((sum, item) => sum + Number(item.price || 0), 0);
|
|
|
|
// Save order for current user
|
|
if (currentUser && Array.isArray(users)) {
|
|
const userIndex = users.findIndex((entry: any) => entry.email === currentUser.email);
|
|
if (userIndex !== -1) {
|
|
if (!Array.isArray(users[userIndex].orders)) users[userIndex].orders = [];
|
|
users[userIndex].orders.push({
|
|
date: new Date().toLocaleString("de-DE"),
|
|
items: orderItems,
|
|
total: orderTotal,
|
|
paymentMethod: selectedPaymentMethod || "-"
|
|
});
|
|
localStorage.setItem("eagleUsers", JSON.stringify(users));
|
|
}
|
|
}
|
|
|
|
// Reserve seats
|
|
orderItems.filter(item => item.category === "movie").forEach(item => {
|
|
const key = `${item.hall}-${item.time}`;
|
|
if (!occupiedSeatsData[key]) occupiedSeatsData[key] = [];
|
|
occupiedSeatsData[key].push(item.seatId);
|
|
});
|
|
updateOccupiedSeats(occupiedSeatsData);
|
|
|
|
emptyCart();
|
|
window.dispatchEvent(new CustomEvent("cart-updated"));
|
|
}
|
|
|
|
function bindCheckoutEvents() {
|
|
const nextButton = document.getElementById("btn-next-step-2");
|
|
const backButton = document.getElementById("btn-back-to-step1");
|
|
const payNowButton = document.getElementById("btn-pay-now") as HTMLButtonElement;
|
|
|
|
document.querySelectorAll(".payment-method").forEach((method) => {
|
|
method.addEventListener("click", () => {
|
|
document.querySelectorAll(".payment-method").forEach((entry) => entry.classList.remove("selected"));
|
|
method.classList.add("selected");
|
|
selectedPaymentMethod = (method as HTMLElement).dataset.method || "";
|
|
nextButton?.classList.remove("hidden");
|
|
});
|
|
});
|
|
|
|
nextButton?.addEventListener("click", () => {
|
|
if (!selectedPaymentMethod) {
|
|
alert("Bitte wähle zuerst eine Zahlungsmethode aus.");
|
|
return;
|
|
}
|
|
setCheckoutStep(2);
|
|
});
|
|
|
|
backButton?.addEventListener("click", () => setCheckoutStep(1));
|
|
|
|
payNowButton?.addEventListener("click", () => {
|
|
if (!cart.length) {
|
|
alert("Dein Warenkorb ist leer.");
|
|
return;
|
|
}
|
|
payNowButton.disabled = true;
|
|
payNowButton.innerText = "Verarbeite...";
|
|
payNowButton.style.opacity = "0.7";
|
|
setTimeout(() => {
|
|
setCheckoutStep(3);
|
|
generateTicket();
|
|
completeCheckout();
|
|
payNowButton.disabled = false;
|
|
payNowButton.innerText = "Jetzt Bezahlen";
|
|
payNowButton.style.opacity = "1";
|
|
}, 1200);
|
|
});
|
|
|
|
document.getElementById("btn-back-home")?.addEventListener("click", () => {
|
|
window.location.href = "/";
|
|
});
|
|
}
|
|
|
|
if (document.getElementById("checkout-view")) {
|
|
renderCheckout();
|
|
bindCheckoutEvents();
|
|
}
|
|
</script>
|