Improve movie search & title fix
This commit is contained in:
@@ -23,6 +23,8 @@ import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatDialogClose, MatDialogTitle, MatDialogContent, MatDialogActions } from "@angular/material/dialog";
|
||||
import { MatStepperModule } from '@angular/material/stepper';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
|
||||
import { HeaderComponent } from './header/header.component';
|
||||
import { HomeComponent } from './home/home.component';
|
||||
@@ -133,6 +135,8 @@ import { TicketListComponent } from './ticket-list/ticket-list.component';
|
||||
NgxMaskDirective,
|
||||
NgxMaskPipe,
|
||||
QRCodeComponent,
|
||||
MatBadgeModule,
|
||||
MatTooltipModule,
|
||||
],
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
@if ( icon() ) {
|
||||
<mat-icon style="font-size: 35px; width: 35px; height: 35px; opacity: 50%;">{{ icon() }}</mat-icon>
|
||||
}
|
||||
<p class="text-2xl font-medium pl-2 bg-gradient-to-r from-indigo-500 to-pink-600 bg-clip-text text-transparent">
|
||||
{{ title() }}
|
||||
<p class="text-2xl font-medium pl-2 bg-linear-to-r from-indigo-500 to-pink-600 bg-clip-text text-transparent">
|
||||
{{ label() }}
|
||||
</p>
|
||||
</div>
|
||||
@if ( searchBar() ) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Component, input, output } from '@angular/core';
|
||||
styleUrl: './menu-header.component.css'
|
||||
})
|
||||
export class MenuHeaderComponent {
|
||||
title = input.required<string>();
|
||||
label = input.required<string>();
|
||||
icon = input<string>();
|
||||
|
||||
searchBar = input<boolean>(false);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<app-menu-header title="Film aus IMDb importieren" icon="cloud_download"></app-menu-header>
|
||||
<app-menu-header label="Film aus IMDb importieren" icon="cloud_download"></app-menu-header>
|
||||
|
||||
<div class="w-6/10 m-auto my-20">
|
||||
<form class="movie-search-form w-full" (ngSubmit)="DoSubmit()">
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
<form class="movie-search-form w-88">
|
||||
<mat-form-field class="w-full" subscriptSizing="dynamic">
|
||||
<mat-label>Film suchen</mat-label>
|
||||
<input class="w-full" type="text" matInput [formControl]="searchControl" [matAutocomplete]="auto" (click)="searchControl.setValue('')">
|
||||
<div class="flex items-center space-x-4">
|
||||
|
||||
<!-- @if (searchControl.hasError('filmNotFound')) { -->
|
||||
<!-- <mat-error>Film existiert nicht</mat-error> -->
|
||||
<!-- } -->
|
||||
@if (searchControl.value && searchControl.value.length > 0) {
|
||||
<button mat-icon-button #tooltip="matTooltip" matTooltip="Filter löschen" matTooltipPosition="above" class="w-11! h-11! opacity-50" (click)="searchControl.setValue('')">
|
||||
<mat-icon style="font-size: 25px; width: 25px; height: 25px;">filter_alt_off</mat-icon>
|
||||
</button>
|
||||
}
|
||||
|
||||
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
|
||||
@for (option of filteredOptions | async; track option) {
|
||||
<mat-option [value]="option">{{option}}</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
<form class="movie-search-form w-88">
|
||||
<mat-form-field class="w-full" subscriptSizing="dynamic">
|
||||
<mat-label>Film suchen</mat-label>
|
||||
<input class="w-full" type="text" matInput [formControl]="searchControl" [matAutocomplete]="auto">
|
||||
|
||||
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
|
||||
@for (option of filteredOptions | async; track option) {
|
||||
<mat-option [value]="option">{{option}}</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -5,3 +5,7 @@
|
||||
::ng-deep .mat-mdc-tab .mdc-tab-indicator__content--underline {
|
||||
border-color: #6366f1 !important; /* indigo-500 */
|
||||
}
|
||||
|
||||
.mat-badge-content {
|
||||
background: #dd2979;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
<app-menu-header title="Programmübersicht" icon="event" [searchBar]="true" (movieSearchResult)="movieSearchResult = $event"></app-menu-header>
|
||||
<app-menu-header label="Programmübersicht" icon="event" [searchBar]="true" (movieSearchResult)="movieSearchResult = $event"></app-menu-header>
|
||||
|
||||
<mat-tab-group mat-stretch-tabs>
|
||||
@for (dateInfo of dates; track dateInfo.date; let i = $index) {
|
||||
<mat-tab [label]="dateInfo.label">
|
||||
<ng-template mat-tab-label>
|
||||
<span [matBadge]="getMovieCount(i)" matBadgeOverlap="false" [matBadgeHidden]="!isSearch() || getMovieCount(i) === 0" [class]="(isSearch() && getMovieCount(i) === 0)? 'text-gray-300' : ''">
|
||||
{{ dateInfo.label }}
|
||||
</span>
|
||||
</ng-template>
|
||||
@if (getMovieCount(i) > 0) {
|
||||
@if (hasSearchResults(i)) {
|
||||
@for (group of dateInfo.performances; track group.movie.id) {
|
||||
@if (group.movie.title.toLowerCase().includes(movieSearchResult.toLowerCase())) {
|
||||
<app-movie-schedule-info [movieGroup]="group"></app-movie-schedule-info>
|
||||
}
|
||||
@for (group of dateInfo.performances; track group.movie.id) {
|
||||
@if (group.movie.title.toLowerCase().includes(movieSearchResult.toLowerCase())) {
|
||||
<app-movie-schedule-info [movieGroup]="group"></app-movie-schedule-info>
|
||||
}
|
||||
} @else {
|
||||
<app-movie-schedule-no-search-result [search]="movieSearchResult" [date]="dates[i].date" ></app-movie-schedule-no-search-result>
|
||||
}
|
||||
} @else {
|
||||
<app-movie-schedule-empty></app-movie-schedule-empty>
|
||||
@if (isSearch()) {
|
||||
<app-movie-schedule-no-search-result [search]="movieSearchResult" [date]="dates[i].date"></app-movie-schedule-no-search-result>
|
||||
} @else {
|
||||
<app-movie-schedule-empty></app-movie-schedule-empty>
|
||||
}
|
||||
}
|
||||
</mat-tab>
|
||||
}
|
||||
|
||||
@@ -31,15 +31,7 @@ export class ScheduleComponent implements OnInit {
|
||||
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) {
|
||||
private generateDates(bookableDays: number) {
|
||||
const today = new Date();
|
||||
for (let i = 0; i < bookableDays; i++) {
|
||||
const date = new Date(today);
|
||||
@@ -58,7 +50,7 @@ export class ScheduleComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
loadPerformances(bookableDays: number) {
|
||||
private loadPerformances(bookableDays: number) {
|
||||
this.loading.show();
|
||||
const filter = this.generateDateFilter(bookableDays);
|
||||
this.http.getPerformacesByFilter(filter).pipe(
|
||||
@@ -75,22 +67,21 @@ export class ScheduleComponent implements OnInit {
|
||||
).subscribe();
|
||||
}
|
||||
|
||||
private generateDateFilter(bookableDays: number): string[] {
|
||||
const startDate = new Date();
|
||||
const endDate = new Date();
|
||||
endDate.setDate(startDate.getDate() + bookableDays - 1);
|
||||
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';
|
||||
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}`,
|
||||
];
|
||||
}
|
||||
return [
|
||||
`ge;start;date;${startStr}`,
|
||||
`le;start;date;${endStr}`,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
assignPerformancesToDates() {
|
||||
private assignPerformancesToDates() {
|
||||
|
||||
// Gruppieren nach Datum
|
||||
const groupedByDate: { [key: string]: Vorstellung[] } = {};
|
||||
@@ -133,6 +124,22 @@ private generateDateFilter(bookableDays: number): string[] {
|
||||
}
|
||||
|
||||
getMovieCount(index: number): number {
|
||||
return this.dates[index].performances.length;
|
||||
if (!this.dates[index]?.performances) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const performances = this.dates[index].performances;
|
||||
|
||||
if (!this.isSearch()) {
|
||||
return performances.length;
|
||||
}
|
||||
|
||||
return performances.filter(group =>
|
||||
group.movie.title.toLowerCase().includes(this.movieSearchResult.toLowerCase())
|
||||
).length;
|
||||
}
|
||||
|
||||
isSearch(): boolean {
|
||||
return !!this.movieSearchResult && this.movieSearchResult.trim() !== '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<app-menu-header title="Vorstellungstickets kaufen" icon="local_activity" [backToSchedule]="true"></app-menu-header>
|
||||
<app-menu-header label="Vorstellungstickets kaufen" icon="local_activity" [backToSchedule]="true"></app-menu-header>
|
||||
|
||||
<div class="flex justify-between h-100">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user