jleibl_hotel_manager #20
@ -2,6 +2,8 @@ import { Routes } from '@angular/router';
|
||||
import { HotelDetailsComponent } from './hotel-details/hotel-details.component';
|
||||
import { HotelListComponent } from './hotel-list/hotel-list.component';
|
||||
import { HotelFormComponent } from './hotel-form/hotel-form.component';
|
||||
import { inject } from '@angular/core';
|
||||
import { formGuard } from './form.guard';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
@ -11,9 +13,11 @@ export const routes: Routes = [
|
||||
{
|
||||
path: "hotels/:id",
|
||||
component: HotelDetailsComponent,
|
||||
canDeactivate: [formGuard],
|
||||
},
|
||||
{
|
||||
path: "create-hotel",
|
||||
component: HotelFormComponent,
|
||||
canDeactivate: [formGuard],
|
||||
},
|
||||
];
|
||||
|
17
src/app/form.guard.spec.ts
Normal file
17
src/app/form.guard.spec.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { CanDeactivateFn } from '@angular/router';
|
||||
|
||||
import { formGuard } from './form.guard';
|
||||
|
||||
describe('formGuard', () => {
|
||||
const executeGuard: CanDeactivateFn = (...guardParameters) =>
|
||||
TestBed.runInInjectionContext(() => formGuard(...guardParameters));
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(executeGuard).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/form.guard.ts
Normal file
15
src/app/form.guard.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { CanDeactivateFn } from '@angular/router';
|
||||
import { HotelFormComponent } from './hotel-form/hotel-form.component';
|
||||
import { HotelDetailsComponent } from './hotel-details/hotel-details.component';
|
||||
|
||||
export const formGuard: CanDeactivateFn<HotelFormComponent | HotelDetailsComponent> = (component: HotelFormComponent | HotelDetailsComponent, currentRoute, currentState, nextState) => {
|
||||
console.log(component)
|
||||
if (component instanceof HotelFormComponent && component.form?.dirty) {
|
||||
return confirm('You have unsaved changes. Do you really want to leave?');
|
||||
}
|
||||
else if (component instanceof HotelDetailsComponent && component.hotelForm?.form?.dirty) {
|
||||
return confirm('You have unsaved changes. Do you really want to leave?');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
<div class="container p-4 mx-auto max-w-4xl">
|
||||
<div class="border border-gray-500 p-4 rounded mt-4" *ngIf="hotel">
|
||||
<app-hotel-form [hotel]="hotel"></app-hotel-form>
|
||||
<div *ngIf="hotel">
|
||||
<app-hotel-form [hotel]="hotel" #hotelForm></app-hotel-form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,23 +1,24 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Hotel } from '../HotelItem/hotel';
|
||||
import {CurrencyPipe, NgIf} from '@angular/common';
|
||||
import { StarRatingComponent } from '../star-rating/star-rating.component';
|
||||
import { HotelItem } from '../HotelItem/HotelItem.component';
|
||||
import { NgIf } from '@angular/common';
|
||||
import { catchError, EMPTY } from 'rxjs';
|
||||
import {HotelFormComponent} from "../hotel-form/hotel-form.component";
|
||||
import { HotelFormComponent } from "../hotel-form/hotel-form.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-hotel-details',
|
||||
standalone: true,
|
||||
imports: [CurrencyPipe, StarRatingComponent, HotelItem, HotelFormComponent, NgIf, RouterLink],
|
||||
imports: [HotelFormComponent, NgIf],
|
||||
templateUrl: './hotel-details.component.html',
|
||||
styleUrl: './hotel-details.component.css'
|
||||
})
|
||||
export class HotelDetailsComponent implements OnInit {
|
||||
public hotel: any;
|
||||
|
||||
@ViewChild('hotelForm', { static: false })
|
||||
public hotelForm!: HotelFormComponent;
|
||||
|
||||
constructor(private route: ActivatedRoute, private http: HttpClient, private router: Router) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -57,7 +57,7 @@
|
||||
<mat-icon class="text-red-500">delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" mat-stroked-button (click)="addTag()" class="mt-2">Add Tag</button>
|
||||
<button type="button" mat-button (click)="addTag()" class="mt-2">Add Tag</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
@ -65,8 +65,19 @@
|
||||
<button type="submit" mat-flat-button (click)="submit()">Submit</button>
|
||||
<button type="button" mat-stroked-button routerLink="/">Cancel</button>
|
||||
</div>
|
||||
<button mat-icon-button aria-label="Delete hotel" *ngIf="hotel" (click)="delete(hotel.id)">
|
||||
<mat-icon class="text-red-500">delete</mat-icon>
|
||||
<button mat-stroked-button color="warn" aria-label="Delete hotel" *ngIf="hotel" (click)="showDeleteConfirmation = true">
|
||||
Remove
|
||||
</button>
|
||||
|
||||
<div *ngIf="showDeleteConfirmation" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div class="bg-white p-6 rounded-lg shadow-lg max-w-sm w-full">
|
||||
<h2 class="text-xl font-bold mb-4">Confirm Deletion</h2>
|
||||
<p class="mb-6">Are you sure you want to delete this hotel?</p>
|
||||
<div class="flex justify-end space-x-2">
|
||||
<button mat-stroked-button (click)="showDeleteConfirmation = false">Cancel</button>
|
||||
<button mat-flat-button color="warn" (click)="delete(hotel.id)">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,4 +1,4 @@
|
||||
import { Component, inject, Inject, Input } from '@angular/core';
|
||||
import { Component, HostListener, inject, Inject, Input } from '@angular/core';
|
||||
import { FormArray, FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||
import { Hotel } from "../HotelItem/hotel";
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
@ -32,6 +32,8 @@ export class HotelFormComponent {
|
||||
|
||||
public router: Router = inject(Router);
|
||||
|
||||
public showDeleteConfirmation = false;
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -66,7 +68,7 @@ export class HotelFormComponent {
|
||||
}
|
||||
|
||||
public submit() {
|
||||
if (this.form.valid) {
|
||||
if (this.form.valid && !this.form.dirty) {
|
||||
const hotelData: Hotel = {
|
||||
id: this.hotel?.id || 0,
|
||||
hotelName: this.form.value.name,
|
||||
|
@ -1,10 +1,28 @@
|
||||
<div class="container p-4 mx-auto max-w-4xl">
|
||||
<h1>{{'hello' | uppercase | text}}</h1>
|
||||
<app-search [(input)]="search"></app-search>
|
||||
<button routerLink="/create-hotel" mat-flat-button class="btn btn-primary bg-blue-500 text-white font-semibold py-2 px-4 rounded-md shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75 my-4">Create New Hotel</button>
|
||||
<div *ngIf="hotels[0].hotelName">
|
||||
<div class="fixed top-0 left-0 w-full bg-white/80 backdrop-blur-xl z-50">
|
||||
<div class="justify-center max-w-4xl container p-4 mx-auto">
|
||||
<h1>{{'hello' | uppercase | text}}</h1>
|
||||
<app-search [(input)]="search"></app-search>
|
||||
<button routerLink="/create-hotel" mat-flat-button
|
||||
class="btn btn-primary bg-blue-500 text-white font-semibold py-2 px-4 rounded-md shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75 my-4">Create
|
||||
New Hotel</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="hotels[0].hotelName" class="mt-56">
|
||||
<div *ngFor="let hotel of hotels">
|
||||
<app-hotel-item *ngIf="hotel.hotelName.toLowerCase().includes(search.toLowerCase())" [hotel]="hotel"></app-hotel-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!hotels[0].hotelName" class="mt-56">
|
||||
<div class="animate-pulse space-y-4">
|
||||
<div class="h-8 bg-gray-200 rounded w-52"></div>
|
||||
<div class="space-y-3">
|
||||
<div class="h-4 bg-gray-200 rounded w-3/4"></div>
|
||||
<div class="h-4 bg-gray-200 rounded w-11/12"></div>
|
||||
<div class="h-4 bg-gray-200 rounded w-2/3"></div>
|
||||
</div>
|
||||
<div class="h-[300px] bg-gray-200 rounded w-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user