451 lines
17 KiB
JavaScript
451 lines
17 KiB
JavaScript
function readStorageJson(key, fallbackValue) {
|
|
const raw = localStorage.getItem(key);
|
|
|
|
if (!raw || raw === "undefined" || raw === "null") {
|
|
return fallbackValue;
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(raw);
|
|
} catch (error) {
|
|
console.warn(`Konnte LocalStorage-Wert fuer ${key} nicht lesen.`, error);
|
|
return fallbackValue;
|
|
}
|
|
}
|
|
|
|
function normalizeUser(user) {
|
|
if (!user || typeof user !== "object") {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
firstName: user.firstName || "",
|
|
lastName: user.lastName || "",
|
|
email: user.email || "",
|
|
password: user.password || "",
|
|
orders: Array.isArray(user.orders) ? user.orders : [],
|
|
paymentMethods: Array.isArray(user.paymentMethods) ? user.paymentMethods : []
|
|
};
|
|
}
|
|
|
|
function escapeHtml(value) {
|
|
return String(value || "")
|
|
.replaceAll("&", "&")
|
|
.replaceAll("<", "<")
|
|
.replaceAll(">", ">")
|
|
.replaceAll('"', """)
|
|
.replaceAll("'", "'");
|
|
}
|
|
|
|
function formatEuro(value) {
|
|
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
|
}
|
|
|
|
function persistUsers() {
|
|
localStorage.setItem("eagleUsers", JSON.stringify(users));
|
|
}
|
|
|
|
function persistCurrentUser() {
|
|
if (currentUser) {
|
|
localStorage.setItem("currentUser", JSON.stringify(currentUser));
|
|
} else {
|
|
localStorage.removeItem("currentUser");
|
|
}
|
|
}
|
|
|
|
let users = readStorageJson("eagleUsers", []);
|
|
if (!Array.isArray(users)) {
|
|
users = [];
|
|
}
|
|
users = users.map(normalizeUser).filter(Boolean);
|
|
|
|
let currentUser = normalizeUser(readStorageJson("currentUser", null));
|
|
if (currentUser && currentUser.email) {
|
|
const storedMatch = users.find((user) => user.email === currentUser.email);
|
|
if (storedMatch) {
|
|
currentUser = storedMatch;
|
|
} else {
|
|
users.push(currentUser);
|
|
persistUsers();
|
|
}
|
|
}
|
|
|
|
function registerUser() {
|
|
const firstName = document.getElementById("reg-firstname")?.value.trim() || "";
|
|
const lastName = document.getElementById("reg-lastname")?.value.trim() || "";
|
|
const email = (document.getElementById("reg-email")?.value.trim() || "").toLowerCase();
|
|
const password = document.getElementById("reg-password")?.value || "";
|
|
|
|
if (!firstName || !lastName || !email || !password) {
|
|
alert("Bitte fuelle alle Felder aus.");
|
|
return;
|
|
}
|
|
|
|
if (!email.includes("@")) {
|
|
alert("Bitte gib eine gueltige E-Mail-Adresse ein.");
|
|
return;
|
|
}
|
|
|
|
const existingUser = users.find((user) => user.email.toLowerCase() === email);
|
|
if (existingUser) {
|
|
alert("E-Mail bereits registriert");
|
|
return;
|
|
}
|
|
|
|
const newUser = {
|
|
firstName,
|
|
lastName,
|
|
email,
|
|
password,
|
|
orders: [],
|
|
paymentMethods: []
|
|
};
|
|
|
|
users.push(newUser);
|
|
currentUser = newUser;
|
|
|
|
persistUsers();
|
|
persistCurrentUser();
|
|
|
|
alert("Registrierung erfolgreich");
|
|
document.getElementById("register-modal")?.classList.add("hidden");
|
|
|
|
openAccountDashboard();
|
|
}
|
|
|
|
function loginUser() {
|
|
const email = (document.getElementById("login-email")?.value.trim() || "").toLowerCase();
|
|
const password = document.getElementById("login-password")?.value || "";
|
|
|
|
const user = users.find(
|
|
(entry) => entry.email.toLowerCase() === email && entry.password === password
|
|
);
|
|
|
|
if (!user) {
|
|
document.getElementById("login-error")?.classList.remove("hidden");
|
|
return;
|
|
}
|
|
|
|
currentUser = user;
|
|
persistCurrentUser();
|
|
openAccountDashboard();
|
|
}
|
|
|
|
function openAccountDashboard() {
|
|
const accountView = document.getElementById("account-view");
|
|
if (!accountView) {
|
|
return;
|
|
}
|
|
|
|
if (!currentUser) {
|
|
accountView.innerHTML = "<div class='account-login-box'><h2>Mein Konto</h2><p>Bitte melde dich an oder registriere dich.</p></div>";
|
|
return;
|
|
}
|
|
|
|
accountView.innerHTML = `
|
|
<div class="account-panel">
|
|
<div class="account-panel-header">
|
|
<h2>Mein Konto</h2>
|
|
<button class="account-logout-btn" onclick="logoutUser()">Abmelden</button>
|
|
</div>
|
|
|
|
<div class="account-tabs">
|
|
<button class="account-tab-btn" onclick="renderPersonalInfo()">Persönliche Daten</button>
|
|
<button class="account-tab-btn" onclick="renderOrders()">Meine Bestellungen</button>
|
|
<button class="account-tab-btn" onclick="renderPayments()">Zahlungsmethoden</button>
|
|
</div>
|
|
|
|
<div id="account-tab-content"></div>
|
|
</div>
|
|
`;
|
|
|
|
renderPersonalInfo();
|
|
}
|
|
|
|
function renderPersonalInfo() {
|
|
const target = document.getElementById("account-tab-content");
|
|
if (!target || !currentUser) {
|
|
return;
|
|
}
|
|
|
|
target.innerHTML = `
|
|
<div class="account-card">
|
|
<p><strong>Vorname:</strong> ${currentUser.firstName || "-"}</p>
|
|
<p><strong>Nachname:</strong> ${currentUser.lastName || "-"}</p>
|
|
<p><strong>E-Mail:</strong> ${currentUser.email || "-"}</p>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function renderOrders() {
|
|
const target = document.getElementById("account-tab-content");
|
|
if (!target || !currentUser) {
|
|
return;
|
|
}
|
|
|
|
const orders = Array.isArray(currentUser.orders) ? currentUser.orders : [];
|
|
|
|
if (!orders.length) {
|
|
target.innerHTML = `
|
|
<div class="account-card">
|
|
<h3>Meine Bestellungen</h3>
|
|
<p>Noch keine Bestellungen vorhanden.</p>
|
|
</div>
|
|
`;
|
|
return;
|
|
}
|
|
|
|
const orderHtml = orders
|
|
.map((order, index) => {
|
|
const movieItems = Array.isArray(order.items)
|
|
? order.items.filter((item) => item.category === "movie")
|
|
: [];
|
|
const previewItem = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null);
|
|
const previewTitle = previewItem?.title || "Bestellung";
|
|
const ticketsCount = movieItems.length || (Array.isArray(order.items) ? order.items.length : 0);
|
|
|
|
return `
|
|
<button type="button" class="order-box order-item-btn" data-order-index="${index}">
|
|
<div class="order-item-head">
|
|
<h4>${escapeHtml(previewTitle)}</h4>
|
|
<span>${formatEuro(order.total || 0)}</span>
|
|
</div>
|
|
<p><strong>Datum:</strong> ${escapeHtml(order.date || "-")}</p>
|
|
<p><strong>Anzahl:</strong> ${ticketsCount}x</p>
|
|
</button>
|
|
`;
|
|
})
|
|
.join("");
|
|
|
|
target.innerHTML = `
|
|
<div class="account-orders-shell">
|
|
<h3>Meine Bestellungen</h3>
|
|
<p class="account-payments-note">Klicke auf eine Bestellung, um dein Ticket-Detail zu sehen.</p>
|
|
<div class="account-orders-grid">${orderHtml}</div>
|
|
<div id="order-ticket-details" class="order-ticket-details hidden"></div>
|
|
</div>
|
|
`;
|
|
|
|
const detailTarget = document.getElementById("order-ticket-details");
|
|
const orderButtons = Array.from(target.querySelectorAll(".order-item-btn"));
|
|
|
|
const renderOrderTicket = (orderIndex) => {
|
|
const order = orders[orderIndex];
|
|
if (!order || !detailTarget) {
|
|
return;
|
|
}
|
|
|
|
const movieItems = Array.isArray(order.items)
|
|
? order.items.filter((item) => item.category === "movie")
|
|
: [];
|
|
const primaryMovie = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null);
|
|
const poster = primaryMovie?.img || "";
|
|
const seats = movieItems.map((item) => item.seatId).filter(Boolean).join(", ") || "-";
|
|
const ticketCount = movieItems.length || (Array.isArray(order.items) ? order.items.length : 0);
|
|
const hall = primaryMovie?.hall || "-";
|
|
const time = primaryMovie?.time ? `${primaryMovie.time} Uhr` : "-";
|
|
|
|
detailTarget.innerHTML = `
|
|
<article class="order-ticket-card">
|
|
<div class="order-ticket-poster">
|
|
${poster
|
|
? `<img src="${escapeHtml(poster)}" alt="${escapeHtml(primaryMovie?.title || "Film")}">`
|
|
: `<div class="order-ticket-poster-fallback">Kein Poster</div>`}
|
|
</div>
|
|
<div class="order-ticket-content">
|
|
<div class="order-ticket-brand">EAGLE'S IMAX | Bestell-Details</div>
|
|
<h4>${escapeHtml(primaryMovie?.title || "Bestellung")}</h4>
|
|
<div class="order-ticket-grid">
|
|
<p><span>Datum</span><strong>${escapeHtml(order.date || "-")}</strong></p>
|
|
<p><span>Saal</span><strong>${escapeHtml(hall)}</strong></p>
|
|
<p><span>Uhrzeit</span><strong>${escapeHtml(time)}</strong></p>
|
|
<p><span>Tickets</span><strong>${ticketCount}x</strong></p>
|
|
<p><span>Sitze</span><strong>${escapeHtml(seats)}</strong></p>
|
|
<p><span>Gesamt</span><strong>${formatEuro(order.total || 0)}</strong></p>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
`;
|
|
|
|
detailTarget.classList.remove("hidden");
|
|
orderButtons.forEach((button) => {
|
|
button.classList.toggle("active", Number(button.dataset.orderIndex) === orderIndex);
|
|
});
|
|
};
|
|
|
|
orderButtons.forEach((button) => {
|
|
button.addEventListener("click", () => {
|
|
const orderIndex = Number(button.dataset.orderIndex || -1);
|
|
if (orderIndex >= 0) {
|
|
renderOrderTicket(orderIndex);
|
|
}
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
function renderPayments() {
|
|
const target = document.getElementById("account-tab-content");
|
|
if (!target || !currentUser) {
|
|
return;
|
|
}
|
|
|
|
target.innerHTML = `
|
|
<div class="account-card">
|
|
<h3>Zahlungsmethoden</h3>
|
|
<p class="account-payments-note">Platzhalter zum Hinterlegen deiner Logos oder Anbieter-Informationen.</p>
|
|
<div class="account-payment-grid">
|
|
<button type="button" class="account-payment-card account-pay-trigger" data-pay-modal="pay-modal-card">
|
|
<div class="payment-logo-slot">
|
|
<img src="img/mastercard.png" alt="Mastercard">
|
|
</div>
|
|
<h4>Visa / Mastercard</h4>
|
|
<p>Karteninformationen hinterlegen</p>
|
|
</button>
|
|
<button type="button" class="account-payment-card account-pay-trigger" data-pay-modal="pay-modal-paypal">
|
|
<div class="payment-logo-slot">
|
|
<img src="img/paypal.png" alt="PayPal">
|
|
</div>
|
|
<h4>PayPal</h4>
|
|
<p>Konto verbinden</p>
|
|
</button>
|
|
<button type="button" class="account-payment-card account-pay-trigger" data-pay-modal="pay-modal-apple">
|
|
<div class="payment-logo-slot">
|
|
<img src="img/applepay.png" alt="Apple Pay">
|
|
</div>
|
|
<h4>Apple Pay</h4>
|
|
<p>Geraet freischalten</p>
|
|
</button>
|
|
<button type="button" class="account-payment-card account-pay-trigger" data-pay-modal="pay-modal-google">
|
|
<div class="payment-logo-slot">
|
|
<img src="img/googlepay.png" alt="Google Pay">
|
|
</div>
|
|
<h4>Google Pay</h4>
|
|
<p>Wallet verknuepfen</p>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="pay-modal-card" class="pay-modal-overlay hidden">
|
|
<div class="pay-modal-panel pay-modal-card-style">
|
|
<button type="button" class="pay-close-btn" data-pay-close>×</button>
|
|
<div class="pay-modal-head">
|
|
<img src="img/mastercard.png" alt="Kreditkarte">
|
|
<h4>Kreditkarte hinterlegen</h4>
|
|
</div>
|
|
<div class="pay-form-grid">
|
|
<label>Kartennummer
|
|
<input type="text" placeholder="1234 5678 9012 3456">
|
|
</label>
|
|
<div class="pay-form-row">
|
|
<label>Exp. Datum
|
|
<input type="text" placeholder="MM/JJ">
|
|
</label>
|
|
<label>CVV
|
|
<input type="text" placeholder="123">
|
|
</label>
|
|
</div>
|
|
<label>Name auf Karte
|
|
<input type="text" placeholder="Max Mustermann">
|
|
</label>
|
|
</div>
|
|
<button type="button" class="pay-submit-btn">Karte speichern</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="pay-modal-paypal" class="pay-modal-overlay hidden">
|
|
<div class="pay-modal-panel pay-modal-paypal-style">
|
|
<button type="button" class="pay-close-btn" data-pay-close>×</button>
|
|
<div class="pay-modal-head">
|
|
<img src="img/paypal.png" alt="PayPal">
|
|
<h4>PayPal verbinden</h4>
|
|
</div>
|
|
<p>Einloggen und dein PayPal-Konto mit deinem Kino-Account verbinden.</p>
|
|
<label>E-Mail
|
|
<input type="email" placeholder="name@beispiel.de">
|
|
</label>
|
|
<label>Passwort
|
|
<input type="password" placeholder="Passwort">
|
|
</label>
|
|
<button type="button" class="pay-submit-btn paypal-btn">Mit PayPal fortfahren</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="pay-modal-apple" class="pay-modal-overlay hidden">
|
|
<div class="pay-modal-panel pay-modal-apple-style">
|
|
<button type="button" class="pay-close-btn" data-pay-close>×</button>
|
|
<div class="pay-modal-head">
|
|
<img src="img/applepay.png" alt="Apple Pay">
|
|
<h4>Apple Pay einrichten</h4>
|
|
</div>
|
|
<p>Apple Pay wirkt schlicht, klar und fokussiert. Hinterlege hier die bevorzugte Karte für schnelle Zahlungen.</p>
|
|
<label>Apple-ID E-Mail
|
|
<input type="email" placeholder="appleid@beispiel.de">
|
|
</label>
|
|
<label>Bevorzugte Karte
|
|
<input type="text" placeholder="Visa, Mastercard, ...">
|
|
</label>
|
|
<button type="button" class="pay-submit-btn apple-btn">Zu Wallet hinzufügen</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="pay-modal-google" class="pay-modal-overlay hidden">
|
|
<div class="pay-modal-panel pay-modal-google-style">
|
|
<button type="button" class="pay-close-btn" data-pay-close>×</button>
|
|
<div class="pay-modal-head">
|
|
<img src="img/googlepay.png" alt="Google Pay">
|
|
<h4>Google Pay einrichten</h4>
|
|
</div>
|
|
<p>Verbinde deine Wallet, damit zukünftige Bestellungen in wenigen Klicks abgeschlossen werden.</p>
|
|
<label>Google-Konto
|
|
<input type="email" placeholder="konto@gmail.com">
|
|
</label>
|
|
<label>Standard-Zahlungsquelle
|
|
<input type="text" placeholder="z. B. Visa 1234">
|
|
</label>
|
|
<button type="button" class="pay-submit-btn google-btn">Wallet verbinden</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
const modals = Array.from(target.querySelectorAll(".pay-modal-overlay"));
|
|
const triggers = Array.from(target.querySelectorAll(".account-pay-trigger"));
|
|
const closeButtons = Array.from(target.querySelectorAll("[data-pay-close]"));
|
|
|
|
const closeAllPaymentModals = () => {
|
|
modals.forEach((modal) => modal.classList.add("hidden"));
|
|
document.body.style.overflow = "auto";
|
|
};
|
|
|
|
triggers.forEach((trigger) => {
|
|
trigger.addEventListener("click", () => {
|
|
closeAllPaymentModals();
|
|
const targetId = trigger.getAttribute("data-pay-modal");
|
|
const modal = targetId ? target.querySelector(`#${targetId}`) : null;
|
|
|
|
if (modal) {
|
|
modal.classList.remove("hidden");
|
|
document.body.style.overflow = "hidden";
|
|
}
|
|
});
|
|
});
|
|
|
|
closeButtons.forEach((button) => {
|
|
button.addEventListener("click", closeAllPaymentModals);
|
|
});
|
|
|
|
modals.forEach((modal) => {
|
|
modal.addEventListener("click", (event) => {
|
|
if (event.target === modal) {
|
|
closeAllPaymentModals();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function logoutUser() {
|
|
currentUser = null;
|
|
persistCurrentUser();
|
|
window.location.reload();
|
|
}
|