Compare commits
6 Commits
10883aa381
...
dev_jannis
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e143d8360a | ||
| c805221208 | |||
|
|
40ee49aff5 | ||
|
|
c88242b2be | ||
|
|
425c5d1900 | ||
|
|
e2b4852e0d |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
dist/
|
||||||
BIN
img/cashtruck.jpg
LFS
BIN
img/cashtruck.jpg
LFS
Binary file not shown.
430
index.html
430
index.html
@@ -267,208 +267,15 @@
|
|||||||
<h1 class="list-title">Snacks & Getränke</h1>
|
<h1 class="list-title">Snacks & Getränke</h1>
|
||||||
|
|
||||||
<div class="category-tabs">
|
<div class="category-tabs">
|
||||||
<button class="tab-btn active" data-target="cat-limited">Limitierte Specials</button>
|
<button class="tab-btn active" data-target="cat-getraenke">Getränke</button>
|
||||||
<button class="tab-btn" data-target="cat-getraenke">Getränke</button>
|
|
||||||
<button class="tab-btn" data-target="cat-popcorn">Popcorn</button>
|
<button class="tab-btn" data-target="cat-popcorn">Popcorn</button>
|
||||||
<button class="tab-btn" data-target="cat-nachos">Nachos</button>
|
<button class="tab-btn" data-target="cat-nachos">Nachos</button>
|
||||||
<button class="tab-btn" data-target="cat-snacks">Snacks</button>
|
<button class="tab-btn" data-target="cat-snacks">Snacks</button>
|
||||||
|
<button class="tab-btn" data-target="cat-kombi">Kombi</button>
|
||||||
<button class="tab-btn" data-target="cat-eis">Eis</button>
|
<button class="tab-btn" data-target="cat-eis">Eis</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="cat-limited" class="snack-category active limited-specials-category">
|
<div id="cat-getraenke" class="snack-category active">
|
||||||
<div class="limited-specials-hero">
|
|
||||||
<div>
|
|
||||||
<span class="limited-kicker">Nur für kurze Zeit</span>
|
|
||||||
<h2>Limitierte Specials</h2>
|
|
||||||
<p>Filmbecher, Sammler-Eimer und Kids-Menüs als kleine Vitrine für besondere Aktionen.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="limited-special-block">
|
|
||||||
<div class="special-film-heading">
|
|
||||||
<img src="img/Zoomania-2.jpg" alt="Zoomania 2 Logo">
|
|
||||||
<div>
|
|
||||||
<span>Zoomania 2</span>
|
|
||||||
<h2>City Edition</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="limited-special-grid">
|
|
||||||
<div class="snack-card limited-special-card">
|
|
||||||
<div class="snack-img"><img src="img/zoomania-popcorn.jpg" alt="Zoomania 2 Metallbecher"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Metallbecher</span>
|
|
||||||
<h3>Limitierter Metallbecher - Zoomania 2</h3>
|
|
||||||
<p class="snack-card-note">Sammlerbecher mit Popcornfüllung, wahlweise süß oder salzig.</p>
|
|
||||||
<div class="option-group">
|
|
||||||
<button class="opt-btn active">Süß</button>
|
|
||||||
<button class="opt-btn">Salzig</button>
|
|
||||||
</div>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Special <span>12,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="snack-card limited-special-card wide-special">
|
|
||||||
<div class="snack-img"><img src="img/zoomaniakidsmenu.jpg" alt="Zoomania Kids Menu"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Kids Special</span>
|
|
||||||
<h3>Zoomania Kids Menü</h3>
|
|
||||||
<p class="snack-card-note">0,5L Getränk im Zoomania Becher + Zoomania Popcorn Schale + Figur zum Aussuchen.</p>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Menü-Preis <span>10,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="limited-special-block">
|
|
||||||
<div class="special-film-heading">
|
|
||||||
<img src="img/screamvii.jpg" alt="Scream VII Logo">
|
|
||||||
<div>
|
|
||||||
<span>Scream VII</span>
|
|
||||||
<h2>Horror Collectors</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="limited-special-grid compact-specials">
|
|
||||||
<div class="snack-card limited-special-card">
|
|
||||||
<div class="snack-img"><img src="img/screamdoorpopcorn.jpg" alt="Scream VII Sammelbecher"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Collector</span>
|
|
||||||
<h3>Limitierter Sammelbecher - Scream VII</h3>
|
|
||||||
<p class="snack-card-note">Dunkler Sammlerbecher passend zum Horrorabend.</p>
|
|
||||||
<div class="option-group">
|
|
||||||
<button class="opt-btn active">Süß</button>
|
|
||||||
<button class="opt-btn">Salzig</button>
|
|
||||||
</div>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Special <span>29,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="limited-special-block">
|
|
||||||
<div class="special-film-heading">
|
|
||||||
<img src="img/derAustronaut.jpg" alt="Der Austronaut Logo">
|
|
||||||
<div>
|
|
||||||
<span>Project Hail Mary</span>
|
|
||||||
<h2>Space Collection</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="limited-special-grid compact-specials">
|
|
||||||
<div class="snack-card limited-special-card">
|
|
||||||
<div class="snack-img"><img src="img/astronautpopcorn.jpg" alt="Der Austronaut Sammelbecher"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Space Cup</span>
|
|
||||||
<h3>Limitierter Sammelbecher - Der Austronaut</h3>
|
|
||||||
<p class="snack-card-note">Großer Sammlerbecher im Sci-Fi-Look für deine Mission ins Kino.</p>
|
|
||||||
<div class="option-group">
|
|
||||||
<button class="opt-btn active">Süß</button>
|
|
||||||
<button class="opt-btn">Salzig</button>
|
|
||||||
</div>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Special <span>34,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="limited-special-block">
|
|
||||||
<div class="special-film-heading">
|
|
||||||
<img src="img/hoppers.jpg" alt="Hoppers Logo">
|
|
||||||
<div>
|
|
||||||
<span>Hoppers</span>
|
|
||||||
<h2>Family Specials</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="limited-special-grid">
|
|
||||||
<div class="snack-card limited-special-card">
|
|
||||||
<div class="snack-img"><img src="img/hopperspopcornmetall.jpg" alt="Hoppers Metallbecher"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Metallbecher</span>
|
|
||||||
<h3>Limitierter Metallbecher - Hoppers</h3>
|
|
||||||
<p class="snack-card-note">Stabiler Becher mit Popcornfüllung.</p>
|
|
||||||
<div class="option-group">
|
|
||||||
<button class="opt-btn active">Süß</button>
|
|
||||||
<button class="opt-btn">Salzig</button>
|
|
||||||
</div>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Special <span>12,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="snack-card limited-special-card">
|
|
||||||
<div class="snack-img"><img src="img/hopperspopcornwood.png" alt="Hoppers Sammelbecher"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Collector</span>
|
|
||||||
<h3>Limitierter Sammelbecher - Hoppers</h3>
|
|
||||||
<p class="snack-card-note">Sammlerbecher mit warmem Popcornmoment.</p>
|
|
||||||
<div class="option-group">
|
|
||||||
<button class="opt-btn active">Süß</button>
|
|
||||||
<button class="opt-btn">Salzig</button>
|
|
||||||
</div>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Special <span>21,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="snack-card limited-special-card wide-special">
|
|
||||||
<div class="snack-img"><img src="img/hopperskidsmenu.jpg" alt="Hoppers Kids Menu"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Kids Special</span>
|
|
||||||
<h3>Hoppers Kids Menü</h3>
|
|
||||||
<p class="snack-card-note">0,5L Getränk im Hoppers Becher + Hoppers Popcorn Schale + Hoppers Figur.</p>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Menü-Preis <span>10,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="limited-special-block">
|
|
||||||
<div class="special-film-heading">
|
|
||||||
<img src="img/mariogalaxy.jpg" alt="Mario Galaxy Logo">
|
|
||||||
<div>
|
|
||||||
<span>Super Mario Galaxy</span>
|
|
||||||
<h2>Galaxy Specials</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="limited-special-grid">
|
|
||||||
<div class="snack-card limited-special-card">
|
|
||||||
<div class="snack-img"><img src="img/marioyoshipopcorn.png" alt="Yoshi Sammelbecher"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Yoshi Cup</span>
|
|
||||||
<h3>Limitierter Sammelbecher - Yoshi Becher</h3>
|
|
||||||
<p class="snack-card-note">Verspielter Sammlerbecher für Mario-Fans.</p>
|
|
||||||
<div class="option-group">
|
|
||||||
<button class="opt-btn active">Süß</button>
|
|
||||||
<button class="opt-btn">Salzig</button>
|
|
||||||
</div>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Special <span>35,90€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="snack-card limited-special-card wide-special">
|
|
||||||
<div class="snack-img"><img src="img/mariokidsmenu.png" alt="Mario Kids Menu"></div>
|
|
||||||
<div class="snack-info">
|
|
||||||
<span class="badge">Kids Special</span>
|
|
||||||
<h3>Mario Galaxy Kids Menü</h3>
|
|
||||||
<p class="snack-card-note">0,5L Getränk im Mario Galaxy Becher + Mario Galaxy Popcorn Schale.</p>
|
|
||||||
<div class="size-selector">
|
|
||||||
<button class="size-chip">Menü-Preis <span>10,00€</span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="cat-getraenke" class="snack-category hidden">
|
|
||||||
<div class="snack-grid">
|
<div class="snack-grid">
|
||||||
|
|
||||||
<div class="snack-card">
|
<div class="snack-card">
|
||||||
@@ -585,11 +392,6 @@
|
|||||||
</div> </div>
|
</div> </div>
|
||||||
|
|
||||||
<div id="cat-popcorn" class="snack-category hidden">
|
<div id="cat-popcorn" class="snack-category hidden">
|
||||||
<div class="snack-subsection">
|
|
||||||
<div class="snack-section-heading">
|
|
||||||
<span>Frisch gepoppt</span>
|
|
||||||
<h2>Einzelprodukte</h2>
|
|
||||||
</div>
|
|
||||||
<div class="snack-grid">
|
<div class="snack-grid">
|
||||||
<div class="snack-card">
|
<div class="snack-card">
|
||||||
<div class="snack-img"><img src="img/popcorn-klein.png" alt="Popcorn klein"></div>
|
<div class="snack-img"><img src="img/popcorn-klein.png" alt="Popcorn klein"></div>
|
||||||
@@ -600,7 +402,7 @@
|
|||||||
<button class="opt-btn">Salzig</button>
|
<button class="opt-btn">Salzig</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Klein <span>3,50€</span></button>
|
<button class="size-chip">3,50€</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -613,7 +415,7 @@
|
|||||||
<button class="opt-btn">Salzig</button>
|
<button class="opt-btn">Salzig</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Mittel <span>4,50€</span></button>
|
<button class="size-chip">4,50€</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -626,56 +428,91 @@
|
|||||||
<button class="opt-btn">Salzig</button>
|
<button class="opt-btn">Salzig</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Groß <span>6,00€</span></button>
|
<button class="size-chip">6,00€</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="snack-card">
|
||||||
</div>
|
<div class="snack-img"><img src="img/zoomania-popcorn.jpg" alt="Popcorn limited - zoomania 2"></div>
|
||||||
|
|
||||||
<div class="snack-subsection">
|
|
||||||
<div class="snack-section-heading popcorn-combo-heading">
|
|
||||||
<span>Für Filmabende</span>
|
|
||||||
<h2>Kombi Menü</h2>
|
|
||||||
</div>
|
|
||||||
<div class="snack-grid">
|
|
||||||
<div class="snack-card highlight">
|
|
||||||
<div class="snack-info">
|
<div class="snack-info">
|
||||||
<h3>Kleines Menü</h3>
|
<h3>Limitierter Metallbecher - Zoomania 2</h3>
|
||||||
<p class="snack-card-note">0,33L Getränk + Popcorn klein</p>
|
<div class="option-group">
|
||||||
|
<button class="opt-btn active">Süß</button>
|
||||||
|
<button class="opt-btn">Salzig</button>
|
||||||
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Menü-Preis <span>5,00€</span></button>
|
<button class="size-chip">12,00€</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="snack-card highlight">
|
<div class="snack-card">
|
||||||
|
<div class="snack-img"><img src="img/screamdoorpopcorn.jpg" alt="Popcorn limited - Scream VII"></div>
|
||||||
<div class="snack-info">
|
<div class="snack-info">
|
||||||
<h3>Mittleres Menü</h3>
|
<h3>Limitierter Sammelbecher - Scream VII</h3>
|
||||||
<p class="snack-card-note">0,5L Getränk + Popcorn mittel</p>
|
<div class="option-group">
|
||||||
|
<button class="opt-btn active">Süß</button>
|
||||||
|
<button class="opt-btn">Salzig</button>
|
||||||
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Menü-Preis <span>6,50€</span></button>
|
<button class="size-chip">29,00€</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="snack-card highlight">
|
<div class="snack-card">
|
||||||
|
<div class="snack-img"><img src="img/astronautpopcorn.jpg" alt="Popcorn limited - Der Austronaut"></div>
|
||||||
<div class="snack-info">
|
<div class="snack-info">
|
||||||
<span class="badge">Bestseller</span>
|
<h3>Limitierter Sammelbecher - Der Austronaut</h3>
|
||||||
<h3>Großes Menü</h3>
|
<div class="option-group">
|
||||||
<p class="snack-card-note">1L Getränk + Popcorn groß</p>
|
<button class="opt-btn active">Süß</button>
|
||||||
|
<button class="opt-btn">Salzig</button>
|
||||||
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Menü-Preis <span>8,00€</span></button>
|
<button class="size-chip">34,00€</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="snack-card">
|
||||||
|
<div class="snack-img"><img src="img/hopperspopcornmetall.jpg" alt="Popcorn limited - Hoppers"></div>
|
||||||
|
<div class="snack-info">
|
||||||
|
<h3>Limitierter Metallbecher - Hoppers</h3>
|
||||||
|
<div class="option-group">
|
||||||
|
<button class="opt-btn active">Süß</button>
|
||||||
|
<button class="opt-btn">Salzig</button>
|
||||||
|
</div>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">12,00€</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="snack-card">
|
||||||
|
<div class="snack-img"><img src="img/hopperspopcornwood.png" alt="Popcorn limited - Hoppers"></div>
|
||||||
|
<div class="snack-info">
|
||||||
|
<h3>Limitierter Sammelbecher - Hoppers</h3>
|
||||||
|
<div class="option-group">
|
||||||
|
<button class="opt-btn active">Süß</button>
|
||||||
|
<button class="opt-btn">Salzig</button>
|
||||||
|
</div>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">21,00€</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="snack-card">
|
||||||
|
<div class="snack-img"><img src="img/marioyoshipopcorn.png" alt="Popcorn limited - Yoshi"></div>
|
||||||
|
<div class="snack-info">
|
||||||
|
<h3>Limitierter Sammelbecher - Yoshi Becher</h3>
|
||||||
|
<div class="option-group">
|
||||||
|
<button class="opt-btn active">Süß</button>
|
||||||
|
<button class="opt-btn">Salzig</button>
|
||||||
|
</div>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">35,90€</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div id="cat-nachos" class="snack-category hidden">
|
<div id="cat-nachos" class="snack-category hidden">
|
||||||
<div class="snack-subsection">
|
|
||||||
<div class="snack-section-heading">
|
|
||||||
<span>Nachos</span>
|
|
||||||
<h2>Einzelprodukte</h2>
|
|
||||||
</div>
|
|
||||||
<div class="snack-grid">
|
<div class="snack-grid">
|
||||||
<div class="snack-card">
|
<div class="snack-card">
|
||||||
<div class="snack-img"><img src="img/nachosnormal.png" alt="Nachos"></div>
|
<div class="snack-img"><img src="img/nachosnormal.png" alt="Nachos"></div>
|
||||||
@@ -686,7 +523,7 @@
|
|||||||
<button class="opt-btn">Salsa-Dip</button>
|
<button class="opt-btn">Salsa-Dip</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Klein <span>5,00€</span></button>
|
<button class="size-chip">Klein<span>5,00€</span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -699,7 +536,7 @@
|
|||||||
<button class="opt-btn">Salsa-Dip</button>
|
<button class="opt-btn">Salsa-Dip</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Mittel <span>6,50€</span></button>
|
<button class="size-chip">Mittel<span>6,50€</span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -717,15 +554,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<h2 class="list-title"> </h2>
|
||||||
</div>
|
<br>
|
||||||
|
<h2 class="list-title">Dips</h2>
|
||||||
<div class="snack-subsection">
|
<br>
|
||||||
<div class="snack-section-heading">
|
<br>
|
||||||
<span>Extra dazu</span>
|
<br>
|
||||||
<h2>Dips</h2>
|
|
||||||
</div>
|
|
||||||
<div class="snack-grid">
|
|
||||||
<div class="snack-card">
|
<div class="snack-card">
|
||||||
<div class="snack-img"><img src="img/käsedip.png" alt="Käse-Dip"></div>
|
<div class="snack-img"><img src="img/käsedip.png" alt="Käse-Dip"></div>
|
||||||
<div class="snack-info">
|
<div class="snack-info">
|
||||||
@@ -735,7 +569,7 @@
|
|||||||
<button class="opt-btn">Scharf</button>
|
<button class="opt-btn">Scharf</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Schale <span>2,00€</span></button>
|
<button class="size-chip">Schale<span>2,00€</span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -747,7 +581,7 @@
|
|||||||
<button class="opt-btn active">Normal</button>
|
<button class="opt-btn active">Normal</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Schale <span>2,00€</span></button>
|
<button class="size-chip">Schale<span>2,00€</span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -759,32 +593,25 @@
|
|||||||
<button class="opt-btn active">Normal</button>
|
<button class="opt-btn active">Normal</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Schale <span>2,00€</span></button>
|
<button class="size-chip">Schale<span>2,00€</span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<h2 class="list-title">Nacho Kombi-Menüs</h2>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="snack-subsection">
|
|
||||||
<div class="snack-section-heading">
|
|
||||||
<span>Alles drin</span>
|
|
||||||
<h2>Kombi Menü</h2>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="snack-grid">
|
<div class="snack-card">
|
||||||
<div class="snack-card highlight">
|
|
||||||
<div class="snack-img"><img src="img/nachokombiklein.png" alt="Nacho Kombi Klein"></div>
|
<div class="snack-img"><img src="img/nachokombiklein.png" alt="Nacho Kombi Klein"></div>
|
||||||
<div class="snack-info">
|
<div class="snack-info">
|
||||||
<h3>Nacho Menü Klein</h3>
|
<h3>Nacho Menü Klein - Nachos klein + 1 Dip + 1 0,33L Getränk</h3>
|
||||||
<p class="snack-card-note">Nachos klein + 1 Dip + 1x 0,33L Getränk</p>
|
|
||||||
<div class="option-group">
|
<div class="option-group">
|
||||||
<button class="opt-btn active">Klein</button>
|
<button class="opt-btn active">Klein</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="size-selector">
|
<div class="size-selector">
|
||||||
<button class="size-chip">Kombi <span>6,90€</span></button>
|
<button class="size-chip">Kombi<span>6,90€</span></button>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -820,6 +647,75 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="cat-kombi" class="snack-category hidden">
|
||||||
|
<div class="snack-grid">
|
||||||
|
<div class="snack-card highlight">
|
||||||
|
<div class="snack-info">
|
||||||
|
<h3>Kleines Menü</h3>
|
||||||
|
<p style="font-size: 0.8rem; color: #86868b; margin-bottom: 10px;">0,33L Getränk + Popcorn Klein</p>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">Menü-Preis <span>5,00€</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="snack-card highlight">
|
||||||
|
<div class="snack-info">
|
||||||
|
<h3>Mittleres Menü</h3>
|
||||||
|
<p style="font-size: 0.8rem; color: #86868b; margin-bottom: 10px;">0,5L Getränk + Popcorn Mittel</p>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">Menü-Preis <span>6,50€</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="snack-card highlight">
|
||||||
|
<div class="snack-info">
|
||||||
|
<span class="badge">Bestseller</span>
|
||||||
|
<h3>Großes Menü</h3>
|
||||||
|
<p style="font-size: 0.8rem; color: #86868b; margin-bottom: 10px;">1L Getränk + Popcorn Groß</p>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">Menü-Preis <span>8,00€</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="snack-card highlight">
|
||||||
|
<div class="snack-info">
|
||||||
|
<div class="snack-img"><img src="img/hopperskidsmenu.jpg" alt="Hoppers Kids Menu"></div>
|
||||||
|
<span class="badge">SPECIAL</span>
|
||||||
|
<h3>Limitiertes Menü</h3>
|
||||||
|
<p style="font-size: 0.8rem; color: #86868b; margin-bottom: 10px;">0,5L Getränk im HOPPERS Becher + HOPPERS Popcorn Schale<br>+HOPPERS Figur</p>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">Menü-Preis <span>10,00€</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="snack-card highlight">
|
||||||
|
<div class="snack-info">
|
||||||
|
<div class="snack-img"><img src="img/mariokidsmenu.png" alt="Mario Kids Menu"></div>
|
||||||
|
<br>
|
||||||
|
<span class="badge">SPECIAL</span>
|
||||||
|
<h3>Limitiertes Menü</h3>
|
||||||
|
<p style="font-size: 0.8rem; color: #86868b; margin-bottom: 10px;">0,5L Getränk im MARIO GALXY Becher + MARIO GALAXY Popcorn Schale</p>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">Menü-Preis <span>10,00€</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="snack-card highlight">
|
||||||
|
<div class="snack-info">
|
||||||
|
<div class="snack-img"><img src="img/zoomaniakidsmenu.jpg" alt="Zoomania Kids Menu"></div>
|
||||||
|
<br>
|
||||||
|
<span class="badge">SPECIAL</span>
|
||||||
|
<h3>Limitiertes Menü</h3>
|
||||||
|
<p style="font-size: 0.8rem; color: #86868b; margin-bottom: 10px;">0,5L Getränk im ZOOMANIA Becher + ZOOMANIA Popcorn Schale<br>+ Figur zum aussuchen</p>
|
||||||
|
<div class="size-selector">
|
||||||
|
<button class="size-chip">Menü-Preis <span>10,00€</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="cat-eis" class="snack-category hidden">
|
<div id="cat-eis" class="snack-category hidden">
|
||||||
<div class="coming-soon-banner">
|
<div class="coming-soon-banner">
|
||||||
<h2>Eiscreme & Shakes</h2>
|
<h2>Eiscreme & Shakes</h2>
|
||||||
@@ -839,8 +735,8 @@
|
|||||||
<div class="header-sub-info">
|
<div class="header-sub-info">
|
||||||
<p id="modal-info-text">Saal • Zeit</p>
|
<p id="modal-info-text">Saal • Zeit</p>
|
||||||
<div id="tech-badges" class="tech-badges-container hidden">
|
<div id="tech-badges" class="tech-badges-container hidden">
|
||||||
<img src="img/dolby.png" alt="Dolby" class="tech-badge">
|
<img src="img/Dolby.png" alt="Dolby" class="tech-badge">
|
||||||
<img src="img/dbox.png" alt="D-Box" class="tech-badge">
|
<img src="img/dbox.jpg" alt="D-Box" class="tech-badge">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1052,11 +948,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="account.js"></script>
|
<script type="module" src="dist/main.js"></script>
|
||||||
<script src="cart.js"></script>
|
<script type="module" src="dist/cart.js"></script>
|
||||||
<script src="booking.js"></script>
|
<script type="module" src="dist/booking.js"></script>
|
||||||
<script src="checkout.js"></script>
|
<script type="module" src="dist/checkout.js"></script>
|
||||||
<script src="main.js"></script>
|
<script type="module" src="dist/account.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
3093
package-lock.json
generated
Normal file
3093
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
package.json
Normal file
25
package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "p1---kino",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"watch": "tsc --watch",
|
||||||
|
"serve": "serve .",
|
||||||
|
"run": "npm-run-all --parallel watch serve"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "ssh://git@gitea.starfour.de:2222/Aaron/Kino-Website.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "Aaron und Jannis",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "commonjs",
|
||||||
|
"devDependencies": {
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"serve": "^14.2.6",
|
||||||
|
"typescript": "^6.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
function readStorageJson(key, fallbackValue) {
|
import type { User } from "./interfaces.js";
|
||||||
|
|
||||||
|
function readStorageJson(key: string, fallbackValue: any) {
|
||||||
const raw = localStorage.getItem(key);
|
const raw = localStorage.getItem(key);
|
||||||
|
|
||||||
if (!raw || raw === "undefined" || raw === "null") {
|
if (!raw || raw === "undefined" || raw === "null") {
|
||||||
@@ -13,22 +15,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeUser(user) {
|
function normalizeUser(user: User): User {
|
||||||
if (!user || typeof user !== "object") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
firstName: user.firstName || "",
|
firstName: user.firstName || "",
|
||||||
lastName: user.lastName || "",
|
lastName: user.lastName || "",
|
||||||
email: user.email || "",
|
email: user.email || "",
|
||||||
password: user.password || "",
|
hashedPassword: user.hashedPassword || "",
|
||||||
orders: Array.isArray(user.orders) ? user.orders : [],
|
orders: Array.isArray(user.orders) ? user.orders : [],
|
||||||
paymentMethods: Array.isArray(user.paymentMethods) ? user.paymentMethods : []
|
paymentMethods: Array.isArray(user.paymentMethods) ? user.paymentMethods : []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(value) {
|
function escapeHtml(value: string) {
|
||||||
return String(value || "")
|
return String(value || "")
|
||||||
.replaceAll("&", "&")
|
.replaceAll("&", "&")
|
||||||
.replaceAll("<", "<")
|
.replaceAll("<", "<")
|
||||||
@@ -37,7 +35,7 @@ function escapeHtml(value) {
|
|||||||
.replaceAll("'", "'");
|
.replaceAll("'", "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatEuro(value) {
|
function formatEuro(value: string) {
|
||||||
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,15 +51,21 @@ function persistCurrentUser() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let users = readStorageJson("eagleUsers", []);
|
export let users = readStorageJson("eagleUsers", []);
|
||||||
if (!Array.isArray(users)) {
|
if (!Array.isArray(users)) {
|
||||||
users = [];
|
users = [];
|
||||||
}
|
}
|
||||||
users = users.map(normalizeUser).filter(Boolean);
|
users = users.map(normalizeUser).filter(Boolean);
|
||||||
|
|
||||||
let currentUser = normalizeUser(readStorageJson("currentUser", null));
|
const rawCurrentUser = readStorageJson("currentUser", null);
|
||||||
|
|
||||||
|
export var currentUser: User | null = rawCurrentUser ? normalizeUser(rawCurrentUser) : null;
|
||||||
|
|
||||||
if (currentUser && currentUser.email) {
|
if (currentUser && currentUser.email) {
|
||||||
const storedMatch = users.find((user) => user.email === currentUser.email);
|
const currentEmail = currentUser.email;
|
||||||
|
const storedMatch = users.find((user: { email: string; }) => {
|
||||||
|
return user.email === currentEmail;
|
||||||
|
});
|
||||||
if (storedMatch) {
|
if (storedMatch) {
|
||||||
currentUser = storedMatch;
|
currentUser = storedMatch;
|
||||||
} else {
|
} else {
|
||||||
@@ -70,11 +74,23 @@ if (currentUser && currentUser.email) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerUser() {
|
async function hashMessage(message: string) {
|
||||||
const firstName = document.getElementById("reg-firstname")?.value.trim() || "";
|
const msgBuffer = new TextEncoder().encode(message); // Encode as UTF-8
|
||||||
const lastName = document.getElementById("reg-lastname")?.value.trim() || "";
|
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); // Hash
|
||||||
const email = (document.getElementById("reg-email")?.value.trim() || "").toLowerCase();
|
const hashArray = Array.from(new Uint8Array(hashBuffer)); // Convert to bytes
|
||||||
const password = document.getElementById("reg-password")?.value || "";
|
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<HTMLInputElement>("#reg-password")?.value ?? "";
|
||||||
|
|
||||||
if (!firstName || !lastName || !email || !password) {
|
if (!firstName || !lastName || !email || !password) {
|
||||||
alert("Bitte fuelle alle Felder aus.");
|
alert("Bitte fuelle alle Felder aus.");
|
||||||
@@ -86,17 +102,19 @@ function registerUser() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingUser = users.find((user) => user.email.toLowerCase() === email);
|
const existingUser = users.find((user: User) => user.email.toLowerCase() === email);
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
alert("E-Mail bereits registriert");
|
alert("E-Mail bereits registriert");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hashedPassword = await hashMessage(password);
|
||||||
|
|
||||||
const newUser = {
|
const newUser = {
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
email,
|
email,
|
||||||
password,
|
hashedPassword,
|
||||||
orders: [],
|
orders: [],
|
||||||
paymentMethods: []
|
paymentMethods: []
|
||||||
};
|
};
|
||||||
@@ -113,12 +131,13 @@ function registerUser() {
|
|||||||
openAccountDashboard();
|
openAccountDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
function loginUser() {
|
export async function loginUser() {
|
||||||
const email = (document.getElementById("login-email")?.value.trim() || "").toLowerCase();
|
const email = (document.querySelector<HTMLInputElement>("#login-email")?.value.trim() || "").toLowerCase();
|
||||||
const password = document.getElementById("login-password")?.value || "";
|
const password = document.querySelector<HTMLInputElement>("#login-password")?.value || "";
|
||||||
|
const hashedPassword = await hashMessage(password);
|
||||||
|
|
||||||
const user = users.find(
|
const user = users.find(
|
||||||
(entry) => entry.email.toLowerCase() === email && entry.password === password
|
(entry: User) => entry.email.toLowerCase() === email && entry.hashedPassword === hashedPassword
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@@ -131,7 +150,7 @@ function loginUser() {
|
|||||||
openAccountDashboard();
|
openAccountDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
function openAccountDashboard() {
|
export function openAccountDashboard() {
|
||||||
const accountView = document.getElementById("account-view");
|
const accountView = document.getElementById("account-view");
|
||||||
if (!accountView) {
|
if (!accountView) {
|
||||||
return;
|
return;
|
||||||
@@ -142,7 +161,7 @@ function openAccountDashboard() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
accountView.innerHTML = `
|
accountView.innerHTML = /*html*/`
|
||||||
<div class="account-panel">
|
<div class="account-panel">
|
||||||
<div class="account-panel-header">
|
<div class="account-panel-header">
|
||||||
<h2>Mein Konto</h2>
|
<h2>Mein Konto</h2>
|
||||||
@@ -198,7 +217,7 @@ function renderOrders() {
|
|||||||
const orderHtml = orders
|
const orderHtml = orders
|
||||||
.map((order, index) => {
|
.map((order, index) => {
|
||||||
const movieItems = Array.isArray(order.items)
|
const movieItems = Array.isArray(order.items)
|
||||||
? order.items.filter((item) => item.category === "movie")
|
? order.items.filter((item: any) => item.category === "movie")
|
||||||
: [];
|
: [];
|
||||||
const previewItem = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null);
|
const previewItem = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null);
|
||||||
const previewTitle = previewItem?.title || "Bestellung";
|
const previewTitle = previewItem?.title || "Bestellung";
|
||||||
@@ -227,20 +246,20 @@ function renderOrders() {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const detailTarget = document.getElementById("order-ticket-details");
|
const detailTarget = document.getElementById("order-ticket-details");
|
||||||
const orderButtons = Array.from(target.querySelectorAll(".order-item-btn"));
|
const orderButtons = Array.from(target.querySelectorAll<HTMLButtonElement>(".order-item-btn"));
|
||||||
|
|
||||||
const renderOrderTicket = (orderIndex) => {
|
const renderOrderTicket = (orderIndex: number) => {
|
||||||
const order = orders[orderIndex];
|
const order = orders[orderIndex];
|
||||||
if (!order || !detailTarget) {
|
if (!order || !detailTarget) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const movieItems = Array.isArray(order.items)
|
const movieItems = Array.isArray(order.items)
|
||||||
? order.items.filter((item) => item.category === "movie")
|
? order.items.filter((item: any) => item.category === "movie")
|
||||||
: [];
|
: [];
|
||||||
const primaryMovie = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null);
|
const primaryMovie = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null);
|
||||||
const poster = primaryMovie?.img || "";
|
const poster = primaryMovie?.img || "";
|
||||||
const seats = movieItems.map((item) => item.seatId).filter(Boolean).join(", ") || "-";
|
const seats = movieItems.map((item: any) => item.seatId).filter(Boolean).join(", ") || "-";
|
||||||
const ticketCount = movieItems.length || (Array.isArray(order.items) ? order.items.length : 0);
|
const ticketCount = movieItems.length || (Array.isArray(order.items) ? order.items.length : 0);
|
||||||
const hall = primaryMovie?.hall || "-";
|
const hall = primaryMovie?.hall || "-";
|
||||||
const time = primaryMovie?.time ? `${primaryMovie.time} Uhr` : "-";
|
const time = primaryMovie?.time ? `${primaryMovie.time} Uhr` : "-";
|
||||||
@@ -290,7 +309,7 @@ function renderPayments() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
target.innerHTML = `
|
target.innerHTML = /*html*/`
|
||||||
<div class="account-card">
|
<div class="account-card">
|
||||||
<h3>Zahlungsmethoden</h3>
|
<h3>Zahlungsmethoden</h3>
|
||||||
<p class="account-payments-note">Platzhalter zum Hinterlegen deiner Logos oder Anbieter-Informationen.</p>
|
<p class="account-payments-note">Platzhalter zum Hinterlegen deiner Logos oder Anbieter-Informationen.</p>
|
||||||
@@ -444,7 +463,7 @@ function renderPayments() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function logoutUser() {
|
function logoutUser() {
|
||||||
currentUser = null;
|
|
||||||
persistCurrentUser();
|
persistCurrentUser();
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
let currentBookingContext = null;
|
import { seatLayouts, occupiedSeatsData, prices, cart } from "./main.js"
|
||||||
let currentHallLayout = null;
|
import { renderCart, saveCart } from "./cart.js";
|
||||||
|
import { renderCheckout } from "./checkout.js";
|
||||||
|
|
||||||
function openBooking(movie, hall, time) {
|
let currentBookingContext: any = null;
|
||||||
|
let currentHallLayout: any = null;
|
||||||
|
|
||||||
|
export function openBooking(movie: string, hall: string, time: any) {
|
||||||
const titleEl = document.getElementById("modal-movie-title");
|
const titleEl = document.getElementById("modal-movie-title");
|
||||||
const infoEl = document.getElementById("modal-info-text");
|
const infoEl = document.getElementById("modal-info-text");
|
||||||
|
|
||||||
@@ -20,13 +24,13 @@ function openBooking(movie, hall, time) {
|
|||||||
updateBookingSummary();
|
updateBookingSummary();
|
||||||
|
|
||||||
document.getElementById("booking-modal")?.classList.remove("hidden");
|
document.getElementById("booking-modal")?.classList.remove("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRowLabel(rowIndex) {
|
function getRowLabel(rowIndex: number) {
|
||||||
return String(rowIndex + 1);
|
return String(rowIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildHallLayout(hallName, baseConfig) {
|
function buildHallLayout(hallName: string, baseConfig:any) {
|
||||||
const rows = Number(baseConfig.rows || 0);
|
const rows = Number(baseConfig.rows || 0);
|
||||||
const totalCols = Number(baseConfig.left || 0) + Number(baseConfig.right || 0);
|
const totalCols = Number(baseConfig.left || 0) + Number(baseConfig.right || 0);
|
||||||
const isDeluxe = /deluxe/i.test(hallName);
|
const isDeluxe = /deluxe/i.test(hallName);
|
||||||
@@ -39,7 +43,7 @@ function buildHallLayout(hallName, baseConfig) {
|
|||||||
const vipRows = rows > 0 ? [rows] : [];
|
const vipRows = rows > 0 ? [rows] : [];
|
||||||
|
|
||||||
const dboxMap = new Set();
|
const dboxMap = new Set();
|
||||||
const markDboxRange = (rowNumber, startCol, width) => {
|
const markDboxRange = (rowNumber: number, startCol: number, width: number) => {
|
||||||
if (!rowNumber || width <= 0) {
|
if (!rowNumber || width <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -52,7 +56,7 @@ function buildHallLayout(hallName, baseConfig) {
|
|||||||
|
|
||||||
if (isDeluxe) {
|
if (isDeluxe) {
|
||||||
const configuredDboxSeats = Array.isArray(baseConfig.dbox)
|
const configuredDboxSeats = Array.isArray(baseConfig.dbox)
|
||||||
? baseConfig.dbox.reduce((sum, section) => sum + Number(section.w || 0), 0)
|
? baseConfig.dbox.reduce((sum: number, section: any) => sum + Number(section.w || 0), 0)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
const totalDboxSeats = Math.max(4, configuredDboxSeats || 0);
|
const totalDboxSeats = Math.max(4, configuredDboxSeats || 0);
|
||||||
@@ -77,7 +81,7 @@ function buildHallLayout(hallName, baseConfig) {
|
|||||||
markDboxRange(rowNumber, startCol, seatsForRow);
|
markDboxRange(rowNumber, startCol, seatsForRow);
|
||||||
});
|
});
|
||||||
} else if (Array.isArray(baseConfig.dbox)) {
|
} else if (Array.isArray(baseConfig.dbox)) {
|
||||||
baseConfig.dbox.forEach((section) => {
|
baseConfig.dbox.forEach((section: any) => {
|
||||||
const rowNumber = Number(section.r || 0);
|
const rowNumber = Number(section.r || 0);
|
||||||
const width = Number(section.w || 0);
|
const width = Number(section.w || 0);
|
||||||
const startCol = Number(section.c || 0);
|
const startCol = Number(section.c || 0);
|
||||||
@@ -96,7 +100,7 @@ function buildHallLayout(hallName, baseConfig) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSeatType(layout, rowNumber, colNumber) {
|
function getSeatType(layout: any, rowNumber: number, colNumber: number) {
|
||||||
if (layout.dboxMap.has(`${rowNumber}-${colNumber}`)) {
|
if (layout.dboxMap.has(`${rowNumber}-${colNumber}`)) {
|
||||||
return "dbox";
|
return "dbox";
|
||||||
}
|
}
|
||||||
@@ -112,7 +116,7 @@ function getSeatType(layout, rowNumber, colNumber) {
|
|||||||
return "normal";
|
return "normal";
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSeatElement({ seatId, seatType, occupiedSeats }) {
|
function createSeatElement({seatId, seatType, occupiedSeats }:any) {
|
||||||
const seat = document.createElement("button");
|
const seat = document.createElement("button");
|
||||||
seat.type = "button";
|
seat.type = "button";
|
||||||
seat.classList.add("seat", seatType);
|
seat.classList.add("seat", seatType);
|
||||||
@@ -136,7 +140,7 @@ function createSeatElement({ seatId, seatType, occupiedSeats }) {
|
|||||||
return seat;
|
return seat;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSeats(hallName, time) {
|
function createSeats(hallName: string, time: any) {
|
||||||
const seatGrid = document.getElementById("seat-grid");
|
const seatGrid = document.getElementById("seat-grid");
|
||||||
if (!seatGrid) {
|
if (!seatGrid) {
|
||||||
return;
|
return;
|
||||||
@@ -144,7 +148,8 @@ function createSeats(hallName, time) {
|
|||||||
|
|
||||||
seatGrid.innerHTML = "";
|
seatGrid.innerHTML = "";
|
||||||
|
|
||||||
const baseConfig = seatLayouts[hallName];
|
const arrIndex = hallName as keyof typeof seatLayouts;
|
||||||
|
const baseConfig: any = seatLayouts[arrIndex];
|
||||||
if (!baseConfig) {
|
if (!baseConfig) {
|
||||||
currentHallLayout = null;
|
currentHallLayout = null;
|
||||||
return;
|
return;
|
||||||
@@ -235,7 +240,7 @@ function renderBookingLegend() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateBookingSummary() {
|
function updateBookingSummary() {
|
||||||
const selectedSeats = Array.from(document.querySelectorAll("#seat-grid .seat.selected"));
|
const selectedSeats = Array.from(document.querySelectorAll("#seat-grid .seat.selected")) as HTMLElement[];;
|
||||||
const summaryPanel = document.getElementById("booking-summary");
|
const summaryPanel = document.getElementById("booking-summary");
|
||||||
const summaryItems = document.getElementById("summary-items");
|
const summaryItems = document.getElementById("summary-items");
|
||||||
const totalEl = document.getElementById("total-price");
|
const totalEl = document.getElementById("total-price");
|
||||||
@@ -245,7 +250,7 @@ function updateBookingSummary() {
|
|||||||
if (summaryItems) {
|
if (summaryItems) {
|
||||||
summaryItems.innerHTML = selectedSeats
|
summaryItems.innerHTML = selectedSeats
|
||||||
.map((seat) => {
|
.map((seat) => {
|
||||||
const type = seat.dataset.type || "normal";
|
const type = (seat.dataset.type || "normal") as keyof typeof prices;
|
||||||
const seatPrice = Number(prices?.[type] ?? prices?.normal ?? 11);
|
const seatPrice = Number(prices?.[type] ?? prices?.normal ?? 11);
|
||||||
total += seatPrice;
|
total += seatPrice;
|
||||||
|
|
||||||
@@ -272,12 +277,13 @@ function updateBookingSummary() {
|
|||||||
summaryPanel?.classList.toggle("hidden", selectedSeats.length === 0);
|
summaryPanel?.classList.toggle("hidden", selectedSeats.length === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function findMoviePoster(movieTitle) {
|
function findMoviePoster(movieTitle: string) {
|
||||||
const cards = Array.from(document.querySelectorAll(".movie-card, .detailed-card"));
|
const cards = Array.from(document.querySelectorAll(".movie-card, .detailed-card"));
|
||||||
const normalizedTarget = String(movieTitle || "").trim().toLowerCase();
|
const normalizedTarget = String(movieTitle || "").trim().toLowerCase();
|
||||||
|
|
||||||
for (const card of cards) {
|
for (const card of cards) {
|
||||||
const title = card.querySelector("h2, h3")?.innerText?.trim().toLowerCase();
|
const currentCard = card.querySelector("h2, h3") as HTMLElement;
|
||||||
|
const title = currentCard.innerText?.trim().toLowerCase();
|
||||||
if (title === normalizedTarget) {
|
if (title === normalizedTarget) {
|
||||||
const imageSrc = card.querySelector("img")?.src;
|
const imageSrc = card.querySelector("img")?.src;
|
||||||
if (imageSrc) {
|
if (imageSrc) {
|
||||||
@@ -290,7 +296,7 @@ function findMoviePoster(movieTitle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function confirmSelectedSeats() {
|
function confirmSelectedSeats() {
|
||||||
const selectedSeats = Array.from(document.querySelectorAll("#seat-grid .seat.selected"));
|
const selectedSeats = Array.from(document.querySelectorAll("#seat-grid .seat.selected")) as HTMLElement[];
|
||||||
|
|
||||||
if (!currentBookingContext || selectedSeats.length === 0) {
|
if (!currentBookingContext || selectedSeats.length === 0) {
|
||||||
alert("Bitte waehle mindestens einen Platz aus.");
|
alert("Bitte waehle mindestens einen Platz aus.");
|
||||||
@@ -304,7 +310,7 @@ function confirmSelectedSeats() {
|
|||||||
const seatId = seat.dataset.seatId;
|
const seatId = seat.dataset.seatId;
|
||||||
const seatType = seat.dataset.type || "normal";
|
const seatType = seat.dataset.type || "normal";
|
||||||
|
|
||||||
const alreadyInCart = cart.some((item) =>
|
const alreadyInCart = cart.some((item: any) =>
|
||||||
item.category === "movie" &&
|
item.category === "movie" &&
|
||||||
item.title === currentBookingContext.movie &&
|
item.title === currentBookingContext.movie &&
|
||||||
item.hall === currentBookingContext.hall &&
|
item.hall === currentBookingContext.hall &&
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
function formatEuro(value) {
|
import { cart } from "./main.js";
|
||||||
|
|
||||||
|
function formatEuro(value: number) {
|
||||||
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(value) {
|
function escapeHtml(value: any) {
|
||||||
return String(value || "")
|
return String(value || "")
|
||||||
.replaceAll("&", "&")
|
.replaceAll("&", "&")
|
||||||
.replaceAll("<", "<")
|
.replaceAll("<", "<")
|
||||||
@@ -11,14 +13,14 @@ function escapeHtml(value) {
|
|||||||
.replaceAll("'", "'");
|
.replaceAll("'", "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildCartKey(item) {
|
function buildCartKey(item: { category: string; seatId: any; hall: any; time: any; title: any; }) {
|
||||||
const infoText = item.category === "movie"
|
const infoText = item.category === "movie"
|
||||||
? `Sitz: ${item.seatId} (${item.hall})`
|
? `Sitz: ${item.seatId} (${item.hall})`
|
||||||
: item.time;
|
: item.time;
|
||||||
return `${item.title}-${item.hall}-${infoText}`;
|
return `${item.title}-${item.hall}-${infoText}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDrinkItem(item) {
|
function isDrinkItem(item: { category: string; title: any; hall: any; }) {
|
||||||
if (item.category !== "snack") {
|
if (item.category !== "snack") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -39,7 +41,7 @@ function isDrinkItem(item) {
|
|||||||
return drinkKeywords.some((word) => title.includes(word)) || size.includes("l");
|
return drinkKeywords.some((word) => title.includes(word)) || size.includes("l");
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildItemInfo(item) {
|
function buildItemInfo(item: { category: any; seatId?: any; hall: any; time?: any; title: any; }) {
|
||||||
if (item.category === "movie") {
|
if (item.category === "movie") {
|
||||||
return `
|
return `
|
||||||
<div>Sitzplatz: ${escapeHtml(item.seatId || "-")}</div>
|
<div>Sitzplatz: ${escapeHtml(item.seatId || "-")}</div>
|
||||||
@@ -65,7 +67,7 @@ function buildItemInfo(item) {
|
|||||||
function groupCartItems() {
|
function groupCartItems() {
|
||||||
const groups = new Map();
|
const groups = new Map();
|
||||||
|
|
||||||
cart.forEach((item) => {
|
cart.forEach((item: { price?: any; category: string; seatId: any; hall: any; time: any; title: any; }) => {
|
||||||
const key = buildCartKey(item);
|
const key = buildCartKey(item);
|
||||||
|
|
||||||
if (!groups.has(key)) {
|
if (!groups.has(key)) {
|
||||||
@@ -85,12 +87,12 @@ function groupCartItems() {
|
|||||||
return Array.from(groups.values());
|
return Array.from(groups.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveCart() {
|
export function saveCart() {
|
||||||
localStorage.setItem("eagleCart", JSON.stringify(cart));
|
localStorage.setItem("eagleCart", JSON.stringify(cart));
|
||||||
updateCartBadge();
|
updateCartBadge();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCartBadge() {
|
export function updateCartBadge() {
|
||||||
const cartBadge = document.getElementById("cart-badge");
|
const cartBadge = document.getElementById("cart-badge");
|
||||||
|
|
||||||
if (!cartBadge) {
|
if (!cartBadge) {
|
||||||
@@ -101,7 +103,7 @@ function updateCartBadge() {
|
|||||||
cartBadge.classList.toggle("hidden", cart.length === 0);
|
cartBadge.classList.toggle("hidden", cart.length === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCart() {
|
export function renderCart() {
|
||||||
const cartList = document.getElementById("cart-items-list");
|
const cartList = document.getElementById("cart-items-list");
|
||||||
const totalEl = document.getElementById("cart-total-right");
|
const totalEl = document.getElementById("cart-total-right");
|
||||||
const vatEl = document.getElementById("cart-vat-right");
|
const vatEl = document.getElementById("cart-vat-right");
|
||||||
@@ -119,7 +121,7 @@ function renderCart() {
|
|||||||
|
|
||||||
const groupedItems = groupCartItems();
|
const groupedItems = groupCartItems();
|
||||||
|
|
||||||
const header = `
|
const header = /*html*/`
|
||||||
<div class="cart-header-row">
|
<div class="cart-header-row">
|
||||||
<div class="col-amount">MENGE</div>
|
<div class="col-amount">MENGE</div>
|
||||||
<div class="col-img">VORSCHAU</div>
|
<div class="col-img">VORSCHAU</div>
|
||||||
@@ -133,11 +135,11 @@ function renderCart() {
|
|||||||
const rows = groupedItems
|
const rows = groupedItems
|
||||||
.map((group) => {
|
.map((group) => {
|
||||||
const imageHtml = group.item.img
|
const imageHtml = group.item.img
|
||||||
? `<img class="cart-img-small" src="${escapeHtml(group.item.img)}" alt="${escapeHtml(group.item.title)}">`
|
? /*html*/`<img class="cart-img-small" src="${escapeHtml(group.item.img)}" alt="${escapeHtml(group.item.title)}">`
|
||||||
: `<div class="cart-img-fallback">Kein Bild</div>`;
|
: /*html*/`<div class="cart-img-fallback">Kein Bild</div>`;
|
||||||
const quantityHtml = group.item.category === "movie"
|
const quantityHtml = group.item.category === "movie"
|
||||||
? `<div class="qty-static" aria-label="Feste Ticketanzahl">${group.quantity}x</div>`
|
? /*html*/`<div class="qty-static" aria-label="Feste Ticketanzahl">${group.quantity}x</div>`
|
||||||
: `
|
: /*html*/`
|
||||||
<div class="qty-stepper">
|
<div class="qty-stepper">
|
||||||
<button class="btn-qty" data-action="minus" data-key="${escapeHtml(group.key)}">-</button>
|
<button class="btn-qty" data-action="minus" data-key="${escapeHtml(group.key)}">-</button>
|
||||||
<span>${group.quantity}</span>
|
<span>${group.quantity}</span>
|
||||||
@@ -145,7 +147,7 @@ function renderCart() {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return `
|
return /*html*/`
|
||||||
<div class="cart-item-row">
|
<div class="cart-item-row">
|
||||||
<div class="col-amount">
|
<div class="col-amount">
|
||||||
${quantityHtml}
|
${quantityHtml}
|
||||||
@@ -172,22 +174,23 @@ function renderCart() {
|
|||||||
|
|
||||||
saveCart();
|
saveCart();
|
||||||
}
|
}
|
||||||
|
//@ts-ignore
|
||||||
window.removeItem = function removeItem(id) {
|
window.removeItem = function removeItem(id: any) {
|
||||||
cart = cart.filter((item) => item.id !== id);
|
var localCart = cart.filter((item: { id: any; }) => item.id !== id);
|
||||||
saveCart();
|
saveCart();
|
||||||
renderCart();
|
renderCart();
|
||||||
};
|
};
|
||||||
|
|
||||||
window.changeQty = function changeQty(title, delta) {
|
//@ts-ignore
|
||||||
|
window.changeQty = function changeQty(title, delta): void {
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
const item = cart.find((entry) => entry.title === title);
|
const item = cart.find((entry: { title: any; }) => entry.title === title);
|
||||||
if (item) {
|
if (item) {
|
||||||
cart.push({ ...item, id: Date.now() + Math.random() });
|
cart.push({ ...item, id: Date.now() + Math.random() });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const index = cart
|
const index = cart
|
||||||
.map((entry) => entry.title)
|
.map((entry: { title: any; }) => entry.title)
|
||||||
.lastIndexOf(title);
|
.lastIndexOf(title);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
cart.splice(index, 1);
|
cart.splice(index, 1);
|
||||||
@@ -197,3 +200,4 @@ window.changeQty = function changeQty(title, delta) {
|
|||||||
saveCart();
|
saveCart();
|
||||||
renderCart();
|
renderCart();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
function formatCheckoutEuro(value) {
|
import { currentUser, users } from "./account.js";
|
||||||
|
import { renderCart, saveCart } from "./cart.js";
|
||||||
|
import { cart, emptyCart, occupiedSeatsData } from "./main.js";
|
||||||
|
|
||||||
|
function formatCheckoutEuro(value: number) {
|
||||||
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let selectedPaymentMethod = "";
|
let selectedPaymentMethod = "";
|
||||||
let checkoutEventsBound = false;
|
let checkoutEventsBound = false;
|
||||||
|
|
||||||
function setCheckoutStep(step) {
|
function setCheckoutStep(step: number) {
|
||||||
const step1 = document.getElementById("checkout-step-1");
|
const step1 = document.getElementById("checkout-step-1");
|
||||||
const step2 = document.getElementById("checkout-step-2");
|
const step2 = document.getElementById("checkout-step-2");
|
||||||
const step3 = document.getElementById("checkout-step-3");
|
const step3 = document.getElementById("checkout-step-3");
|
||||||
@@ -27,7 +31,7 @@ function setCheckoutStep(step) {
|
|||||||
line2?.classList.toggle("active", step >= 3);
|
line2?.classList.toggle("active", step >= 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCheckout() {
|
export function renderCheckout() {
|
||||||
const summaryList = document.getElementById("checkout-summary-list");
|
const summaryList = document.getElementById("checkout-summary-list");
|
||||||
const totalDisplay = document.getElementById("checkout-total-display");
|
const totalDisplay = document.getElementById("checkout-total-display");
|
||||||
const vatDisplay = document.getElementById("checkout-vat-display");
|
const vatDisplay = document.getElementById("checkout-vat-display");
|
||||||
@@ -93,7 +97,7 @@ function generateTicket() {
|
|||||||
const qrData = encodeURIComponent(`EAGLE-IMAX|${mainMovie.title}|${mainMovie.hall}|${matchingMovieSeats}`);
|
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`;
|
const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${qrData}&bgcolor=ffffff`;
|
||||||
|
|
||||||
ticketContainer.innerHTML = `
|
ticketContainer.innerHTML = /*html*/`
|
||||||
<div class="luxury-ticket">
|
<div class="luxury-ticket">
|
||||||
<div class="ticket-left">
|
<div class="ticket-left">
|
||||||
<img src="${mainMovie.img}" class="ticket-poster" alt="${mainMovie.title}">
|
<img src="${mainMovie.img}" class="ticket-poster" alt="${mainMovie.title}">
|
||||||
@@ -115,7 +119,7 @@ function generateTicket() {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveOrderForCurrentUser(orderItems, orderTotal) {
|
function saveOrderForCurrentUser(orderItems: any[], orderTotal: any) {
|
||||||
if (typeof currentUser === "undefined" || !currentUser) {
|
if (typeof currentUser === "undefined" || !currentUser) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -131,6 +135,7 @@ function saveOrderForCurrentUser(orderItems, orderTotal) {
|
|||||||
paymentMethod: selectedPaymentMethod || "-"
|
paymentMethod: selectedPaymentMethod || "-"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
const userIndex = users.findIndex((entry) => entry.email === currentUser.email);
|
const userIndex = users.findIndex((entry) => entry.email === currentUser.email);
|
||||||
if (userIndex === -1) {
|
if (userIndex === -1) {
|
||||||
return;
|
return;
|
||||||
@@ -144,7 +149,7 @@ function saveOrderForCurrentUser(orderItems, orderTotal) {
|
|||||||
localStorage.setItem("eagleUsers", JSON.stringify(users));
|
localStorage.setItem("eagleUsers", JSON.stringify(users));
|
||||||
}
|
}
|
||||||
|
|
||||||
function reserveSeatsAfterPayment(orderItems) {
|
function reserveSeatsAfterPayment(orderItems: any[]) {
|
||||||
const movieItems = orderItems.filter((item) => item.category === "movie");
|
const movieItems = orderItems.filter((item) => item.category === "movie");
|
||||||
|
|
||||||
movieItems.forEach((item) => {
|
movieItems.forEach((item) => {
|
||||||
@@ -166,7 +171,7 @@ function completeCheckout() {
|
|||||||
saveOrderForCurrentUser(orderItems, orderTotal);
|
saveOrderForCurrentUser(orderItems, orderTotal);
|
||||||
reserveSeatsAfterPayment(orderItems);
|
reserveSeatsAfterPayment(orderItems);
|
||||||
|
|
||||||
cart = [];
|
emptyCart?.()
|
||||||
saveCart?.();
|
saveCart?.();
|
||||||
renderCart?.();
|
renderCart?.();
|
||||||
}
|
}
|
||||||
@@ -180,7 +185,7 @@ function bindCheckoutEvents() {
|
|||||||
|
|
||||||
const nextButton = document.getElementById("btn-next-step-2");
|
const nextButton = document.getElementById("btn-next-step-2");
|
||||||
const backButton = document.getElementById("btn-back-to-step1");
|
const backButton = document.getElementById("btn-back-to-step1");
|
||||||
const payNowButton = document.getElementById("btn-pay-now");
|
const payNowButton = document.getElementById("btn-pay-now") as HTMLButtonElement;
|
||||||
|
|
||||||
document.querySelectorAll(".payment-method").forEach((method) => {
|
document.querySelectorAll(".payment-method").forEach((method) => {
|
||||||
method.addEventListener("click", () => {
|
method.addEventListener("click", () => {
|
||||||
@@ -189,6 +194,7 @@ function bindCheckoutEvents() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
method.classList.add("selected");
|
method.classList.add("selected");
|
||||||
|
//@ts-ignore
|
||||||
selectedPaymentMethod = method.dataset.method || "";
|
selectedPaymentMethod = method.dataset.method || "";
|
||||||
nextButton?.classList.remove("hidden");
|
nextButton?.classList.remove("hidden");
|
||||||
});
|
});
|
||||||
8
src/interfaces.ts
Normal file
8
src/interfaces.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export interface User {
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
email: string;
|
||||||
|
hashedPassword: string;
|
||||||
|
orders: any[]; // TODO: figure out proper array type of orders. Probably smartest do create an Order interface which this would be an array of
|
||||||
|
paymentMethods: any[]; // TODO: figure out proper array type of paymentMethods. create paymentMethod interface and make this an array of it
|
||||||
|
}
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
// Shared app state for legacy script files (account.js, booking.js, cart.js, checkout.js)
|
import { currentUser, loginUser, openAccountDashboard, registerUser } from "./account.js";
|
||||||
var prices = { normal: 11.0, imax: 15.0, vip: 12.0, dbox: 16.0 };
|
import { openBooking } from "./booking.js";
|
||||||
var seatLayouts = {
|
import { renderCart, saveCart, updateCartBadge } from "./cart.js";
|
||||||
|
import { renderCheckout } from "./checkout.js";
|
||||||
|
|
||||||
|
// Shared app state for legacy script files (account.js, booking.js, cart.js, checkout.js)
|
||||||
|
export const prices: Record<string, number> = { normal: 11.0, imax: 15.0, vip: 12.0, dbox: 16.0 };
|
||||||
|
export var seatLayouts = {
|
||||||
"Kino 1": { rows: 6, left: 3, right: 7, vipRows: [5], dbox: [] },
|
"Kino 1": { rows: 6, left: 3, right: 7, vipRows: [5], dbox: [] },
|
||||||
"Kino 2": { rows: 7, left: 5, right: 5, vipRows: [6], dbox: [] },
|
"Kino 2": { rows: 7, left: 5, right: 5, vipRows: [6], dbox: [] },
|
||||||
"Deluxe 1": { rows: 10, left: 7, right: 8, vipRows: [9], dbox: [{ r: 4, c: 5, w: 4 }] },
|
"Deluxe 1": { rows: 10, left: 7, right: 8, vipRows: [9], dbox: [{ r: 4, c: 5, w: 4 }] },
|
||||||
IMAX: { rows: 15, left: 10, right: 10, vipRows: [], dbox: [], isImax: true }
|
IMAX: { rows: 15, left: 10, right: 10, vipRows: [], dbox: [], isImax: true }
|
||||||
};
|
};
|
||||||
var cart = JSON.parse(localStorage.getItem("eagleCart")) || [];
|
export var cart = JSON.parse(localStorage.getItem("eagleCart") || '{}');
|
||||||
var occupiedSeatsData = JSON.parse(localStorage.getItem("eagleOccupied")) || {};
|
export var occupiedSeatsData = JSON.parse(localStorage.getItem("eagleOccupied") || '{}');
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const views = {
|
const views = {
|
||||||
@@ -62,8 +67,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
duration: 148,
|
duration: 148,
|
||||||
fsk: "6",
|
fsk: "6",
|
||||||
description: "In Walt Disney Animation Studios’ \"Zoomania 2\" geraten die tierischen Detektive Judy Hopps und Nick Wilde auf die rätselhafte Spur eines geheimnisvollen Reptils, das in Zoomania auftaucht und die Metropole völlig auf den Kopf stellt: Gary De’Snake! ",
|
description: "In Walt Disney Animation Studios’ \"Zoomania 2\" geraten die tierischen Detektive Judy Hopps und Nick Wilde auf die rätselhafte Spur eines geheimnisvollen Reptils, das in Zoomania auftaucht und die Metropole völlig auf den Kopf stellt: Gary De’Snake! ",
|
||||||
poster: "img/zoomania-2.jpg",
|
poster: "img/Zoomania-2.jpg",
|
||||||
backdrop: "img/zoomania-2.jpg"
|
backdrop: "img/Zoomania-2.jpg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Shelter",
|
title: "Shelter",
|
||||||
@@ -221,11 +226,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
{
|
{
|
||||||
title: "Cash Truck",
|
title: "Cash Truck",
|
||||||
genre: "Action",
|
genre: "Action",
|
||||||
duration: 98,
|
duration: 118,
|
||||||
fsk: "16",
|
fsk: "16",
|
||||||
description: "Der verschlossene Einzelgänger „H” nimmt einen Job bei einer Geldtransporter-Firma an, die jede Woche hunderte von Millionen Dollar durch Los Angeles fährt. Gleich bei seinem ersten Einsatz wird der Geldtransport überfallen und zur Überraschung seiner Kollegen setzt H die Gangster im Alleingang außer Gefecht und wartet mit ungeahnten Präzisionsfähigkeiten auf. Doch H’s Absichten sind nicht zu durchschauen und kommen nur schrittweise ans Licht. Wer ist der geheimnisvolle Neuzugang und auf wen hat er es wirklich abgesehen?",
|
description: ""
|
||||||
poster: "img/cashtruck.jpg",
|
|
||||||
backdrop: "img/cashtruck.jpg"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Die Gangster Gang",
|
title: "Die Gangster Gang",
|
||||||
@@ -328,10 +331,10 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
["13:00", "16:00", "18:20", "20:40"]
|
["13:00", "16:00", "18:20", "20:40"]
|
||||||
];
|
];
|
||||||
|
|
||||||
let movieProgram = [];
|
let movieProgram: any = []; // TODO: Find type
|
||||||
let heroItems = [];
|
let heroItems: any = []; // TODO: find Type
|
||||||
let heroIndex = 0;
|
let heroIndex = 0;
|
||||||
let heroTimer = null;
|
let heroTimer:any = null; // TODO: find type
|
||||||
|
|
||||||
const weekdayShort = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
|
const weekdayShort = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
|
||||||
|
|
||||||
@@ -350,7 +353,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
};
|
};
|
||||||
|
|
||||||
const showMovieList = (programIndexToFocus = null) => {
|
const showMovieList = (programIndexToFocus:number = NaN) => {
|
||||||
hideAllViews();
|
hideAllViews();
|
||||||
views.list?.classList.remove("hidden");
|
views.list?.classList.remove("hidden");
|
||||||
|
|
||||||
@@ -367,7 +370,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showStaticView = (viewElement) => {
|
const showStaticView = (viewElement: HTMLElement) => {
|
||||||
if (!viewElement) {
|
if (!viewElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -396,20 +399,20 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
ui.bookingModal?.classList.add("hidden");
|
ui.bookingModal?.classList.add("hidden");
|
||||||
};
|
};
|
||||||
|
|
||||||
const escapeHtml = (value) => String(value || "")
|
const escapeHtml = (value: string) => String(value || "")
|
||||||
.replaceAll("&", "&")
|
.replaceAll("&", "&")
|
||||||
.replaceAll("<", "<")
|
.replaceAll("<", "<")
|
||||||
.replaceAll(">", ">")
|
.replaceAll(">", ">")
|
||||||
.replaceAll('"', """)
|
.replaceAll('"', """)
|
||||||
.replaceAll("'", "'");
|
.replaceAll("'", "'");
|
||||||
|
|
||||||
const formatDateShort = (dateObj) => {
|
const formatDateShort = (dateObj: any) => {
|
||||||
const day = String(dateObj.getDate()).padStart(2, "0");
|
const day = String(dateObj.getDate()).padStart(2, "0");
|
||||||
const month = String(dateObj.getMonth() + 1).padStart(2, "0");
|
const month = String(dateObj.getMonth() + 1).padStart(2, "0");
|
||||||
return `${day}.${month}.`;
|
return `${day}.${month}.`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildDayMeta = (offset) => {
|
const buildDayMeta = (offset: number) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
date.setHours(0, 0, 0, 0);
|
date.setHours(0, 0, 0, 0);
|
||||||
date.setDate(date.getDate() + offset);
|
date.setDate(date.getDate() + offset);
|
||||||
@@ -443,14 +446,15 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildScheduleForMovie = (movieIndex) => {
|
const buildScheduleForMovie = (movieIndex: number) => {
|
||||||
return Array.from({ length: 7 }, (_, dayOffset) => {
|
return Array.from({ length: 7 }, (_, dayOffset) => {
|
||||||
const dayMeta = buildDayMeta(dayOffset);
|
const dayMeta = buildDayMeta(dayOffset);
|
||||||
const pattern = timePatterns[(movieIndex + dayOffset) % timePatterns.length];
|
const pattern = timePatterns[(movieIndex + dayOffset) % timePatterns.length] || "Error reading";
|
||||||
const desiredCount = 4 + ((movieIndex + dayOffset) % 2);
|
const desiredCount = 4 + ((movieIndex + dayOffset) % 2);
|
||||||
const showCount = Math.min(pattern.length, desiredCount);
|
const showCount = Math.min(pattern.length, desiredCount);
|
||||||
|
|
||||||
const showings = pattern.slice(0, showCount).map((time, slotIndex) => {
|
//@ts-ignore
|
||||||
|
const showings = pattern.slice(0, showCount).map((time: any, slotIndex: number) => { // TODO: fix map issue
|
||||||
const hall = hallRotation[(movieIndex + dayOffset + slotIndex) % hallRotation.length];
|
const hall = hallRotation[(movieIndex + dayOffset + slotIndex) % hallRotation.length];
|
||||||
return { time, hall };
|
return { time, hall };
|
||||||
});
|
});
|
||||||
@@ -470,7 +474,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
heroItems = movieProgram.slice(0, 5);
|
heroItems = movieProgram.slice(0, 5);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setHeroSlide = (index) => {
|
const setHeroSlide = (index: number) => {
|
||||||
if (!heroItems.length || !ui.heroSlider) {
|
if (!heroItems.length || !ui.heroSlider) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -499,17 +503,18 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.heroSlider.innerHTML = heroItems.map((movie, index) => `
|
ui.heroSlider.innerHTML = heroItems.map((movie: any, index: number) => `
|
||||||
<div class="hero-slide ${index === 0 ? "active" : ""}" style="background-image: linear-gradient(118deg, rgba(0,0,0,0.34), rgba(0,0,0,0.04)), url('${escapeHtml(movie.backdrop || movie.poster)}');"></div>
|
<div class="hero-slide ${index === 0 ? "active" : ""}" style="background-image: linear-gradient(118deg, rgba(0,0,0,0.34), rgba(0,0,0,0.04)), url('${escapeHtml(movie.backdrop || movie.poster)}');"></div>
|
||||||
`).join("");
|
`).join("");
|
||||||
|
|
||||||
if (ui.heroDots) {
|
if (ui.heroDots) {
|
||||||
ui.heroDots.innerHTML = heroItems.map((_, index) => `
|
ui.heroDots.innerHTML = heroItems.map((_:any, index: number) => `
|
||||||
<button type="button" class="hero-dot ${index === 0 ? "active" : ""}" data-hero-index="${index}"></button>
|
<button type="button" class="hero-dot ${index === 0 ? "active" : ""}" data-hero-index="${index}"></button>
|
||||||
`).join("");
|
`).join("");
|
||||||
|
|
||||||
ui.heroDots.addEventListener("click", (event) => {
|
ui.heroDots.addEventListener("click", (event: any) => {
|
||||||
const dot = event.target.closest(".hero-dot");
|
const dotTarget = event.target || 0;
|
||||||
|
const dot = dotTarget.closest(".hero-dot");
|
||||||
if (!dot) {
|
if (!dot) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -540,7 +545,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.nowRunningRow.innerHTML = movieProgram.map((movie, index) => `
|
// TODO: implement movie interface
|
||||||
|
ui.nowRunningRow.innerHTML = movieProgram.map((movie: any, index: number) => /*html*/`
|
||||||
<article class="running-poster">
|
<article class="running-poster">
|
||||||
<img src="${escapeHtml(movie.poster)}" alt="${escapeHtml(movie.title)}">
|
<img src="${escapeHtml(movie.poster)}" alt="${escapeHtml(movie.title)}">
|
||||||
<div class="running-meta">
|
<div class="running-meta">
|
||||||
@@ -552,7 +558,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
`).join("");
|
`).join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderScheduleRows = (programIndex, dayIndex) => {
|
const renderScheduleRows = (programIndex: number, dayIndex: number) => {
|
||||||
const movie = movieProgram[programIndex];
|
const movie = movieProgram[programIndex];
|
||||||
if (!movie) {
|
if (!movie) {
|
||||||
return;
|
return;
|
||||||
@@ -564,7 +570,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.innerHTML = day.showings.map((showing) => `
|
body.innerHTML = day.showings.map((showing: { hall: string; time: string; }) => /*html*/`
|
||||||
<button class="schedule-row time-chip program-time-row" data-movie="${escapeHtml(movie.title)}" data-hall="${escapeHtml(showing.hall)}" data-time="${escapeHtml(showing.time)}">
|
<button class="schedule-row time-chip program-time-row" data-movie="${escapeHtml(movie.title)}" data-hall="${escapeHtml(showing.hall)}" data-time="${escapeHtml(showing.time)}">
|
||||||
<span>${escapeHtml(day.long)}</span>
|
<span>${escapeHtml(day.long)}</span>
|
||||||
<span class="hall-pill">${escapeHtml(showing.hall)}</span>
|
<span class="hall-pill">${escapeHtml(showing.hall)}</span>
|
||||||
@@ -578,15 +584,15 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.movieProgramList.innerHTML = movieProgram.map((movie, programIndex) => {
|
ui.movieProgramList.innerHTML = movieProgram.map((movie: { schedule: any[]; poster: string; title: string; fsk: string; duration: any; genre: string; description: string; }, programIndex: any) => {
|
||||||
const dayTabs = movie.schedule.map((day, dayIndex) => `
|
const dayTabs = movie.schedule.map((day, dayIndex) => /*html*/`
|
||||||
<button type="button" class="program-day-tab ${dayIndex === 0 ? "active" : ""}" data-program-index="${programIndex}" data-day-index="${dayIndex}">
|
<button type="button" class="program-day-tab ${dayIndex === 0 ? "active" : ""}" data-program-index="${programIndex}" data-day-index="${dayIndex}">
|
||||||
<span>${escapeHtml(day.short)}</span>
|
<span>${escapeHtml(day.short)}</span>
|
||||||
<small>${escapeHtml(formatDateShort(day.date))}</small>
|
<small>${escapeHtml(formatDateShort(day.date))}</small>
|
||||||
</button>
|
</button>
|
||||||
`).join("");
|
`).join("");
|
||||||
|
|
||||||
return `
|
return /*html*/`
|
||||||
<article class="detailed-card program-card reveal-on-scroll" data-program-index="${programIndex}">
|
<article class="detailed-card program-card reveal-on-scroll" data-program-index="${programIndex}">
|
||||||
<div class="card-left">
|
<div class="card-left">
|
||||||
<img src="${escapeHtml(movie.poster)}" alt="${escapeHtml(movie.title)}">
|
<img src="${escapeHtml(movie.poster)}" alt="${escapeHtml(movie.title)}">
|
||||||
@@ -612,7 +618,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
`;
|
`;
|
||||||
}).join("");
|
}).join("");
|
||||||
|
|
||||||
movieProgram.forEach((_, programIndex) => {
|
movieProgram.forEach((_: any, programIndex: number) => {
|
||||||
renderScheduleRows(programIndex, 0);
|
renderScheduleRows(programIndex, 0);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -660,12 +666,16 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
ui.linkSnacks?.addEventListener("click", (event) => {
|
ui.linkSnacks?.addEventListener("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
if (views.snacks) {
|
||||||
showStaticView(views.snacks);
|
showStaticView(views.snacks);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.linkAbout?.addEventListener("click", (event) => {
|
ui.linkAbout?.addEventListener("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
if (views.about) {
|
||||||
showStaticView(views.about);
|
showStaticView(views.about);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.linkCart?.addEventListener("click", (event) => {
|
ui.linkCart?.addEventListener("click", (event) => {
|
||||||
@@ -695,17 +705,17 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const bindProgramActions = () => {
|
const bindProgramActions = () => {
|
||||||
views.moviesGrid?.addEventListener("click", (event) => {
|
views.moviesGrid?.addEventListener("click", (event:any) => {
|
||||||
const trigger = event.target.closest(".open-program-btn");
|
const trigger = event.target.closest(".open-program-btn");
|
||||||
if (!trigger) {
|
if (!trigger) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const programIndex = Number(trigger.dataset.programIndex || 0);
|
const programIndex = Number(trigger.dataset.programIndex) || 0;
|
||||||
showMovieList(programIndex);
|
showMovieList(programIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.movieProgramList?.addEventListener("click", (event) => {
|
ui.movieProgramList?.addEventListener("click", (event:any) => {
|
||||||
const dayButton = event.target.closest(".program-day-tab");
|
const dayButton = event.target.closest(".program-day-tab");
|
||||||
if (!dayButton) {
|
if (!dayButton) {
|
||||||
return;
|
return;
|
||||||
@@ -715,7 +725,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
const dayIndex = Number(dayButton.dataset.dayIndex || 0);
|
const dayIndex = Number(dayButton.dataset.dayIndex || 0);
|
||||||
|
|
||||||
const tabRow = dayButton.closest(".program-day-tabs");
|
const tabRow = dayButton.closest(".program-day-tabs");
|
||||||
tabRow?.querySelectorAll(".program-day-tab").forEach((tab) => tab.classList.remove("active"));
|
tabRow?.querySelectorAll(".program-day-tab").forEach((tab: { classList: { remove: (arg0: string) => any; }; }) => tab.classList.remove("active"));
|
||||||
dayButton.classList.add("active");
|
dayButton.classList.add("active");
|
||||||
|
|
||||||
renderScheduleRows(programIndex, dayIndex);
|
renderScheduleRows(programIndex, dayIndex);
|
||||||
@@ -741,7 +751,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
openButtons.forEach((button) => {
|
openButtons.forEach((button) => {
|
||||||
button.addEventListener("click", () => {
|
button.addEventListener("click", () => {
|
||||||
const targetId = button.getAttribute("data-home-view-open");
|
const targetId = button.getAttribute("data-home-view-open") as keyof typeof targetMap;
|
||||||
const target = targetId ? targetMap[targetId] : null;
|
const target = targetId ? targetMap[targetId] : null;
|
||||||
if (target) {
|
if (target) {
|
||||||
showStaticView(target);
|
showStaticView(target);
|
||||||
@@ -794,10 +804,11 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
const THEME_KEY = "eagleTheme";
|
const THEME_KEY = "eagleTheme";
|
||||||
|
|
||||||
const applyTheme = (theme) => {
|
const applyTheme = (theme: any) => {
|
||||||
const isLight = theme === "light";
|
const isLight = theme === "light";
|
||||||
document.body.classList.toggle("theme-light", isLight);
|
document.body.classList.toggle("theme-light", isLight);
|
||||||
document.body.classList.toggle("theme-dark", !isLight);
|
document.body.classList.toggle("theme-dark", !isLight);
|
||||||
|
//@ts-ignore
|
||||||
ui.themeToggle.classList.toggle("is-light", isLight);
|
ui.themeToggle.classList.toggle("is-light", isLight);
|
||||||
localStorage.setItem(THEME_KEY, isLight ? "light" : "dark");
|
localStorage.setItem(THEME_KEY, isLight ? "light" : "dark");
|
||||||
};
|
};
|
||||||
@@ -814,14 +825,14 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
const bindAccountActions = () => {
|
const bindAccountActions = () => {
|
||||||
const registerModal = document.getElementById("register-modal");
|
const registerModal = document.getElementById("register-modal");
|
||||||
const forgotModal = document.getElementById("forgot-modal");
|
const forgotModal = document.getElementById("forgot-modal");
|
||||||
const forgotEmailInput = document.getElementById("forgot-email");
|
const forgotEmailInput = document.getElementById("forgot-email") as HTMLInputElement;
|
||||||
const resetMessage = document.getElementById("reset-message");
|
const resetMessage = document.getElementById("reset-message");
|
||||||
const loginError = document.getElementById("login-error");
|
const loginError = document.getElementById("login-error");
|
||||||
const loginEmailInput = document.getElementById("login-email");
|
const loginEmailInput = document.getElementById("login-email");
|
||||||
const loginPasswordInput = document.getElementById("login-password");
|
const loginPasswordInput = document.getElementById("login-password");
|
||||||
|
|
||||||
const openModal = (modal) => modal?.classList.remove("hidden");
|
const openModal = (modal: HTMLElement | null) => modal?.classList.remove("hidden");
|
||||||
const closeModal = (modal) => modal?.classList.add("hidden");
|
const closeModal = (modal: HTMLElement | null) => modal?.classList.add("hidden");
|
||||||
const triggerLogin = () => {
|
const triggerLogin = () => {
|
||||||
loginError?.classList.add("hidden");
|
loginError?.classList.add("hidden");
|
||||||
if (typeof loginUser === "function") {
|
if (typeof loginUser === "function") {
|
||||||
@@ -857,7 +868,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("btn-forgot-password")?.addEventListener("click", () => {
|
document.getElementById("btn-forgot-password")?.addEventListener("click", () => {
|
||||||
if (forgotEmailInput) {
|
if (forgotEmailInput != null) {
|
||||||
forgotEmailInput.value = "";
|
forgotEmailInput.value = "";
|
||||||
}
|
}
|
||||||
resetMessage?.classList.add("hidden");
|
resetMessage?.classList.add("hidden");
|
||||||
@@ -902,10 +913,10 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const bindGlobalDocumentClicks = () => {
|
const bindGlobalDocumentClicks = () => {
|
||||||
document.addEventListener("click", (event) => {
|
document.addEventListener("click", (event: any) => {
|
||||||
if (event.target.classList.contains("opt-btn")) {
|
if (event.target.classList.contains("opt-btn")) {
|
||||||
const optionGroup = event.target.parentElement;
|
const optionGroup = event.target.parentElement;
|
||||||
optionGroup?.querySelectorAll(".opt-btn").forEach((button) => button.classList.remove("active"));
|
optionGroup?.querySelectorAll(".opt-btn").forEach((button: { classList: { remove: (arg0: string) => any; }; }) => button.classList.remove("active"));
|
||||||
event.target.classList.add("active");
|
event.target.classList.add("active");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -914,15 +925,17 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
const row = deleteBtn.closest(".cart-item-row");
|
const row = deleteBtn.closest(".cart-item-row");
|
||||||
if (row) {
|
if (row) {
|
||||||
row.classList.add("slide-out-left");
|
row.classList.add("slide-out-left");
|
||||||
row.querySelectorAll("button").forEach((button) => {
|
row.querySelectorAll("button").forEach((button: { disabled: boolean; }) => {
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
removeFromCartByKey(deleteBtn.dataset.key);
|
//@ts-ignore
|
||||||
|
removeFromCartByKey(deleteBtn.dataset.key); //TODO: removeFromCartByKey doesnt exist
|
||||||
}, 380);
|
}, 380);
|
||||||
} else {
|
} else {
|
||||||
removeFromCartByKey(deleteBtn.dataset.key);
|
//@ts-ignore
|
||||||
|
removeFromCartByKey(deleteBtn.dataset.key); //TODO: removeFromCartByKey doesnt exist
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -951,7 +964,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const relatedItem = cart.find((item) => {
|
const relatedItem = cart.find((item: { category: string; seatId: any; hall: any; time: any; title: any; }) => {
|
||||||
const infoText = item.category === "movie"
|
const infoText = item.category === "movie"
|
||||||
? `Sitz: ${item.seatId} (${item.hall})`
|
? `Sitz: ${item.seatId} (${item.hall})`
|
||||||
: item.time;
|
: item.time;
|
||||||
@@ -965,7 +978,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
if (action === "plus") {
|
if (action === "plus") {
|
||||||
cart.push({ ...relatedItem, id: Date.now() + Math.random() });
|
cart.push({ ...relatedItem, id: Date.now() + Math.random() });
|
||||||
} else {
|
} else {
|
||||||
const keyList = cart.map((item) => {
|
const keyList = cart.map((item: { category: string; seatId: any; hall: any; time: any; title: any; }) => {
|
||||||
const infoText = item.category === "movie"
|
const infoText = item.category === "movie"
|
||||||
? `Sitz: ${item.seatId} (${item.hall})`
|
? `Sitz: ${item.seatId} (${item.hall})`
|
||||||
: item.time;
|
: item.time;
|
||||||
@@ -984,7 +997,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const bindSnacksActions = () => {
|
const bindSnacksActions = () => {
|
||||||
ui.snacksView?.addEventListener("click", (event) => {
|
ui.snacksView?.addEventListener("click", (event:any) => {
|
||||||
const sizeChip = event.target.closest(".size-chip");
|
const sizeChip = event.target.closest(".size-chip");
|
||||||
if (!sizeChip) {
|
if (!sizeChip) {
|
||||||
return;
|
return;
|
||||||
@@ -1028,7 +1041,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
}, 800);
|
}, 800);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll(".tab-btn").forEach((button) => {
|
document.querySelectorAll(".tab-btn").forEach((button: any) => {
|
||||||
button.addEventListener("click", () => {
|
button.addEventListener("click", () => {
|
||||||
document.querySelectorAll(".tab-btn").forEach((tab) => tab.classList.remove("active"));
|
document.querySelectorAll(".tab-btn").forEach((tab) => tab.classList.remove("active"));
|
||||||
button.classList.add("active");
|
button.classList.add("active");
|
||||||
@@ -1065,9 +1078,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// @ts-ignore
|
||||||
window.removeFromCartByKey = function removeFromCartByKey(key) {
|
window.removeFromCartByKey = function removeFromCartByKey(key: string) {
|
||||||
cart = cart.filter((item) => {
|
cart = cart.filter((item: { category: string; seatId: any; hall: any; time: any; title: any; }) => {
|
||||||
const infoText = item.category === "movie"
|
const infoText = item.category === "movie"
|
||||||
? `Sitz: ${item.seatId} (${item.hall})`
|
? `Sitz: ${item.seatId} (${item.hall})`
|
||||||
: item.time;
|
: item.time;
|
||||||
@@ -1092,3 +1105,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
updateCartBadge?.();
|
updateCartBadge?.();
|
||||||
renderCheckout?.();
|
renderCheckout?.();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function emptyCart() {
|
||||||
|
cart = []
|
||||||
|
return
|
||||||
|
}
|
||||||
379
style.css
379
style.css
@@ -2902,15 +2902,15 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.inline-halls .inline-media {
|
.inline-halls .inline-media {
|
||||||
background-image: linear-gradient(120deg, rgba(0, 113, 227, 0.3), rgba(7, 10, 16, 0.55)), url('img/placeholder-hall.jpg');
|
background-image: linear-gradient(120deg, rgba(0, 113, 227, 0.3), rgba(7, 10, 16, 0.55)), url('img/shelter.jpg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.inline-dbox .inline-media {
|
.inline-dbox .inline-media {
|
||||||
background-image: linear-gradient(120deg, rgba(255, 176, 0, 0.2), rgba(8, 12, 18, 0.62)), url('img/placeholder-dbox.jpg');
|
background-image: linear-gradient(120deg, rgba(255, 176, 0, 0.2), rgba(8, 12, 18, 0.62)), url('img/dbox.jpg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.inline-collectors .inline-media {
|
.inline-collectors .inline-media {
|
||||||
background-image: linear-gradient(120deg, rgba(185, 124, 255, 0.15), rgba(8, 12, 18, 0.62)), url('img/placeholder-collector.jpg');
|
background-image: linear-gradient(120deg, rgba(185, 124, 255, 0.15), rgba(8, 12, 18, 0.62)), url('img/popcorn.jpg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.inline-content {
|
.inline-content {
|
||||||
@@ -3865,376 +3865,3 @@ body.theme-light .about-card {
|
|||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- 2026-04-29 account/about/snack readability polish --- */
|
|
||||||
.snack-subsection {
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.snack-subsection:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.snack-section-heading {
|
|
||||||
margin: 0 0 16px;
|
|
||||||
padding: 16px 18px;
|
|
||||||
border-left: 4px solid var(--accent-blue);
|
|
||||||
border-radius: 18px;
|
|
||||||
background:
|
|
||||||
linear-gradient(135deg, rgba(0, 113, 227, 0.18), rgba(255, 255, 255, 0.035)),
|
|
||||||
rgba(255, 255, 255, 0.035);
|
|
||||||
}
|
|
||||||
|
|
||||||
.snack-section-heading span {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 3px;
|
|
||||||
color: #9ed0ff;
|
|
||||||
font-size: 0.72rem;
|
|
||||||
font-weight: 800;
|
|
||||||
letter-spacing: 1.7px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.snack-section-heading h2 {
|
|
||||||
margin: 0;
|
|
||||||
color: #f5f8ff;
|
|
||||||
font-size: clamp(1.35rem, 2vw, 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.snack-card-note {
|
|
||||||
margin: 4px 0 12px;
|
|
||||||
color: #aeb8c6;
|
|
||||||
font-size: 0.82rem;
|
|
||||||
line-height: 1.45;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-dark .account-orders-shell h3,
|
|
||||||
body.theme-dark .order-item-head h4,
|
|
||||||
body.theme-dark .order-box p,
|
|
||||||
body.theme-dark .order-box strong,
|
|
||||||
body.theme-dark .order-ticket-content h4,
|
|
||||||
body.theme-dark .order-ticket-grid strong {
|
|
||||||
color: #f4f8ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-dark .order-box {
|
|
||||||
background: linear-gradient(145deg, #18202d 0%, #10151f 100%);
|
|
||||||
border-color: rgba(130, 180, 235, 0.2);
|
|
||||||
box-shadow: 0 14px 34px rgba(0, 0, 0, 0.22);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-dark .order-box p {
|
|
||||||
color: #d2dbe8;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-dark .order-item-btn:hover,
|
|
||||||
body.theme-dark .order-item-btn.active {
|
|
||||||
background: linear-gradient(145deg, #1d3148 0%, #111a27 100%);
|
|
||||||
border-color: rgba(110, 185, 255, 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-dark .order-item-head span {
|
|
||||||
color: #a9d7ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-dark .order-ticket-card {
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 18% 0%, rgba(0, 113, 227, 0.2), transparent 30%),
|
|
||||||
linear-gradient(155deg, #172235 0%, #0b111b 100%);
|
|
||||||
border-color: rgba(146, 194, 255, 0.22);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-dark .order-ticket-grid span,
|
|
||||||
body.theme-dark .order-ticket-brand {
|
|
||||||
color: #b9c9dd;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-hero-block {
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 8% 0%, rgba(0, 113, 227, 0.12), transparent 36%),
|
|
||||||
linear-gradient(130deg, #ffffff 0%, #edf5ff 100%);
|
|
||||||
box-shadow: 0 22px 55px rgba(35, 67, 108, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-hero-content h1,
|
|
||||||
body.theme-light .about-stats-grid h3,
|
|
||||||
body.theme-light .about-card h3 {
|
|
||||||
color: #0e1b31 !important;
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-hero-content p,
|
|
||||||
body.theme-light .about-stats-grid p {
|
|
||||||
color: #314763 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-pill-row span {
|
|
||||||
background: rgba(0, 113, 227, 0.11);
|
|
||||||
border-color: rgba(0, 113, 227, 0.28);
|
|
||||||
color: #064b90;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-stats-grid article {
|
|
||||||
background: rgba(255, 255, 255, 0.92);
|
|
||||||
border-color: rgba(24, 52, 88, 0.18);
|
|
||||||
box-shadow: 0 12px 28px rgba(42, 70, 106, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card {
|
|
||||||
border-color: rgba(22, 47, 80, 0.22);
|
|
||||||
box-shadow: 0 18px 42px rgba(31, 61, 98, 0.13);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card-halls {
|
|
||||||
background-image: url('img/zoomania-2.jpg') !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card-dbox {
|
|
||||||
background-image: url('img/shelter.jpg') !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card-tech {
|
|
||||||
background-image: url('img/spidermannewday.jpg') !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card::before {
|
|
||||||
background:
|
|
||||||
linear-gradient(175deg, rgba(255, 255, 255, 0.42) 0%, rgba(255, 255, 255, 0.93) 74%),
|
|
||||||
linear-gradient(90deg, rgba(0, 113, 227, 0.1), transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card p {
|
|
||||||
color: #263f5f !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card .story-more-btn {
|
|
||||||
background: rgba(255, 255, 255, 0.84);
|
|
||||||
border-color: rgba(0, 83, 170, 0.24);
|
|
||||||
color: #0d3563;
|
|
||||||
box-shadow: 0 10px 24px rgba(26, 57, 95, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .about-card .story-more-btn:hover {
|
|
||||||
background: #0071e3;
|
|
||||||
border-color: #0071e3;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .snack-section-heading {
|
|
||||||
background:
|
|
||||||
linear-gradient(135deg, rgba(0, 113, 227, 0.12), rgba(255, 255, 255, 0.94)),
|
|
||||||
#ffffff;
|
|
||||||
border-color: #0071e3;
|
|
||||||
box-shadow: 0 12px 26px rgba(34, 74, 121, 0.09);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .snack-section-heading span {
|
|
||||||
color: #0057ae;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .snack-section-heading h2 {
|
|
||||||
color: #10213a;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .snack-card-note {
|
|
||||||
color: #4a5d79;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- 2026-04-29 limited snack specials --- */
|
|
||||||
.limited-specials-category {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-specials-hero {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 28px;
|
|
||||||
padding: clamp(24px, 4vw, 42px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.13);
|
|
||||||
border-radius: 28px;
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 14% 16%, rgba(0, 113, 227, 0.42), transparent 34%),
|
|
||||||
radial-gradient(circle at 82% 10%, rgba(255, 178, 84, 0.2), transparent 30%),
|
|
||||||
linear-gradient(135deg, rgba(12, 18, 31, 0.96), rgba(5, 8, 14, 0.96));
|
|
||||||
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-specials-hero::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: auto -10% -45% 42%;
|
|
||||||
height: 180px;
|
|
||||||
border-radius: 999px;
|
|
||||||
background: rgba(255, 255, 255, 0.08);
|
|
||||||
transform: rotate(-8deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-kicker {
|
|
||||||
display: inline-flex;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 7px 12px;
|
|
||||||
border: 1px solid rgba(158, 208, 255, 0.38);
|
|
||||||
border-radius: 999px;
|
|
||||||
color: #9ed0ff;
|
|
||||||
font-size: 0.76rem;
|
|
||||||
font-weight: 800;
|
|
||||||
letter-spacing: 1.5px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-specials-hero h2 {
|
|
||||||
margin: 0 0 8px;
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: clamp(2rem, 5vw, 4.6rem);
|
|
||||||
letter-spacing: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-specials-hero p {
|
|
||||||
max-width: 620px;
|
|
||||||
color: #d4dfec;
|
|
||||||
line-height: 1.65;
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-special-block {
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.special-film-heading {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 16px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
||||||
border-radius: 22px;
|
|
||||||
background:
|
|
||||||
linear-gradient(115deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.025)),
|
|
||||||
rgba(255, 255, 255, 0.035);
|
|
||||||
}
|
|
||||||
|
|
||||||
.special-film-heading img {
|
|
||||||
width: 76px;
|
|
||||||
height: 76px;
|
|
||||||
border-radius: 18px;
|
|
||||||
object-fit: cover;
|
|
||||||
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
|
|
||||||
}
|
|
||||||
|
|
||||||
.special-film-heading span {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 3px;
|
|
||||||
color: #9ed0ff;
|
|
||||||
font-size: 0.74rem;
|
|
||||||
font-weight: 800;
|
|
||||||
letter-spacing: 1.5px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.special-film-heading h2 {
|
|
||||||
margin: 0;
|
|
||||||
color: #f8fbff;
|
|
||||||
font-size: clamp(1.35rem, 2vw, 2.2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-special-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
|
|
||||||
gap: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-special-grid.compact-specials {
|
|
||||||
grid-template-columns: minmax(230px, 420px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-special-card {
|
|
||||||
border-color: rgba(0, 113, 227, 0.3);
|
|
||||||
background:
|
|
||||||
linear-gradient(160deg, rgba(0, 113, 227, 0.15), transparent 42%),
|
|
||||||
var(--card-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-special-card .snack-img {
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.11), transparent 34%),
|
|
||||||
#090d14;
|
|
||||||
}
|
|
||||||
|
|
||||||
.limited-special-card .badge {
|
|
||||||
display: inline-flex;
|
|
||||||
width: max-content;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wide-special {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: minmax(130px, 42%) 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wide-special .snack-img {
|
|
||||||
height: 100%;
|
|
||||||
min-height: 220px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wide-special .snack-info {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .limited-specials-hero {
|
|
||||||
border-color: rgba(31, 67, 110, 0.14);
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 12% 16%, rgba(0, 113, 227, 0.18), transparent 34%),
|
|
||||||
radial-gradient(circle at 84% 12%, rgba(255, 188, 104, 0.26), transparent 32%),
|
|
||||||
linear-gradient(135deg, #ffffff, #edf5ff);
|
|
||||||
box-shadow: 0 24px 60px rgba(35, 67, 108, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .limited-specials-hero h2 {
|
|
||||||
color: #0e1b31;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .limited-specials-hero p {
|
|
||||||
color: #314763;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .limited-kicker {
|
|
||||||
background: rgba(0, 113, 227, 0.1);
|
|
||||||
border-color: rgba(0, 113, 227, 0.28);
|
|
||||||
color: #0759aa;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .special-film-heading {
|
|
||||||
background: rgba(255, 255, 255, 0.86);
|
|
||||||
border-color: rgba(28, 56, 94, 0.14);
|
|
||||||
box-shadow: 0 14px 32px rgba(33, 67, 107, 0.09);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .special-film-heading span {
|
|
||||||
color: #0057ae;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .special-film-heading h2 {
|
|
||||||
color: #10213a;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.theme-light .limited-special-card {
|
|
||||||
background:
|
|
||||||
linear-gradient(160deg, rgba(0, 113, 227, 0.08), transparent 42%),
|
|
||||||
#ffffff !important;
|
|
||||||
border-color: rgba(0, 113, 227, 0.16) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 760px) {
|
|
||||||
.wide-special {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wide-special .snack-img {
|
|
||||||
min-height: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.special-film-heading {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
45
tsconfig.json
Normal file
45
tsconfig.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// Visit https://aka.ms/tsconfig to read more about this file
|
||||||
|
"compilerOptions": {
|
||||||
|
// File Layout
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./dist",
|
||||||
|
|
||||||
|
// Environment Settings
|
||||||
|
// See also https://aka.ms/tsconfig/module
|
||||||
|
"module": "ES2020",
|
||||||
|
"target": "ES2021",
|
||||||
|
"types": [],
|
||||||
|
// For nodejs:
|
||||||
|
// "lib": ["esnext"],
|
||||||
|
// "types": ["node"],
|
||||||
|
// and npm install -D @types/node
|
||||||
|
|
||||||
|
// Other Outputs
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
|
||||||
|
// Stricter Typechecking Options
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"exactOptionalPropertyTypes": true,
|
||||||
|
|
||||||
|
// Style Options
|
||||||
|
// "noImplicitReturns": true,
|
||||||
|
// "noImplicitOverride": true,
|
||||||
|
// "noUnusedLocals": true,
|
||||||
|
// "noUnusedParameters": true,
|
||||||
|
// "noFallthroughCasesInSwitch": true,
|
||||||
|
// "noPropertyAccessFromIndexSignature": true,
|
||||||
|
|
||||||
|
// Recommended Options
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noUncheckedSideEffectImports": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
},
|
||||||
|
"include": ["src/*"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user