nice
This commit is contained in:
parent
3c6515f91f
commit
727a636b97
@ -1,6 +1,7 @@
|
|||||||
import { Component } from '@angular/core';
|
import {Component, inject} from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
import {MainViewComponent} from './components/main-view/main-view.component';
|
import {MainViewComponent} from './components/main-view/main-view.component';
|
||||||
|
import {ShowService} from './services/show.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -11,4 +12,5 @@ import {MainViewComponent} from './components/main-view/main-view.component';
|
|||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'netflix';
|
title = 'netflix';
|
||||||
|
showService: ShowService = inject(ShowService);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
|||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter } from '@angular/router';
|
||||||
|
|
||||||
import { routes } from './app.routes';
|
import { routes } from './app.routes';
|
||||||
|
import {provideHttpClient} from '@angular/common/http';
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
|
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient()]
|
||||||
};
|
};
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
<div class="row mt-3"><h1>TV-Serien</h1></div>
|
<div class="row mt-3"><h1>TV-Serien</h1></div>
|
||||||
<div class="row mt-1">
|
<div class="row mt-1">
|
||||||
<div class="col-md-7 mb-3">
|
<div class="col-md-7 mb-3">
|
||||||
<app-show-list></app-show-list>
|
<app-show-list [shows]="shows" (selectedShow)="onSelectedShow($event)"></app-show-list>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
|
@if (isShowSelected) {
|
||||||
|
<app-show-details [detailShow$]="selectedShow$"></app-show-details>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<app-show-form></app-show-form>
|
<app-show-form></app-show-form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,16 +1,41 @@
|
|||||||
import {Component} from '@angular/core';
|
import {Component, inject} from '@angular/core';
|
||||||
import {ShowListComponent} from '../show-list/show-list.component';
|
import {ShowListComponent} from '../show-list/show-list.component';
|
||||||
|
import {Show} from '../../model/show';
|
||||||
|
import {ShowService} from '../../services/show.service';
|
||||||
import {ShowFormComponent} from '../show-form/show-form.component';
|
import {ShowFormComponent} from '../show-form/show-form.component';
|
||||||
|
import {BehaviorSubject} from 'rxjs';
|
||||||
|
import {ApiService} from '../../services/api-service';
|
||||||
|
import {ShowDetailsComponent} from '../show-details/show-details.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-main-view',
|
selector: 'app-main-view',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
ShowListComponent,
|
ShowListComponent,
|
||||||
ShowFormComponent
|
ShowFormComponent,
|
||||||
|
ShowDetailsComponent
|
||||||
],
|
],
|
||||||
templateUrl: './main-view.component.html',
|
templateUrl: './main-view.component.html',
|
||||||
styleUrl: './main-view.component.css'
|
styleUrl: './main-view.component.css'
|
||||||
})
|
})
|
||||||
export class MainViewComponent {
|
export class MainViewComponent {
|
||||||
|
private dataService: ShowService = inject(ShowService);
|
||||||
|
private apiService: ApiService = inject(ApiService);
|
||||||
|
|
||||||
|
public shows: Show[] = [];
|
||||||
|
selectedShow$: BehaviorSubject<Show>;
|
||||||
|
isShowSelected = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.shows = this.dataService.getShows();
|
||||||
|
this.selectedShow$ = new BehaviorSubject<Show>(new Show(0, ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectedShow(show: Show) {
|
||||||
|
const title = show.title ?? '';
|
||||||
|
this.apiService.getDetailShow(title).subscribe((s) => {
|
||||||
|
this.selectedShow$.next(s);
|
||||||
|
});
|
||||||
|
this.isShowSelected = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
@if (detailShow$ | async; as detailShow) {
|
||||||
|
<div class="card">
|
||||||
|
<img class="card-img-top img-fluid" ngSrc="{{detailShow.image}}">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">{{ detailShow.title }}</h4>
|
||||||
|
<p class="card-text" [innerHTML]="detailShow.summary"></p></div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ShowDetailsComponent } from './show-details.component';
|
||||||
|
|
||||||
|
describe('ShowDetailsComponent', () => {
|
||||||
|
let component: ShowDetailsComponent;
|
||||||
|
let fixture: ComponentFixture<ShowDetailsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ShowDetailsComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ShowDetailsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
18
src/app/components/show-details/show-details.component.ts
Normal file
18
src/app/components/show-details/show-details.component.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {BehaviorSubject} from 'rxjs';
|
||||||
|
import {Show} from '../../model/show';
|
||||||
|
import {AsyncPipe, NgOptimizedImage} from '@angular/common';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-show-details',
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
NgOptimizedImage
|
||||||
|
],
|
||||||
|
templateUrl: './show-details.component.html',
|
||||||
|
styleUrl: './show-details.component.css'
|
||||||
|
})
|
||||||
|
export class ShowDetailsComponent {
|
||||||
|
@Input() detailShow$?: BehaviorSubject<Show>;
|
||||||
|
}
|
@ -14,12 +14,12 @@ import {FormsModule} from '@angular/forms';
|
|||||||
})
|
})
|
||||||
export class ShowFormComponent {
|
export class ShowFormComponent {
|
||||||
showService: ShowService = inject(ShowService);
|
showService: ShowService = inject(ShowService);
|
||||||
show: Show = new Show(null, null);
|
show: Show = new Show(0, "");
|
||||||
shows: Show[] = this.showService.getShows();
|
shows: Show[] = this.showService.getShows();
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
this.shows.push(this.show);
|
this.shows.push(this.show);
|
||||||
|
|
||||||
this.show = new Show(null, null);
|
this.show = new Show(0, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ show.id }}</td>
|
<td>{{ show.id }}</td>
|
||||||
<td>{{ show.title }}</td>
|
<td>{{ show.title }}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-primary" (click)="showDetails(show)">Details</button>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-secondary" (click)="edit(show)">Bearbeiten</button>
|
<button class="btn btn-secondary" (click)="edit(show)">Bearbeiten</button>
|
||||||
</td>
|
</td>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import {Component, inject} from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {Show} from '../../model/show';
|
import {Show} from '../../model/show';
|
||||||
import {ShowService} from '../../services/show.service';
|
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -13,9 +12,13 @@ import {FormsModule} from '@angular/forms';
|
|||||||
styleUrl: './show-list.component.css'
|
styleUrl: './show-list.component.css'
|
||||||
})
|
})
|
||||||
export class ShowListComponent {
|
export class ShowListComponent {
|
||||||
showService: ShowService = inject(ShowService);
|
@Input() shows: Show[] = [];
|
||||||
shows: Show[] = this.showService.getShows();
|
@Output() selectedShow = new EventEmitter<Show>();
|
||||||
editShow: Show = new Show(null, null);
|
editShow: Show = new Show(0, "");
|
||||||
|
|
||||||
|
showDetails(show: Show) {
|
||||||
|
this.selectedShow.emit(show);
|
||||||
|
}
|
||||||
|
|
||||||
edit(show: Show) {
|
edit(show: Show) {
|
||||||
this.editShow = show;
|
this.editShow = show;
|
||||||
@ -24,7 +27,7 @@ export class ShowListComponent {
|
|||||||
saveEdit() {
|
saveEdit() {
|
||||||
this.updateShow(this.editShow);
|
this.updateShow(this.editShow);
|
||||||
|
|
||||||
this.editShow = new Show(null, null);
|
this.editShow = new Show(0, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
updateShow(show: Show) {
|
updateShow(show: Show) {
|
||||||
|
11
src/app/model/ShowDto.ts
Normal file
11
src/app/model/ShowDto.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export class ShowDTO {
|
||||||
|
constructor(
|
||||||
|
public id: number,
|
||||||
|
public title: string,
|
||||||
|
public image?: {
|
||||||
|
medium: string;
|
||||||
|
original: string;
|
||||||
|
},
|
||||||
|
public summary?: string) {
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
export class Show {
|
export class Show {
|
||||||
constructor(public id: number|null, public title: string|null) {
|
constructor(public id?: number, public title?: string, public image?: string, public summary?: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
src/app/services/api-service.ts
Normal file
24
src/app/services/api-service.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {inject, Injectable} from '@angular/core';
|
||||||
|
import {Show} from '../model/show';
|
||||||
|
import {HttpClient} from '@angular/common/http';
|
||||||
|
import {map, Observable} from 'rxjs';
|
||||||
|
import {ShowDTO} from '../model/ShowDto';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ApiService {
|
||||||
|
private baseUrl: string = "https://api.tvmaze.com";
|
||||||
|
httpClient: HttpClient = inject(HttpClient);
|
||||||
|
|
||||||
|
getDetailShow(title: string): Observable<Show> {
|
||||||
|
const apiUrl = `${this.baseUrl}/singlesearch/shows?q=${title}`;
|
||||||
|
let show: Show = new Show(0, title);
|
||||||
|
|
||||||
|
return this.httpClient.get<ShowDTO>(apiUrl).pipe(map((s) => {
|
||||||
|
show.summary = s.summary;
|
||||||
|
show.image = s.image?.medium;
|
||||||
|
return show;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user