forked from Aaron/Kino-Website
refactor: redistribute main.ts logic into Astro components
This commit is contained in:
@@ -1,16 +1,127 @@
|
||||
---
|
||||
import { getTopMovies } from "../scripts/fetchMovies"
|
||||
import Movie from "./Movie.astro"
|
||||
console.log(await getTopMovies())
|
||||
import { movieCatalog, timePatterns, hallRotation, weekdayShort } from "../scripts/bigConstants";
|
||||
|
||||
const formatDateShort = (dateObj: Date) => {
|
||||
const day = String(dateObj.getDate()).padStart(2, "0");
|
||||
const month = String(dateObj.getMonth() + 1).padStart(2, "0");
|
||||
return `${day}.${month}.`;
|
||||
};
|
||||
|
||||
const buildDayMeta = (offset: number) => {
|
||||
const date = new Date();
|
||||
date.setHours(0, 0, 0, 0);
|
||||
date.setDate(date.getDate() + offset);
|
||||
|
||||
const weekday = weekdayShort[date.getDay()];
|
||||
const formattedDate = formatDateShort(date);
|
||||
|
||||
if (offset === 0) return { offset, date, short: "Heute", long: `Heute, ${formattedDate}` };
|
||||
if (offset === 1) return { offset, date, short: "Morgen", long: `Morgen, ${formattedDate}` };
|
||||
return { offset, date, short: weekday, long: `${weekday}, ${formattedDate}` };
|
||||
};
|
||||
|
||||
const buildScheduleForMovie = (movieIndex: number) => {
|
||||
return Array.from({ length: 7 }, (_, dayOffset) => {
|
||||
const dayMeta = buildDayMeta(dayOffset);
|
||||
const pattern = timePatterns[(movieIndex + dayOffset) % timePatterns.length];
|
||||
const desiredCount = 4 + ((movieIndex + dayOffset) % 2);
|
||||
const showCount = Math.min(pattern.length, desiredCount);
|
||||
|
||||
const showings = pattern.slice(0, showCount).map((time: string, slotIndex: number) => {
|
||||
const hall = hallRotation[(movieIndex + dayOffset + slotIndex) % hallRotation.length];
|
||||
return { time, hall };
|
||||
});
|
||||
|
||||
return { ...dayMeta, showings };
|
||||
});
|
||||
};
|
||||
|
||||
const movieProgram = movieCatalog.map((movie, movieIndex) => ({
|
||||
...movie,
|
||||
schedule: buildScheduleForMovie(movieIndex)
|
||||
}));
|
||||
---
|
||||
|
||||
<section id="movie-list-view" class="hidden">
|
||||
<section id="movie-list-view">
|
||||
<div class="container movie-list-shell">
|
||||
<h1 class="list-title">Aktuelle Filme & Spielzeiten</h1>
|
||||
<p class="list-subtitle">Alle Filme mit 7 Tagen Spielplan. Erste Vorstellung täglich ab 13:00 Uhr.</p>
|
||||
|
||||
<!-- Movie List. -->
|
||||
<!-- <div id="movie-program-list" class="movie-program-list"></div> -->
|
||||
<Movie />
|
||||
<div id="movie-program-list" class="movie-program-list">
|
||||
{movieProgram.map((movie, programIndex) => (
|
||||
<article class="detailed-card program-card reveal-on-scroll" data-program-index={programIndex}>
|
||||
<div class="card-left">
|
||||
<img src={movie.poster} alt={movie.title} />
|
||||
<span class={`fsk fsk-${movie.fsk}`}>{movie.fsk}</span>
|
||||
</div>
|
||||
<div class="card-right">
|
||||
<div class="card-header">
|
||||
<h2>{movie.title}</h2>
|
||||
<span class="duration">{movie.duration} Min. | {movie.genre} | FSK: {movie.fsk}</span>
|
||||
</div>
|
||||
<p class="description">{movie.description}</p>
|
||||
|
||||
<div class="program-day-tabs">
|
||||
{movie.schedule.map((day, dayIndex) => (
|
||||
<button type="button" class={`program-day-tab ${dayIndex === 0 ? "active" : ""}`} data-program-index={programIndex} data-day-index={dayIndex}>
|
||||
<span>{day.short}</span>
|
||||
<small>{formatDateShort(day.date)}</small>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div class="schedule-container program-schedule-shell">
|
||||
<div class="schedule-header">
|
||||
<span>Tag</span><span>Kinosaal</span><span>Uhrzeit</span>
|
||||
</div>
|
||||
<div id={`schedule-body-${programIndex}`} class="program-schedule-body">
|
||||
{movie.schedule[0].showings.map((showing) => (
|
||||
<button class="schedule-row time-chip program-time-row" data-movie={movie.title} data-hall={showing.hall} data-time={showing.time}>
|
||||
<span>{movie.schedule[0].long}</span>
|
||||
<span class="hall-pill">{showing.hall}</span>
|
||||
<span class="time-btn">{showing.time}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
const movieProgramList = document.getElementById("movie-program-list");
|
||||
|
||||
movieProgramList?.addEventListener("click", (event: any) => {
|
||||
const dayButton = event.target.closest(".program-day-tab");
|
||||
if (dayButton) {
|
||||
const tabs = dayButton.closest(".program-day-tabs");
|
||||
tabs?.querySelectorAll(".program-day-tab").forEach((t: any) => t.classList.remove("active"));
|
||||
dayButton.classList.add("active");
|
||||
}
|
||||
|
||||
const chip = event.target.closest(".time-chip");
|
||||
if (chip) {
|
||||
const movie = chip.getAttribute("data-movie");
|
||||
const hall = chip.getAttribute("data-hall");
|
||||
const time = chip.getAttribute("data-time");
|
||||
if (movie && hall && time && (window as any).openBooking) {
|
||||
(window as any).openBooking(movie, hall, time);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle deep links
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const focusIndex = params.get("focus");
|
||||
if (focusIndex !== null) {
|
||||
const target = document.querySelector(`[data-program-index="${focusIndex}"]`);
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
target.classList.add("flash-focus");
|
||||
setTimeout(() => target.classList.remove("flash-focus"), 1200);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user