Make movie schedule components functional

Introduces MovieGroup and Performance models for better type safety and data handling. Refactors movie-related components to use Angular signals (input/computed) and updates templates to bind data dynamically. Updates HttpService to support Vorstellung API endpoints. The schedule component now loads and groups performances by date and movie, passing structured data to child components for rendering.
This commit is contained in:
2025-10-30 01:38:43 +01:00
parent 6ebde0b5f5
commit 98626d11ed
19 changed files with 213 additions and 69 deletions

View File

@@ -1,12 +1,12 @@
<mat-tab-group mat-stretch-tabs>
@for (dateInfo of dates; track dateInfo.date; let i = $index) {
@for (dateInfo of dates; track dateInfo.date; let i = $index) {
<mat-tab [label]="dateInfo.label">
@if (getMovieCount(i)> 0) {
@for (movie of [].constructor(getMovieCount(i)); track movie) {
<app-movie-schedule-info></app-movie-schedule-info>
@if (getMovieCount(i) > 0) {
@for (group of dateInfo.performances; track group.movie.id) {
<app-movie-schedule-info [movieGroup]="group"></app-movie-schedule-info>
}
} @else {
<app-movie-schedule-empty></app-movie-schedule-empty>
<app-movie-schedule-empty></app-movie-schedule-empty>
}
</mat-tab>
}

View File

@@ -1,4 +1,8 @@
import { Component } from '@angular/core';
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';
@Component({
selector: 'app-schedule',
@@ -6,16 +10,23 @@ import { Component } from '@angular/core';
templateUrl: './schedule.component.html',
styleUrl: './schedule.component.css'
})
export class ScheduleComponent {
dates: { label: string; date: Date }[] = [];
export class ScheduleComponent implements OnInit {
dates: { label: string; date: Date; performances: MovieGroup[] }[] = [];
performaces: Vorstellung[] = [];
private http = inject(HttpService);
constructor() {
this.generateDates();
}
ngOnInit() {
this.loadPerformances();
}
generateDates() {
const today = new Date();
for (let i = 0; i < 31; i++) {
for (let i = 0; i < 14; i++) {
const date = new Date(today);
date.setDate(today.getDate() + i);
@@ -28,12 +39,63 @@ dates: { label: string; date: Date }[] = [];
label = date.toLocaleDateString('de-DE', { weekday: 'short' }) + '. ' + date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit'});
}
this.dates.push({ label, date });
this.dates.push({ label, date, performances: []});
}
}
loadPerformances() {
this.http.getPerformaces().subscribe({
next: (data) => {
this.performaces = Array.isArray(data) ? data : [data];
this.assignPerformancesToDates();
},
error: (err) => console.error('Fehler beim Laden der Performances', err),
});
}
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<number, { movie: typeof dailyPerformances[0]['movie']; performances: Performance[] }>();
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 {
// Hier kannst du später die echten Filmzahlen zurückgeben
return index === 0 ? 10 : index === 1 ? 0 : 4;
return this.dates[index].performances.length;
}
}