import type { User } from "./interfaces.js"; function readStorageJson(key: string, fallbackValue: any) { 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: User): User { return { firstName: user.firstName || "", lastName: user.lastName || "", email: user.email || "", hashedPassword: user.hashedPassword || "", orders: Array.isArray(user.orders) ? user.orders : [], paymentMethods: Array.isArray(user.paymentMethods) ? user.paymentMethods : [] }; } function escapeHtml(value: string) { return String(value || "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); } function formatEuro(value: string) { 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"); } } export let users = readStorageJson("eagleUsers", []); if (!Array.isArray(users)) { users = []; } users = users.map(normalizeUser).filter(Boolean); const rawCurrentUser = readStorageJson("currentUser", null); export var currentUser: User | null = rawCurrentUser ? normalizeUser(rawCurrentUser) : null; if (currentUser && currentUser.email) { const currentEmail = currentUser.email; const storedMatch = users.find((user: { email: string; }) => { return user.email === currentEmail; }); if (storedMatch) { currentUser = storedMatch; } else { users.push(currentUser); persistUsers(); } } async function hashMessage(message: string) { const msgBuffer = new TextEncoder().encode(message); // Encode as UTF-8 const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); // Hash const hashArray = Array.from(new Uint8Array(hashBuffer)); // Convert to bytes return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // Hex string } function getInputValue(id: string): string { const el = document.getElementById(id) as HTMLInputElement | null; return el?.value.trim() ?? ""; } export async function registerUser() { const firstName = getInputValue("reg-firstname"); const lastName = getInputValue("reg-lastname"); const email = getInputValue("reg-email").toLowerCase(); const password = document.querySelector("#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) => user.email.toLowerCase() === email); if (existingUser) { alert("E-Mail bereits registriert"); return; } const hashedPassword = await hashMessage(password); const newUser = { firstName, lastName, email, hashedPassword, orders: [], paymentMethods: [] }; users.push(newUser); currentUser = newUser; persistUsers(); persistCurrentUser(); alert("Registrierung erfolgreich"); document.getElementById("register-modal")?.classList.add("hidden"); openAccountDashboard(); } export async function loginUser() { const email = (document.querySelector("#login-email")?.value.trim() || "").toLowerCase(); const password = document.querySelector("#login-password")?.value || ""; const hashedPassword = await hashMessage(password); const user = users.find( (entry: User) => entry.email.toLowerCase() === email && entry.hashedPassword === hashedPassword ); if (!user) { document.getElementById("login-error")?.classList.remove("hidden"); return; } currentUser = user; persistCurrentUser(); openAccountDashboard(); } export function openAccountDashboard() { const accountView = document.getElementById("account-view"); if (!accountView) { return; } if (!currentUser) { accountView.innerHTML = ""; return; } accountView.innerHTML = /*html*/` `; renderPersonalInfo(); } function renderPersonalInfo() { const target = document.getElementById("account-tab-content"); if (!target || !currentUser) { return; } target.innerHTML = ` `; } 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 = ` `; return; } const orderHtml = orders .map((order, index) => { const movieItems = Array.isArray(order.items) ? order.items.filter((item: any) => 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 ` `; }) .join(""); target.innerHTML = ` `; const detailTarget = document.getElementById("order-ticket-details"); const orderButtons = Array.from(target.querySelectorAll(".order-item-btn")); const renderOrderTicket = (orderIndex: number) => { const order = orders[orderIndex]; if (!order || !detailTarget) { return; } const movieItems = Array.isArray(order.items) ? order.items.filter((item: any) => item.category === "movie") : []; const primaryMovie = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null); const poster = primaryMovie?.img || ""; const seats = movieItems.map((item: any) => 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 = `
${poster ? `${escapeHtml(primaryMovie?.title || ` : `
Kein Poster
`}
EAGLE'S IMAX | Bestell-Details

${escapeHtml(primaryMovie?.title || "Bestellung")}

Datum${escapeHtml(order.date || "-")}

Saal${escapeHtml(hall)}

Uhrzeit${escapeHtml(time)}

Tickets${ticketCount}x

Sitze${escapeHtml(seats)}

Gesamt${formatEuro(order.total || 0)}

`; 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 = /*html*/` `; 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() { persistCurrentUser(); window.location.reload(); } (window as any).logoutUser = logoutUser; (window as any).renderPersonalInfo = renderPersonalInfo; (window as any).renderOrders = renderOrders; (window as any).renderPayments = renderPayments;