add TypeScript interfaces for cart and cart items

Introduces BaseCartItem, MovieCartItem, SnackCartItem, and the CartItem
discriminated union in bigConstants.ts. Replaces all any-typed cart
references across CartView, CheckoutView, SnacksView, and BookingModal
with the new typed interfaces. Also types users/currentUser with the
existing User interface and removes the unused JSONType import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jannis Heydemann
2026-05-06 08:25:16 +02:00
parent e6fee6e4e1
commit 06606131ef
5 changed files with 97 additions and 58 deletions

View File

@@ -53,6 +53,7 @@
<script>
import { currentUser, users, cart, emptyCart, occupiedSeatsData, updateCart, updateOccupiedSeats } from "../scripts/bigConstants";
import type { CartItem, MovieCartItem } from "../scripts/bigConstants";
function formatCheckoutEuro(value: number) {
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
@@ -90,15 +91,15 @@
if (!summaryList) return;
summaryList.innerHTML = "";
const total = cart.reduce((sum: number, item: any) => sum + Number(item.price || 0), 0);
const total = cart.reduce((sum: number, item: CartItem) => sum + item.price, 0);
const vat = total - total / 1.19;
cart.forEach((item: any) => {
cart.forEach((item: CartItem) => {
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 || "-"}`;
? `Sitz ${(item as MovieCartItem).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);
});
@@ -116,16 +117,16 @@
const ticketContainer = document.getElementById("ticket-container");
if (!ticketContainer) return;
const moviesInCart = cart.filter((item: any) => item.category === "movie");
const moviesInCart = cart.filter((item: CartItem): item is MovieCartItem => item.category === "movie");
if (!moviesInCart.length) {
ticketContainer.innerHTML = "<p>Danke für deinen Einkauf!</p>";
return;
}
const mainMovie = moviesInCart[0];
const mainMovie: MovieCartItem = moviesInCart[0];
const matchingMovieSeats = moviesInCart
.filter((item: any) => item.title === mainMovie.title && item.time === mainMovie.time)
.map((item: any) => item.seatId)
.filter((item: MovieCartItem) => item.title === mainMovie.title && item.time === mainMovie.time)
.map((item: MovieCartItem) => item.seatId)
.join(", ");
const qrData = encodeURIComponent(`EAGLE-IMAX|${mainMovie.title}|${mainMovie.hall}|${matchingMovieSeats}`);
@@ -154,12 +155,11 @@
}
function completeCheckout() {
const orderItems = [...cart];
const orderTotal = orderItems.reduce((sum, item) => sum + Number(item.price || 0), 0);
const orderItems: CartItem[] = [...cart];
const orderTotal = orderItems.reduce((sum: number, item: CartItem) => sum + item.price, 0);
// Save order for current user
if (currentUser && Array.isArray(users)) {
const userIndex = users.findIndex((entry: any) => entry.email === currentUser.email);
const userIndex = users.findIndex((entry: any) => entry.email === (currentUser as any).email);
if (userIndex !== -1) {
if (!Array.isArray(users[userIndex].orders)) users[userIndex].orders = [];
users[userIndex].orders.push({
@@ -172,12 +172,13 @@
}
}
// 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);
});
orderItems
.filter((item: CartItem): item is MovieCartItem => item.category === "movie")
.forEach((item: MovieCartItem) => {
const key = `${item.hall}-${item.time}`;
if (!occupiedSeatsData[key]) occupiedSeatsData[key] = [];
occupiedSeatsData[key].push(item.seatId);
});
updateOccupiedSeats(occupiedSeatsData);
emptyCart();