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 { MatDialogClose, MatDialogTitle, MatDialogContent, MatDialogActions } from "@angular/material/dialog";
|
||||||
import { MatStepperModule } from '@angular/material/stepper';
|
import { MatStepperModule } from '@angular/material/stepper';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
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 { HeaderComponent } from './header/header.component';
|
||||||
import { HomeComponent } from './home/home.component';
|
import { HomeComponent } from './home/home.component';
|
||||||
@@ -133,6 +135,8 @@ import { TicketListComponent } from './ticket-list/ticket-list.component';
|
|||||||
NgxMaskDirective,
|
NgxMaskDirective,
|
||||||
NgxMaskPipe,
|
NgxMaskPipe,
|
||||||
QRCodeComponent,
|
QRCodeComponent,
|
||||||
|
MatBadgeModule,
|
||||||
|
MatTooltipModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
provideBrowserGlobalErrorListeners(),
|
provideBrowserGlobalErrorListeners(),
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
@if ( icon() ) {
|
@if ( icon() ) {
|
||||||
<mat-icon style="font-size: 35px; width: 35px; height: 35px; opacity: 50%;">{{ icon() }}</mat-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">
|
<p class="text-2xl font-medium pl-2 bg-linear-to-r from-indigo-500 to-pink-600 bg-clip-text text-transparent">
|
||||||
{{ title() }}
|
{{ label() }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@if ( searchBar() ) {
|
@if ( searchBar() ) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Component, input, output } from '@angular/core';
|
|||||||
styleUrl: './menu-header.component.css'
|
styleUrl: './menu-header.component.css'
|
||||||
})
|
})
|
||||||
export class MenuHeaderComponent {
|
export class MenuHeaderComponent {
|
||||||
title = input.required<string>();
|
label = input.required<string>();
|
||||||
icon = input<string>();
|
icon = input<string>();
|
||||||
|
|
||||||
searchBar = input<boolean>(false);
|
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">
|
<div class="w-6/10 m-auto my-20">
|
||||||
<form class="movie-search-form w-full" (ngSubmit)="DoSubmit()">
|
<form class="movie-search-form w-full" (ngSubmit)="DoSubmit()">
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
|
||||||
|
@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>
|
||||||
|
}
|
||||||
|
|
||||||
<form class="movie-search-form w-88">
|
<form class="movie-search-form w-88">
|
||||||
<mat-form-field class="w-full" subscriptSizing="dynamic">
|
<mat-form-field class="w-full" subscriptSizing="dynamic">
|
||||||
<mat-label>Film suchen</mat-label>
|
<mat-label>Film suchen</mat-label>
|
||||||
<input class="w-full" type="text" matInput [formControl]="searchControl" [matAutocomplete]="auto" (click)="searchControl.setValue('')">
|
<input class="w-full" type="text" matInput [formControl]="searchControl" [matAutocomplete]="auto">
|
||||||
|
|
||||||
<!-- @if (searchControl.hasError('filmNotFound')) { -->
|
|
||||||
<!-- <mat-error>Film existiert nicht</mat-error> -->
|
|
||||||
<!-- } -->
|
|
||||||
|
|
||||||
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
|
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
|
||||||
@for (option of filteredOptions | async; track option) {
|
@for (option of filteredOptions | async; track option) {
|
||||||
@@ -14,3 +18,5 @@
|
|||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -5,3 +5,7 @@
|
|||||||
::ng-deep .mat-mdc-tab .mdc-tab-indicator__content--underline {
|
::ng-deep .mat-mdc-tab .mdc-tab-indicator__content--underline {
|
||||||
border-color: #6366f1 !important; /* indigo-500 */
|
border-color: #6366f1 !important; /* indigo-500 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mat-badge-content {
|
||||||
|
background: #dd2979;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
<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>
|
<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">
|
<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 (getMovieCount(i) > 0) {
|
||||||
@if (hasSearchResults(i)) {
|
|
||||||
@for (group of dateInfo.performances; track group.movie.id) {
|
@for (group of dateInfo.performances; track group.movie.id) {
|
||||||
@if (group.movie.title.toLowerCase().includes(movieSearchResult.toLowerCase())) {
|
@if (group.movie.title.toLowerCase().includes(movieSearchResult.toLowerCase())) {
|
||||||
<app-movie-schedule-info [movieGroup]="group"></app-movie-schedule-info>
|
<app-movie-schedule-info [movieGroup]="group"></app-movie-schedule-info>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
|
@if (isSearch()) {
|
||||||
<app-movie-schedule-no-search-result [search]="movieSearchResult" [date]="dates[i].date"></app-movie-schedule-no-search-result>
|
<app-movie-schedule-no-search-result [search]="movieSearchResult" [date]="dates[i].date"></app-movie-schedule-no-search-result>
|
||||||
}
|
|
||||||
} @else {
|
} @else {
|
||||||
<app-movie-schedule-empty></app-movie-schedule-empty>
|
<app-movie-schedule-empty></app-movie-schedule-empty>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
}
|
}
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
|
|||||||
@@ -31,15 +31,7 @@ export class ScheduleComponent implements OnInit {
|
|||||||
this.loadPerformances(this.bookableDays);
|
this.loadPerformances(this.bookableDays);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasSearchResults(dateIndex: number): boolean {
|
private generateDates(bookableDays: number) {
|
||||||
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();
|
const today = new Date();
|
||||||
for (let i = 0; i < bookableDays; i++) {
|
for (let i = 0; i < bookableDays; i++) {
|
||||||
const date = new Date(today);
|
const date = new Date(today);
|
||||||
@@ -58,7 +50,7 @@ export class ScheduleComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPerformances(bookableDays: number) {
|
private loadPerformances(bookableDays: number) {
|
||||||
this.loading.show();
|
this.loading.show();
|
||||||
const filter = this.generateDateFilter(bookableDays);
|
const filter = this.generateDateFilter(bookableDays);
|
||||||
this.http.getPerformacesByFilter(filter).pipe(
|
this.http.getPerformacesByFilter(filter).pipe(
|
||||||
@@ -89,8 +81,7 @@ private generateDateFilter(bookableDays: number): string[] {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private assignPerformancesToDates() {
|
||||||
assignPerformancesToDates() {
|
|
||||||
|
|
||||||
// Gruppieren nach Datum
|
// Gruppieren nach Datum
|
||||||
const groupedByDate: { [key: string]: Vorstellung[] } = {};
|
const groupedByDate: { [key: string]: Vorstellung[] } = {};
|
||||||
@@ -133,6 +124,22 @@ private generateDateFilter(bookableDays: number): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMovieCount(index: number): number {
|
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">
|
<div class="flex justify-between h-100">
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user