Add movie search and schedule header components
Introduces MovieSearchComponent, ScheduleHeaderComponent, and MovieScheduleNoSearchResultComponent for improved movie search and schedule display. Updates schedule and navbar to support search functionality and UI enhancements. Adds movie fetching to HttpService and refines layout and styles for better user experience.
This commit is contained in:
0
src/app/movie-search/movie-search.component.css
Normal file
0
src/app/movie-search/movie-search.component.css
Normal file
16
src/app/movie-search/movie-search.component.html
Normal file
16
src/app/movie-search/movie-search.component.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<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('')">
|
||||
|
||||
<!-- @if (searchControl.hasError('filmNotFound')) { -->
|
||||
<!-- <mat-error>Film existiert nicht</mat-error> -->
|
||||
<!-- } -->
|
||||
|
||||
<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>
|
||||
62
src/app/movie-search/movie-search.component.ts
Normal file
62
src/app/movie-search/movie-search.component.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Component, inject, OnInit, output, ViewEncapsulation } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { catchError, map, startWith, tap } from 'rxjs/operators';
|
||||
import { HttpService } from '../http.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-movie-search',
|
||||
standalone: false,
|
||||
templateUrl: './movie-search.component.html',
|
||||
styleUrl: './movie-search.component.css',
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MovieSearchComponent implements OnInit {
|
||||
|
||||
movieSearchResult = output<string>();
|
||||
|
||||
options: string[] = [];
|
||||
filteredOptions: Observable<string[]> = new Observable();
|
||||
|
||||
searchControl = new FormControl('', (control) => {
|
||||
if (!control.value) return null;
|
||||
|
||||
const value = control.value.toLowerCase();
|
||||
const found = this.options.some(option =>
|
||||
option.toLowerCase().includes(value)
|
||||
);
|
||||
return found ? null : { filmNotFound: true };
|
||||
});
|
||||
|
||||
private http = inject(HttpService)
|
||||
|
||||
ngOnInit() {
|
||||
this.loadMovies();
|
||||
this.filteredOptions = this.searchControl.valueChanges.pipe(
|
||||
startWith(''),
|
||||
tap(value => this.movieSearchResult.emit(value || '')),
|
||||
map(value => this._filter(value || ''))
|
||||
);
|
||||
}
|
||||
|
||||
private _filter(value: string): string[] {
|
||||
const filterValue = value.toLowerCase();
|
||||
return this.options.filter(option =>
|
||||
option.toLowerCase().includes(filterValue)
|
||||
);
|
||||
}
|
||||
|
||||
private loadMovies() {
|
||||
this.http.getMovies().pipe(
|
||||
tap(movies => {
|
||||
this.options = movies
|
||||
.map(movie => movie.title)
|
||||
.sort();
|
||||
}),
|
||||
catchError(err => {
|
||||
console.error('Fehler beim Laden der Filme', err);
|
||||
return of([]);
|
||||
})
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user