From 8dd8b8b4387c3dc1cdc7f082d5bc04135d70b0ce Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Tue, 12 Nov 2024 09:18:15 +0100 Subject: [PATCH] feat: add hotel details and list components with routing --- src/app/HotelItem/HotelItem.component.html | 1 + src/app/HotelItem/HotelItem.component.ts | 5 +- src/app/api/api.ts | 1 - src/app/app.component.html | 8 +- src/app/app.component.ts | 57 +-------------- src/app/app.config.ts | 6 +- src/app/app.routes.ts | 13 +++- .../hotel-details/hotel-details.component.css | 0 .../hotel-details.component.html | 1 + .../hotel-details.component.spec.ts | 23 ++++++ .../hotel-details/hotel-details.component.ts | 29 ++++++++ src/app/hotel-list/hotel-list.component.css | 0 src/app/hotel-list/hotel-list.component.html | 7 ++ .../hotel-list/hotel-list.component.spec.ts | 23 ++++++ src/app/hotel-list/hotel-list.component.ts | 73 +++++++++++++++++++ 15 files changed, 181 insertions(+), 66 deletions(-) create mode 100644 src/app/hotel-details/hotel-details.component.css create mode 100644 src/app/hotel-details/hotel-details.component.html create mode 100644 src/app/hotel-details/hotel-details.component.spec.ts create mode 100644 src/app/hotel-details/hotel-details.component.ts create mode 100644 src/app/hotel-list/hotel-list.component.css create mode 100644 src/app/hotel-list/hotel-list.component.html create mode 100644 src/app/hotel-list/hotel-list.component.spec.ts create mode 100644 src/app/hotel-list/hotel-list.component.ts diff --git a/src/app/HotelItem/HotelItem.component.html b/src/app/HotelItem/HotelItem.component.html index 1a874b2..1065705 100644 --- a/src/app/HotelItem/HotelItem.component.html +++ b/src/app/HotelItem/HotelItem.component.html @@ -7,4 +7,5 @@ } Hotel +Details diff --git a/src/app/HotelItem/HotelItem.component.ts b/src/app/HotelItem/HotelItem.component.ts index f7c2678..0e5d136 100644 --- a/src/app/HotelItem/HotelItem.component.ts +++ b/src/app/HotelItem/HotelItem.component.ts @@ -5,18 +5,21 @@ import { CurrencyPipe, NgIf } from "@angular/common"; import { FormsModule } from "@angular/forms"; import { StarRatingComponent } from "../star-rating/star-rating.component"; import { HttpClient } from "@angular/common/http"; +import { RouterLink } from "@angular/router"; @Component({ selector: 'app-hotel-item', standalone: true, templateUrl: './HotelItem.component.html', - imports: [ChildComponent, CurrencyPipe, FormsModule, StarRatingComponent, NgIf], + imports: [ChildComponent, CurrencyPipe, FormsModule, StarRatingComponent, NgIf, RouterLink], }) export class HotelItem { @Input() public hotel!: Hotel; public selectedLanguage?: string; + @Input() public isDetail: boolean = false; + public languageChange(lang: string) { this.selectedLanguage = lang; console.log(this.selectedLanguage); diff --git a/src/app/api/api.ts b/src/app/api/api.ts index 24c788c..b330010 100644 --- a/src/app/api/api.ts +++ b/src/app/api/api.ts @@ -51,7 +51,6 @@ export class HotelData implements InMemoryDbService { return { hotels }; } - genId(hotels: Hotel[]): number { return hotels.length > 0 ? Math.max(...hotels.map(hotel => hotel.id)) + 1 : 1; } diff --git a/src/app/app.component.html b/src/app/app.component.html index f638679..346d4ad 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,10 +1,4 @@ -

{{'hello' | uppercase | text}}

- -@if (hotels[0].hotelName) { -
- -
-} + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index a021147..50508e2 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -8,70 +8,17 @@ import { inject } from '@angular/core'; import { filter, from, last, map, Observable, scan } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { Hotel } from './HotelItem/hotel'; - -interface User { - name: string; - age: number; -} +import { RouterOutlet } from '@angular/router'; @Injectable({providedIn: "root"}) @Component({ selector: 'app-root', standalone: true, - imports: [NgFor, NgForOf, NgIf, HotelItem, SearchComponent, UpperCasePipe, TextPipe, AsyncPipe], + imports: [RouterOutlet, NgFor, NgForOf, NgIf, HotelItem, SearchComponent, UpperCasePipe, TextPipe, AsyncPipe], templateUrl: './app.component.html', providers: [HotelService], styleUrl: './app.component.css' }) export class AppComponent { - public search: string = ""; - public hotelService: HotelService = inject(HotelService); - public response: any = null; - public hotels: Array = [{} as Hotel]; - - constructor (private http: HttpClient) { - } - - ngOnInit() { - this.http.get>("api/hotels").subscribe(res => { - this.hotels = res; - }); - - const users = [ - { name: "Max", age: 21 }, - { name: "Peter", age: 31 }, - { name: "Hans", age: 13 }, - { name: "Klaus", age: 51 }, - { name: "Dieter", age: 1 }, - { name: "Jan-Marlon", age: 3 }, - ] - - const stream: Observable = from(users); - - stream.pipe( - filter((user) => user.age > 18), - scan((acc, user) => acc + user.age, 0), - map((ageSum, index) => ageSum / (index + 1)), - last(), - ).subscribe(console.log); - - // const stream: Observable = from([5, 1, 2, 12, 5, 14, 17, 5, "testing"]); - - // stream.pipe( - // filter((value) => typeof value === "number"), - // tap((value) => console.log("Zahl:" + value)), - // filter((value: number) => value % 2 === 0), - // tap((value) => console.log("Gerade Zahl: " + value)), - // toArray(), - //).subscribe(console.log); - } - - public test() { - console.log(this.search); - } - - // public foundHotels = this.hotels.pipe( - // filter((hotel) => hotel.hotelName.includes(this.search)), - // ); } diff --git a/src/app/app.config.ts b/src/app/app.config.ts index a490314..55b7251 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -12,5 +12,9 @@ import { HotelData } from './api/api'; registerLocaleData(localeDe, 'de-DE'); registerLocaleData(localeCn, 'cn-CN'); export const appConfig: ApplicationConfig = { - providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient(), importProvidersFrom(InMemoryWebApiModule.forRoot(HotelData))] + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(routes), + provideHttpClient(), + importProvidersFrom(InMemoryWebApiModule.forRoot(HotelData))] }; diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index dc39edb..eaaae27 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,3 +1,14 @@ import { Routes } from '@angular/router'; +import { HotelDetailsComponent } from './hotel-details/hotel-details.component'; +import { HotelListComponent } from './hotel-list/hotel-list.component'; -export const routes: Routes = []; +export const routes: Routes = [ + { + path: "", + component: HotelListComponent, + }, + { + path: "hotels/:id", + component: HotelDetailsComponent, + }, +]; diff --git a/src/app/hotel-details/hotel-details.component.css b/src/app/hotel-details/hotel-details.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/hotel-details/hotel-details.component.html b/src/app/hotel-details/hotel-details.component.html new file mode 100644 index 0000000..3a1c644 --- /dev/null +++ b/src/app/hotel-details/hotel-details.component.html @@ -0,0 +1 @@ + diff --git a/src/app/hotel-details/hotel-details.component.spec.ts b/src/app/hotel-details/hotel-details.component.spec.ts new file mode 100644 index 0000000..94047d9 --- /dev/null +++ b/src/app/hotel-details/hotel-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HotelDetailsComponent } from './hotel-details.component'; + +describe('HotelDetailsComponent', () => { + let component: HotelDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HotelDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HotelDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/hotel-details/hotel-details.component.ts b/src/app/hotel-details/hotel-details.component.ts new file mode 100644 index 0000000..ef39b15 --- /dev/null +++ b/src/app/hotel-details/hotel-details.component.ts @@ -0,0 +1,29 @@ +import { HttpClient } from '@angular/common/http'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Hotel } from '../HotelItem/hotel'; +import { CurrencyPipe } from '@angular/common'; +import { StarRatingComponent } from '../star-rating/star-rating.component'; +import { HotelItem } from '../HotelItem/HotelItem.component'; + +@Component({ + selector: 'app-hotel-details', + standalone: true, + imports: [CurrencyPipe, StarRatingComponent, HotelItem], + templateUrl: './hotel-details.component.html', + styleUrl: './hotel-details.component.css' +}) +export class HotelDetailsComponent implements OnInit { + public hotel: any; + + constructor(private route: ActivatedRoute, private http: HttpClient) { } + + ngOnInit(): void { + const routeParams = this.route.snapshot.paramMap; + const hotelId = routeParams.get("id"); + + this.http.get("api/hotels/" + hotelId).subscribe(res => { + this.hotel = res; + }); + } +} diff --git a/src/app/hotel-list/hotel-list.component.css b/src/app/hotel-list/hotel-list.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/hotel-list/hotel-list.component.html b/src/app/hotel-list/hotel-list.component.html new file mode 100644 index 0000000..8f8ec24 --- /dev/null +++ b/src/app/hotel-list/hotel-list.component.html @@ -0,0 +1,7 @@ +

{{'hello' | uppercase | text}}

+ +@if (hotels[0].hotelName) { +
+ +
+} diff --git a/src/app/hotel-list/hotel-list.component.spec.ts b/src/app/hotel-list/hotel-list.component.spec.ts new file mode 100644 index 0000000..ecc4715 --- /dev/null +++ b/src/app/hotel-list/hotel-list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HotelListComponent } from './hotel-list.component'; + +describe('HotelListComponent', () => { + let component: HotelListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HotelListComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HotelListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/hotel-list/hotel-list.component.ts b/src/app/hotel-list/hotel-list.component.ts new file mode 100644 index 0000000..528c8ce --- /dev/null +++ b/src/app/hotel-list/hotel-list.component.ts @@ -0,0 +1,73 @@ +import { CommonModule, NgFor, NgIf, UpperCasePipe } from '@angular/common'; +import { Component, inject } from '@angular/core'; +import { TextPipe } from '../../text.pipe'; +import { SearchComponent } from '../Search/search.component'; +import { HotelService } from '../Parent/services/hotel.service'; +import { Hotel } from '../HotelItem/hotel'; +import { HttpClient } from '@angular/common/http'; +import { filter, from, last, map, Observable, scan } from 'rxjs'; +import { HotelItem } from '../HotelItem/HotelItem.component'; + +interface User { + name: string; + age: number; +} + +@Component({ + selector: 'app-hotel-list', + standalone: true, + imports: [UpperCasePipe, TextPipe, SearchComponent, HotelItem, NgFor, NgIf], + templateUrl: './hotel-list.component.html', + styleUrl: './hotel-list.component.css' +}) +export class HotelListComponent { + public search: string = ""; + public hotelService: HotelService = inject(HotelService); + public response: any = null; + public hotels: Array = [{} as Hotel]; + + constructor (private http: HttpClient) { + } + + ngOnInit() { + this.http.get>("api/hotels").subscribe(res => { + this.hotels = res; + }); + + const users = [ + { name: "Max", age: 21 }, + { name: "Peter", age: 31 }, + { name: "Hans", age: 13 }, + { name: "Klaus", age: 51 }, + { name: "Dieter", age: 1 }, + { name: "Jan-Marlon", age: 3 }, + ] + + const stream: Observable = from(users); + + stream.pipe( + filter((user) => user.age > 18), + scan((acc, user) => acc + user.age, 0), + map((ageSum, index) => ageSum / (index + 1)), + last(), + ).subscribe(console.log); + + // const stream: Observable = from([5, 1, 2, 12, 5, 14, 17, 5, "testing"]); + + // stream.pipe( + // filter((value) => typeof value === "number"), + // tap((value) => console.log("Zahl:" + value)), + // filter((value: number) => value % 2 === 0), + // tap((value) => console.log("Gerade Zahl: " + value)), + // toArray(), + //).subscribe(console.log); + } + + public test() { + console.log(this.search); + } + + // public foundHotels = this.hotels.pipe( + // filter((hotel) => hotel.hotelName.includes(this.search)), + // ); +}