import { Component, inject, OnInit } from '@angular/core'; import { HttpService } from '../http.service'; import { Vorstellung } from '@infinimotion/model-frontend'; import { Performance } from '../model/performance.model'; import { MovieGroup } from '../model/movie-group.model'; import { LoadingService } from '../loading.service'; import { catchError, of, tap } from 'rxjs'; @Component({ selector: 'app-schedule', standalone: false, templateUrl: './schedule.component.html', styleUrl: './schedule.component.css' }) export class ScheduleComponent implements OnInit { dates: { label: string; date: Date; performances: MovieGroup[] }[] = []; performaces: Vorstellung[] = []; movieSearchResult: string = ''; private readonly bookableDays: number = 14; private http = inject(HttpService); private loading = inject(LoadingService) constructor() { this.generateDates(this.bookableDays); } ngOnInit() { this.loadPerformances(this.bookableDays); } hasSearchResults(dateIndex: number): boolean { if (!this.movieSearchResult) return true; return this.dates[dateIndex].performances.some(group => group.movie.title.toLowerCase().includes(this.movieSearchResult.toLowerCase()) ); } generateDates(bookableDays: number) { const today = new Date(); for (let i = 0; i < bookableDays; i++) { const date = new Date(today); date.setDate(today.getDate() + i); let label = ''; if (i === 0) { label = 'Heute'; } else if (i === 1) { label = 'Morgen'; } else { label = date.toLocaleDateString('de-DE', { weekday: 'short' }) + '. ' + date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit'}); } this.dates.push({ label, date, performances: []}); } } loadPerformances(bookableDays: number) { this.loading.show(); const filter = this.generateDateFilter(bookableDays); this.http.getPerformacesByFilter(filter).pipe( tap(performaces => { this.performaces = performaces; this.assignPerformancesToDates(); this.loading.hide(); }), catchError(err => { this.loading.showError(err); console.error('Fehler beim Laden der Vorstellungen', err); return of([]); }) ).subscribe(); } private generateDateFilter(bookableDays: number): string[] { const startDate = new Date(); const endDate = new Date(); endDate.setDate(startDate.getDate() + bookableDays - 1); const startStr = startDate.toISOString().split('T')[0] + 'T00:00:00'; const endStr = endDate.toISOString().split('T')[0] + 'T23:59:59'; return [ `ge;start;date;${startStr}`, `le;start;date;${endStr}`, ]; } assignPerformancesToDates() { // Gruppieren nach Datum const groupedByDate: { [key: string]: Vorstellung[] } = {}; for (const vorstellung of this.performaces) { const dateKey = new Date(vorstellung.start).toDateString(); if (!groupedByDate[dateKey]) { groupedByDate[dateKey] = []; } groupedByDate[dateKey].push(vorstellung); } // Gruppieren nach Film for (const dateInfo of this.dates) { const dateKey = dateInfo.date.toDateString(); const dailyPerformances: Vorstellung[] = groupedByDate[dateKey] || []; const movieMap = new Map(); for (const perf of dailyPerformances) { const movieId = perf.movie.id; if (!movieMap.has(movieId)) { movieMap.set(movieId, { movie: perf.movie, performances: [] }); } const performance: Performance = { id: perf.id, hall: perf.hall.name, start: new Date(perf.start), // utilisation: 0 // TODO: perf.utilisation einrichten }; movieMap.get(movieId)!.performances.push(performance); } // MovieGroups erstellen dateInfo.performances = Array.from(movieMap.values()).map((entry) => ({ movie: entry.movie, performances: entry.performances.sort((a, b) => a.start.getTime() - b.start.getTime()), })) as MovieGroup[]; } } getMovieCount(index: number): number { return this.dates[index].performances.length; } }