This commit is contained in:
Constantin Simonis 2024-12-03 08:06:56 +01:00
parent 01de60aacb
commit 676aae14af
No known key found for this signature in database
GPG Key ID: 758DD9C506603183
11 changed files with 174 additions and 22 deletions

View File

@ -1,7 +1,7 @@
import { Routes } from '@angular/router';
import {Routes} from '@angular/router';
import {HotelsComponent} from "./hotel/hotels.component";
import {HotelComponent} from "./hotel/hotel.component";
import {EditHotelComponent} from "./hotel/edit-hotel.component";
import {CreateHotelComponent} from "./hotel/create-hotel.component";
export const routes: Routes = [
{
@ -11,7 +11,7 @@ export const routes: Routes = [
},
{
path: 'hotels/new',
component: EditHotelComponent,
component: CreateHotelComponent,
title: 'New Hotel'
},
{

View File

@ -0,0 +1,42 @@
import {Component, Input} from "@angular/core";
import {NgForOf} from "@angular/common";
import {TagComponent} from "./tag.component";
import {
AbstractControl,
ControlContainer,
FormArray,
FormControl,
FormGroupDirective,
Validators
} from "@angular/forms";
@Component({
selector: 'app-add-tag',
standalone: true,
template: `
`,
viewProviders: [
{
provide: ControlContainer,
useExisting: FormGroupDirective
}
],
imports: [
NgForOf,
TagComponent
]
})
export class AddTagComponent {
@Input()
form!: FormArray;
addTag() {
this.form.push(new FormControl('', [Validators.required]));
}
deleteTag(id: AbstractControl) {
this.form.removeAt(this.form.controls.indexOf(id));
}
}

View File

@ -1,21 +1,24 @@
import {Component} from "@angular/core";
import {Component, inject} from "@angular/core";
import {Hotel} from "./hotel";
import {HotelService} from "../service/hotel.service";
import {EditHotelComponent} from "./edit-hotel.component";
@Component({
selector: "app-create-hotel",
standalone: true,
imports: [
EditHotelComponent
],
template: `
<app-create-hotel (updateHotel)="create($event)" />
<app-edit-hotel (updateHotel)="create($event)"></app-edit-hotel>
`
})
export class CreateHotelComponent {
protected hotelService: HotelService;
hotelService: HotelService = inject(HotelService);
create(hotel: Hotel) {
console.log(hotel)
this.hotelService.createHotel(hotel).subscribe(console.log)
this.hotelService.createHotel(hotel).subscribe()
}
}

View File

@ -0,0 +1,27 @@
import {Component, inject, Input} from "@angular/core";
import {HotelService} from "../service/hotel.service";
import {Router} from "@angular/router";
@Component({
selector: 'app-delete-hotel',
standalone: true,
template: `
<button (click)="delete()">Delete Hotel</button>
`
})
export class DeleteHotelComponent {
@Input()
id: number = 0;
hotelService: HotelService = inject(HotelService);
router: Router = inject(Router);
delete() {
if (confirm('Are you sure?')) {
this.hotelService.deleteById(this.id).subscribe()
this.router.navigate(['/hotels']);
}
}
}

View File

@ -1,24 +1,29 @@
import {Component, EventEmitter, inject, Input, OnInit, Output} from '@angular/core';
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {
AbstractControl,
FormArray,
FormControl,
FormGroup,
FormsModule,
ReactiveFormsModule,
ValidationErrors, Validators
Validators
} from "@angular/forms";
import {Hotel} from "./hotel";
import {HotelService} from "../service/hotel.service";
import {RouterLink} from "@angular/router";
import {HotelsComponent} from "./hotels.component";
import {AddTagComponent} from "./add-tag.component";
import {NgForOf} from "@angular/common";
import {TagComponent} from "./tag.component";
@Component({
selector: 'app-create-hotel',
selector: 'app-edit-hotel',
standalone: true,
imports: [
FormsModule,
ReactiveFormsModule,
RouterLink
RouterLink,
AddTagComponent,
NgForOf,
TagComponent
],
template: `
<ng-form [formGroup]="form" (ngSubmit)="submit()">
@ -39,6 +44,16 @@ import {HotelsComponent} from "./hotels.component";
<input id="rating" type="number" formControlName="rating" min="0" max="5">
<br>
<br>
<button (click)="addTag()">+</button>
<div formArrayName="tags">
@for (tag of getTags().controls; track null) {
<br>
<input type="text" placeholder="tag" value="{{tag.value}}" formControlName="tagsControl">
<button (click)="deleteTag(tag)">-</button>
}
</div>
<br>
<br>
<button type="submit" (click)="submit()">Submit</button>
</ng-form>
@ -55,11 +70,18 @@ export class EditHotelComponent implements OnInit {
form!: FormGroup
ngOnInit(): void {
const tags = [];
for (const tag of this.hotel?.tags ?? []) {
tags.push(new FormControl(tag, [Validators.required]));
}
this.form = new FormGroup({
name: new FormControl(this.hotel?.hotelName, [Validators.required]),
description: new FormControl(this.hotel?.description, [Validators.required]),
price: new FormControl(this.hotel?.price, [Validators.required]),
rating: new FormControl(this.hotel?.rating, [Validators.required, Validators.min(0), Validators.max(5)]),
tags: new FormArray(tags),
})
}
@ -67,7 +89,6 @@ export class EditHotelComponent implements OnInit {
if (!this.form.valid) {
console.error('Form invalid');
return;
}
const hotel: Hotel = {
@ -77,10 +98,23 @@ export class EditHotelComponent implements OnInit {
price: this.form.value.price,
rating: this.form.value.rating,
id: this.hotel?.id ?? 0,
tags: this.form.value.tags ?? []
};
console.log(hotel)
this.updateHotel.emit(hotel)
this.hotel = hotel;
}
getTags() {
return this.form.controls['tags'] as FormArray;
}
addTag() {
this.getTags().push(new FormControl('', [Validators.required]));
}
deleteTag(tagElement: AbstractControl) {
this.getTags().removeAt(this.getTags().controls.indexOf(tagElement));
}
}

View File

@ -7,6 +7,7 @@ import {ActivatedRoute} from "@angular/router";
import {HotelService} from "../service/hotel.service";
import {catchError, EMPTY} from "rxjs";
import {EditHotelComponent} from "./edit-hotel.component";
import {DeleteHotelComponent} from "./delete-hotel.component";
@Component({
@ -16,12 +17,14 @@ import {EditHotelComponent} from "./edit-hotel.component";
CurrencyPipe,
StarComponent,
NgOptimizedImage,
EditHotelComponent
EditHotelComponent,
DeleteHotelComponent
],
template: `
<div style="border: white 2px; border-radius: 2px">
@if (hotel && !alert) {
<app-create-hotel [hotel]="hotel" (updateHotel)="update($event)" />
<app-edit-hotel [hotel]="hotel" (updateHotel)="update($event)" />
<app-delete-hotel [id]="hotel.id" />
} @else if(alert) {
<h2>{{alert}}</h2>
} @else {

View File

@ -5,4 +5,5 @@ export interface Hotel {
price: number;
imageUrl: string;
rating: number;
tags: string[];
}

View File

@ -17,6 +17,7 @@ import {StarComponent} from "../star/star.component";
<form>
<input name="search" [ngModel]="search" (ngModelChange)="searchEvent($event)">
</form>
<p routerLink="/hotels/new">Create Hotel</p>
@for (hotel of (matchingHotels | async); track hotel.id) {
<div>{{hotel.hotelName}}</div>
<img src="{{hotel.imageUrl}}" alt="{{hotel.hotelName}}" height="64" width="64">

View File

@ -0,0 +1,33 @@
import {Component, EventEmitter, Input, Output} from "@angular/core";
import {AbstractControl, ControlContainer, FormGroupDirective, ReactiveFormsModule} from "@angular/forms";
import {JsonPipe} from "@angular/common";
@Component({
standalone: true,
selector: 'app-tag',
imports: [
ReactiveFormsModule,
JsonPipe
],
viewProviders: [
{
provide: ControlContainer,
useExisting: FormGroupDirective
}
],
template: `
`
})
export class TagComponent {
@Input()
tagElement!: AbstractControl;
@Output()
deleteEvent: EventEmitter<AbstractControl> = new EventEmitter();
delete() {
this.deleteEvent.emit(this.tagElement);
}
}

View File

@ -11,7 +11,8 @@ export class HotelDataService implements InMemoryDbService{
"description": "Schöne Aussicht am Meer",
"price": 230.5,
"imageUrl": "assets/img/heisenberg.jpg",
"rating": 3.5
"rating": 3.5,
"tags": ["Meer", "Berge"]
},
{
"id": 2,
@ -19,7 +20,8 @@ export class HotelDataService implements InMemoryDbService{
"description": "Genießen Sie den Blick auf die Berge",
"price": 145.5,
"imageUrl": "assets/img/kjan.png",
"rating": 5
"rating": 5,
"tags": ["Meer", "Berge"]
},
{
"id": 3,
@ -27,7 +29,8 @@ export class HotelDataService implements InMemoryDbService{
"description": "Kompletter Aufenthalt mit Autoservice",
"price": 120.12,
"imageUrl": "assets/img/huy.png",
"rating": 4
"rating": 4,
"tags": ["Meer", "Berge"]
},
{
"id": 4,
@ -35,7 +38,8 @@ export class HotelDataService implements InMemoryDbService{
"description": "Wunderschönes Ambiente für Ihren Aufenthalt",
"price": 135.12,
"imageUrl": "assets/img/rat.png",
"rating": 2.5
"rating": 2.5,
"tags": ["Meer", "Berge"]
}
];

View File

@ -24,4 +24,8 @@ export class HotelService {
public createHotel(hotel: Hotel): Observable<Hotel> {
return this.httpClient.post<Hotel>(`/api/hotels`, hotel)
}
public deleteById(id: number): Observable<Hotel> {
return this.httpClient.delete<Hotel>(`/api/hotels/${id}`);
}
}