diff --git a/angular.json b/angular.json index 0529da2..57bf8a9 100644 --- a/angular.json +++ b/angular.json @@ -16,9 +16,7 @@ "outputPath": "dist/hotel-manager", "index": "src/index.html", "browser": "src/main.ts", - "polyfills": [ - "zone.js" - ], + "polyfills": ["zone.js"], "tsConfig": "tsconfig.app.json", "assets": [ { @@ -27,9 +25,7 @@ }, "src/assets" ], - "styles": [ - "src/styles.css" - ], + "styles": ["src/styles.css"], "scripts": [] }, "configurations": { @@ -74,10 +70,7 @@ "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "polyfills": [ - "zone.js", - "zone.js/testing" - ], + "polyfills": ["zone.js", "zone.js/testing"], "tsConfig": "tsconfig.spec.json", "assets": [ { @@ -85,9 +78,7 @@ "input": "public" } ], - "styles": [ - "src/styles.css" - ], + "styles": ["src/styles.css"], "scripts": [] } } diff --git a/renovate.json b/renovate.json index c183f9d..89613e3 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,4 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "local>Renovate/renovate-config" - ] + "extends": ["local>Renovate/renovate-config"] } diff --git a/src/app/Button/button.component.html b/src/app/Button/button.component.html index 54fb491..245bafa 100644 --- a/src/app/Button/button.component.html +++ b/src/app/Button/button.component.html @@ -1 +1,6 @@ - + diff --git a/src/app/Button/button.component.ts b/src/app/Button/button.component.ts index c77daef..96e47fe 100644 --- a/src/app/Button/button.component.ts +++ b/src/app/Button/button.component.ts @@ -1,5 +1,4 @@ -import { Component } from "@angular/core"; - +import { Component } from '@angular/core'; @Component({ selector: 'app-button', diff --git a/src/app/Child/child.component.html b/src/app/Child/child.component.html index 84f430a..df67c69 100644 --- a/src/app/Child/child.component.html +++ b/src/app/Child/child.component.html @@ -1,4 +1,12 @@

Child

-

Balance: {{balance}}

-

I'm broke. Now I'm about as poor as Jan-Marlon.

- +

Balance: {{ balance }}

+

+ I'm broke. Now I'm about as poor as Jan-Marlon. +

+ diff --git a/src/app/Child/child.component.ts b/src/app/Child/child.component.ts index e03c3ad..d789816 100644 --- a/src/app/Child/child.component.ts +++ b/src/app/Child/child.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, Output, EventEmitter } from "@angular/core"; +import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-child', diff --git a/src/app/HotelItem/HotelItem.component.html b/src/app/HotelItem/HotelItem.component.html index cb2a46b..329cc33 100644 --- a/src/app/HotelItem/HotelItem.component.html +++ b/src/app/HotelItem/HotelItem.component.html @@ -1,8 +1,37 @@ -

Name: {{hotel.hotelName}}

-

Description: {{hotel.description}}

-

Price: {{hotel.price | currency : getCurrencyCode(selectedLanguage) : "symbol" : "2.2-2" : selectedLanguage}}

- + -Hotel -Details +Hotel +Details diff --git a/src/app/HotelItem/HotelItem.component.ts b/src/app/HotelItem/HotelItem.component.ts index 934de63..c8e1036 100644 --- a/src/app/HotelItem/HotelItem.component.ts +++ b/src/app/HotelItem/HotelItem.component.ts @@ -1,20 +1,27 @@ -import { Component, Injectable, Input } from "@angular/core"; -import { ChildComponent } from "../Child/child.component"; -import { Hotel } from "./hotel"; -import { CurrencyPipe, NgFor, 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"; +import { Component, Injectable, Input } from '@angular/core'; +import { ChildComponent } from '../Child/child.component'; +import { Hotel } from './hotel'; +import { CurrencyPipe, NgFor, 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, RouterLink, NgFor], + imports: [ + ChildComponent, + CurrencyPipe, + FormsModule, + StarRatingComponent, + NgIf, + RouterLink, + NgFor, + ], }) export class HotelItem { - @Input() public hotel!: Hotel; public selectedLanguage?: string; @@ -38,19 +45,19 @@ export class HotelItem { public langs = [ { - "lang": "en", - "code": "en-US", - "currency": "USD" + lang: 'en', + code: 'en-US', + currency: 'USD', }, { - "lang": "cn", - "code": "cn-CN", - "currency": "CNY" + lang: 'cn', + code: 'cn-CN', + currency: 'CNY', }, { - "lang": "de", - "code": "de-DE", - "currency": "EUR" - } + lang: 'de', + code: 'de-DE', + currency: 'EUR', + }, ]; } diff --git a/src/app/Parent/parent.component.html b/src/app/Parent/parent.component.html index 6fc429c..c4e176c 100644 --- a/src/app/Parent/parent.component.html +++ b/src/app/Parent/parent.component.html @@ -1,9 +1,8 @@
-

Parent

-

Kontostand: {{ balance }}

- +

Parent

+

Kontostand: {{ balance }}

+ - - + +
- diff --git a/src/app/Parent/parent.component.ts b/src/app/Parent/parent.component.ts index 502bb94..f047ce0 100644 --- a/src/app/Parent/parent.component.ts +++ b/src/app/Parent/parent.component.ts @@ -1,6 +1,5 @@ -import { Component } from "@angular/core"; -import { ChildComponent } from "../Child/child.component"; - +import { Component } from '@angular/core'; +import { ChildComponent } from '../Child/child.component'; @Component({ selector: 'app-parent', diff --git a/src/app/Parent/services/hotel.service.ts b/src/app/Parent/services/hotel.service.ts index 2eb1125..c33687a 100644 --- a/src/app/Parent/services/hotel.service.ts +++ b/src/app/Parent/services/hotel.service.ts @@ -1,47 +1,47 @@ -import { Injectable } from "@angular/core"; -import { Hotel } from "../../HotelItem/hotel"; -import { from, Observable } from "rxjs"; +import { Injectable } from '@angular/core'; +import { Hotel } from '../../HotelItem/hotel'; +import { from, Observable } from 'rxjs'; @Injectable() export class HotelService { public getHotels(): Observable { return from([ { - "id": 1, - "hotelName": "Buea süßes Leben", - "description": "Schöne Aussicht am Meer", - "price": 230.5, - "imageUrl": "assets/img/1.jpg", - "rating": 3.5, - "tags": ["test"] + id: 1, + hotelName: 'Buea süßes Leben', + description: 'Schöne Aussicht am Meer', + price: 230.5, + imageUrl: 'assets/img/1.jpg', + rating: 3.5, + tags: ['test'], }, { - "id": 2, - "hotelName": "Marrakesch", - "description": "Genießen Sie den Blick auf die Berge", - "price": 145.5, - "imageUrl": "assets/img/2.jpg", - "rating": 5, - "tags": ["test"] + id: 2, + hotelName: 'Marrakesch', + description: 'Genießen Sie den Blick auf die Berge', + price: 145.5, + imageUrl: 'assets/img/2.jpg', + rating: 5, + tags: ['test'], }, { - "id": 3, - "hotelName": "Abuja neuer Palast", - "description": "Kompletter Aufenthalt mit Autoservice", - "price": 120.12, - "imageUrl": "assets/img/3.jpg", - "rating": 4, - "tags": ["test"] + id: 3, + hotelName: 'Abuja neuer Palast', + description: 'Kompletter Aufenthalt mit Autoservice', + price: 120.12, + imageUrl: 'assets/img/3.jpg', + rating: 4, + tags: ['test'], }, { - "id": 4, - "hotelName": "Kapstadt Stadt", - "description": "Wunderschönes Ambiente für Ihren Aufenthalt", - "price": 135.12, - "imageUrl": "assets/img/4.jpg", - "rating": 2.5, - "tags": ["test"] - } + id: 4, + hotelName: 'Kapstadt Stadt', + description: 'Wunderschönes Ambiente für Ihren Aufenthalt', + price: 135.12, + imageUrl: 'assets/img/4.jpg', + rating: 2.5, + tags: ['test'], + }, ]); } } diff --git a/src/app/Search/search.component.html b/src/app/Search/search.component.html index a408279..0cd8698 100644 --- a/src/app/Search/search.component.html +++ b/src/app/Search/search.component.html @@ -1 +1,6 @@ - + diff --git a/src/app/Search/search.component.ts b/src/app/Search/search.component.ts index c3564a0..c33d81d 100644 --- a/src/app/Search/search.component.ts +++ b/src/app/Search/search.component.ts @@ -1,8 +1,8 @@ -import { CommonModule } from "@angular/common"; -import { Component, NgModule } from "@angular/core"; -import { FormsModule, NgForm, NgModel } from "@angular/forms"; -import { Input, Output } from "@angular/core"; -import { EventEmitter } from "@angular/core"; +import { CommonModule } from '@angular/common'; +import { Component, NgModule } from '@angular/core'; +import { FormsModule, NgForm, NgModel } from '@angular/forms'; +import { Input, Output } from '@angular/core'; +import { EventEmitter } from '@angular/core'; @Component({ selector: 'app-search', @@ -11,7 +11,7 @@ import { EventEmitter } from "@angular/core"; imports: [FormsModule], }) export class SearchComponent { - @Input() public input: string = ""; + @Input() public input: string = ''; @Output() inputChange = new EventEmitter(); public update(e: string) { diff --git a/src/app/api/api.ts b/src/app/api/api.ts index b330010..3e83957 100644 --- a/src/app/api/api.ts +++ b/src/app/api/api.ts @@ -10,7 +10,6 @@ import { Hotel } from '../HotelItem/hotel'; * @implements {InMemoryDbService} */ export class HotelData implements InMemoryDbService { - createDb(): Record { const hotels: Hotel[] = [ { @@ -20,39 +19,43 @@ export class HotelData implements InMemoryDbService { price: 230.5, imageUrl: 'assets/img/1.jpg', rating: 3.5, - tags: ['nouveau'] - }, { + tags: ['nouveau'], + }, + { id: 2, hotelName: 'Marakech', description: 'Profitez de la vue sur les montagnes', price: 145.5, imageUrl: 'assets/img/2.jpg', rating: 5, - tags: ['nouveau'] - }, { + tags: ['nouveau'], + }, + { id: 3, hotelName: 'Abudja new look palace', description: 'Séjour complet avec service de voitures', price: 120.12, imageUrl: 'assets/img/3.jpg', rating: 4, - tags: ['nouveau'] - }, { + tags: ['nouveau'], + }, + { id: 4, hotelName: 'Cape town city', description: 'Magnifique cadre pour votre séjour', price: 135.12, imageUrl: 'assets/img/4.jpg', rating: 2.5, - tags: ['nouveau'] - } + tags: ['nouveau'], + }, ]; return { hotels }; } genId(hotels: Hotel[]): number { - return hotels.length > 0 ? Math.max(...hotels.map(hotel => hotel.id)) + 1 : 1; + return hotels.length > 0 + ? Math.max(...hotels.map((hotel) => hotel.id)) + 1 + : 1; } } - diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index c9898ba..b18bdaf 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -24,6 +24,8 @@ describe('AppComponent', () => { const fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, hotel-manager'); + expect(compiled.querySelector('h1')?.textContent).toContain( + 'Hello, hotel-manager', + ); }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 50508e2..a048be1 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,7 +1,13 @@ import { Component, Injectable } from '@angular/core'; import { HotelItem } from './HotelItem/HotelItem.component'; import { SearchComponent } from './Search/search.component'; -import { AsyncPipe, NgFor, NgForOf, NgIf, UpperCasePipe } from '@angular/common'; +import { + AsyncPipe, + NgFor, + NgForOf, + NgIf, + UpperCasePipe, +} from '@angular/common'; import { TextPipe } from '../text.pipe'; import { HotelService } from './Parent/services/hotel.service'; import { inject } from '@angular/core'; @@ -10,15 +16,23 @@ import { HttpClient } from '@angular/common/http'; import { Hotel } from './HotelItem/hotel'; import { RouterOutlet } from '@angular/router'; -@Injectable({providedIn: "root"}) +@Injectable({ providedIn: 'root' }) @Component({ selector: 'app-root', standalone: true, - imports: [RouterOutlet, 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' + styleUrl: './app.component.css', }) -export class AppComponent { -} - +export class AppComponent {} diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 55b7251..f3fc230 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,4 +1,8 @@ -import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'; +import { + ApplicationConfig, + importProvidersFrom, + provideZoneChangeDetection, +} from '@angular/core'; import { provideRouter } from '@angular/router'; import localeDe from '@angular/common/locales/de'; import localeCn from '@angular/common/locales/zh-Hans'; @@ -16,5 +20,6 @@ export const appConfig: ApplicationConfig = { provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient(), - importProvidersFrom(InMemoryWebApiModule.forRoot(HotelData))] + importProvidersFrom(InMemoryWebApiModule.forRoot(HotelData)), + ], }; diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index b316c2f..59cfcdf 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -6,19 +6,19 @@ import { NewHotelComponent } from './new-hotel/new-hotel.component'; export const routes: Routes = [ { - path: "", + path: '', component: HotelListComponent, }, { - path: "hotels/:id", + path: 'hotels/:id', component: HotelDetailsComponent, }, { - path: "testing", + path: 'testing', component: TestComponent, }, { - path: "new", + path: 'new', component: NewHotelComponent, - } + }, ]; diff --git a/src/app/crossValidator.service.ts b/src/app/crossValidator.service.ts index 8242487..d20931d 100644 --- a/src/app/crossValidator.service.ts +++ b/src/app/crossValidator.service.ts @@ -1,25 +1,11 @@ -import { AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from "@angular/forms"; +import { + AbstractControl, + FormGroup, + ValidationErrors, + ValidatorFn, +} from '@angular/forms'; export class CrossValidator { - public onlyAllowNameAndDescriptionSame() { - return (control: AbstractControl): ValidationErrors | null => { - if (!(control instanceof FormGroup)) { - return null; - } - - const name = control.get('name')?.value; - const description = control.get('description')?.value; - - console.log(name, description); - - const error = name !== description ? { mismatch: true } : null; - - console.log(error); - - return error; - }; - } - public crossValidate() { return (control: AbstractControl): ValidationErrors | null => { if (!(control instanceof FormGroup)) { @@ -28,7 +14,23 @@ export class CrossValidator { const contactType = control.get('contactType')?.value; - if (contactType == "None") return null; - } + if (contactType == ('None' || null)) return null; + + let error = null; + if (contactType == 'Email') { + error = + control.get('email')?.value != control.get('emailConfirmation')?.value + ? { mismatchEmail: true } + : null; + } else { + error = + control.get('phone')?.value != control.get('phoneConfirmation')?.value + ? { mismatchPhone: true } + : null; + } + + console.log('Error: ', error); + return error; + }; } } diff --git a/src/app/hotel-details/hotel-details.component.spec.ts b/src/app/hotel-details/hotel-details.component.spec.ts index 94047d9..c2c4a29 100644 --- a/src/app/hotel-details/hotel-details.component.spec.ts +++ b/src/app/hotel-details/hotel-details.component.spec.ts @@ -8,9 +8,8 @@ describe('HotelDetailsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [HotelDetailsComponent] - }) - .compileComponents(); + imports: [HotelDetailsComponent], + }).compileComponents(); fixture = TestBed.createComponent(HotelDetailsComponent); component = fixture.componentInstance; diff --git a/src/app/hotel-details/hotel-details.component.ts b/src/app/hotel-details/hotel-details.component.ts index 5adc141..e2a7f56 100644 --- a/src/app/hotel-details/hotel-details.component.ts +++ b/src/app/hotel-details/hotel-details.component.ts @@ -11,35 +11,51 @@ import { HotelFormComponent } from '../hotel-form/hotel-form.component'; @Component({ selector: 'app-hotel-details', standalone: true, - imports: [CurrencyPipe, StarRatingComponent, HotelItem, HotelFormComponent, NgIf, NgForOf], + imports: [ + CurrencyPipe, + StarRatingComponent, + HotelItem, + HotelFormComponent, + NgIf, + NgForOf, + ], templateUrl: './hotel-details.component.html', - styleUrl: './hotel-details.component.css' + styleUrl: './hotel-details.component.css', }) export class HotelDetailsComponent implements OnInit { public hotel: any; - constructor(private route: ActivatedRoute, private http: HttpClient, private router: Router) { } + constructor( + private route: ActivatedRoute, + private http: HttpClient, + private router: Router, + ) {} delete(): void { - if (confirm("Are u sure u want to delete this hotel")) { - this.http.delete("/api/hotels/" + this.route.snapshot.paramMap.get("id")).subscribe(); - this.router.navigate(["/"]); + if (confirm('Are u sure u want to delete this hotel')) { + this.http + .delete('/api/hotels/' + this.route.snapshot.paramMap.get('id')) + .subscribe(); + this.router.navigate(['/']); } } ngOnInit(): void { const routeParams = this.route.snapshot.paramMap; - const hotelId = routeParams.get("id"); + const hotelId = routeParams.get('id'); - this.http.get("api/hotels/" + hotelId).pipe( - catchError(() => { - alert("Not Found"); - this.router.navigate(["/"]); + this.http + .get('api/hotels/' + hotelId) + .pipe( + catchError(() => { + alert('Not Found'); + this.router.navigate(['/']); - return EMPTY; - }) - ).subscribe(res => { - this.hotel = res; - }) + return EMPTY; + }), + ) + .subscribe((res) => { + this.hotel = res; + }); } } diff --git a/src/app/hotel-form/hotel-form.component.html b/src/app/hotel-form/hotel-form.component.html index 21ccabc..1278b19 100644 --- a/src/app/hotel-form/hotel-form.component.html +++ b/src/app/hotel-form/hotel-form.component.html @@ -1,18 +1,47 @@

hotel-form works!

-

{{errorMsg}}

+

{{ errorMsg }}

-
{{ errorMessages['name'] }}
- +
+ {{ errorMessages["name"] }} +
+ -
{{ errorMessages['description'] }}
- +
+ {{ errorMessages["description"] }} +
+ -
{{ errorMessages['price'] }}
- - +
+ {{ errorMessages["price"] }} +
+ + 😭 Cancel
diff --git a/src/app/hotel-form/hotel-form.component.spec.ts b/src/app/hotel-form/hotel-form.component.spec.ts index 3f1f5bd..49ce8c2 100644 --- a/src/app/hotel-form/hotel-form.component.spec.ts +++ b/src/app/hotel-form/hotel-form.component.spec.ts @@ -8,9 +8,8 @@ describe('HotelFormComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [HotelFormComponent] - }) - .compileComponents(); + imports: [HotelFormComponent], + }).compileComponents(); fixture = TestBed.createComponent(HotelFormComponent); component = fixture.componentInstance; diff --git a/src/app/hotel-form/hotel-form.component.ts b/src/app/hotel-form/hotel-form.component.ts index 0ca2da5..e11fdad 100644 --- a/src/app/hotel-form/hotel-form.component.ts +++ b/src/app/hotel-form/hotel-form.component.ts @@ -1,6 +1,12 @@ import { Component, Input } from '@angular/core'; import { Hotel } from '../HotelItem/hotel'; -import { AbstractControl, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { + AbstractControl, + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; import { NgFor, NgIf } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { Router, RouterLink } from '@angular/router'; @@ -10,43 +16,50 @@ import { Router, RouterLink } from '@angular/router'; standalone: true, imports: [ReactiveFormsModule, NgIf, NgFor, RouterLink], templateUrl: './hotel-form.component.html', - styleUrl: './hotel-form.component.css' + styleUrl: './hotel-form.component.css', }) export class HotelFormComponent { @Input() public hotel!: Hotel; - public hotelForm!: FormGroup + public hotelForm!: FormGroup; public errorMsg: string = 'testing'; errorMessages: Record = {}; - constructor(public http: HttpClient, public router: Router) { - - } + constructor( + public http: HttpClient, + public router: Router, + ) {} private validationErrorMessages: Record = { - required: "This field is required", - minlength: "The value is too short", - maxlength: "The value is too long", - pattern: "The value format is incorrect" + required: 'This field is required', + minlength: 'The value is too short', + maxlength: 'The value is too long', + pattern: 'The value format is incorrect', }; setMessage(value: AbstractControl): void { if ((value.touched || value.dirty) && value.errors) { - this.errorMsg = Object.keys(value.errors).map(key => { - console.log(this.validationErrorMessages[key]); - return this.validationErrorMessages[key] || `Unknown error: ${key}`; - }).join(' '); + this.errorMsg = Object.keys(value.errors) + .map((key) => { + console.log(this.validationErrorMessages[key]); + return this.validationErrorMessages[key] || `Unknown error: ${key}`; + }) + .join(' '); } } updateErrorMessages(): void { this.errorMessages = {}; - Object.keys(this.hotelForm.controls).forEach(field => { + Object.keys(this.hotelForm.controls).forEach((field) => { const control = this.hotelForm.get(field); if (control && control.errors) { this.errorMessages[field] = Object.keys(control.errors) - .map(errorKey => this.validationErrorMessages[errorKey] || `Unknown error: ${errorKey}`) + .map( + (errorKey) => + this.validationErrorMessages[errorKey] || + `Unknown error: ${errorKey}`, + ) .join(' '); } }); @@ -67,11 +80,11 @@ export class HotelFormComponent { } submit(): void { - this.hotel.hotelName = this.hotelForm.get("name")?.value; - this.hotel.description = this.hotelForm.get("description")?.value; - this.hotel.price = this.hotelForm.get("price")?.value; + this.hotel.hotelName = this.hotelForm.get('name')?.value; + this.hotel.description = this.hotelForm.get('description')?.value; + this.hotel.price = this.hotelForm.get('price')?.value; console.log(this.hotelForm.value); - this.http.put("/api/hotels/" + this.hotel.id, this.hotel).subscribe(); - this.router.navigate(["/"]); + this.http.put('/api/hotels/' + this.hotel.id, this.hotel).subscribe(); + this.router.navigate(['/']); } } diff --git a/src/app/hotel-list/hotel-list.component.html b/src/app/hotel-list/hotel-list.component.html index 8d727a9..91d0a92 100644 --- a/src/app/hotel-list/hotel-list.component.html +++ b/src/app/hotel-list/hotel-list.component.html @@ -1,10 +1,13 @@
-

{{'hello' | uppercase | text}}

+

{{ "hello" | uppercase | text }}

CREATE NEW HOTEL @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 index ecc4715..ffeec64 100644 --- a/src/app/hotel-list/hotel-list.component.spec.ts +++ b/src/app/hotel-list/hotel-list.component.spec.ts @@ -8,9 +8,8 @@ describe('HotelListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [HotelListComponent] - }) - .compileComponents(); + imports: [HotelListComponent], + }).compileComponents(); fixture = TestBed.createComponent(HotelListComponent); component = fixture.componentInstance; diff --git a/src/app/hotel-list/hotel-list.component.ts b/src/app/hotel-list/hotel-list.component.ts index 6da0006..d95fce8 100644 --- a/src/app/hotel-list/hotel-list.component.ts +++ b/src/app/hotel-list/hotel-list.component.ts @@ -17,41 +17,50 @@ interface User { @Component({ selector: 'app-hotel-list', standalone: true, - imports: [UpperCasePipe, TextPipe, SearchComponent, HotelItem, NgFor, NgIf, RouterLink], + imports: [ + UpperCasePipe, + TextPipe, + SearchComponent, + HotelItem, + NgFor, + NgIf, + RouterLink, + ], templateUrl: './hotel-list.component.html', - styleUrl: './hotel-list.component.css' + styleUrl: './hotel-list.component.css', }) export class HotelListComponent { - public search: string = ""; + public search: string = ''; public hotelService: HotelService = inject(HotelService); public response: any = null; public hotels: Array = [{} as Hotel]; - constructor (private http: HttpClient) { - } + constructor(private http: HttpClient) {} ngOnInit() { - this.http.get>("api/hotels").subscribe(res => { + 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 }, - ] + { 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); + 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"]); diff --git a/src/app/new-hotel/new-hotel.component.html b/src/app/new-hotel/new-hotel.component.html index c2ae134..42fdd73 100644 --- a/src/app/new-hotel/new-hotel.component.html +++ b/src/app/new-hotel/new-hotel.component.html @@ -1,59 +1,120 @@

Create Hotel

-
{{ errorMessages['form'] }}
+
+ {{ errorMessages["form"] }} +
-
{{ errorMessages['name'] }}
- +
+ {{ errorMessages["name"] }} +
+ -
{{ errorMessages['description'] }}
- +
+ {{ errorMessages["description"] }} +
+ -
{{ errorMessages['imageUrl'] }}
- +
+ {{ errorMessages["imageUrl"] }} +
+ -
{{ errorMessages['price'] }}
- +
+ {{ errorMessages["price"] }} +
+ -
{{ errorMessages['rating'] }}
- +
+ {{ errorMessages["rating"] }} +
+ @for (tag of getTags().controls; track tag) { - - + + } - None - Email - SMS + None + Email + SMS @if (hotelForm.get("contactType")?.value == "Email") { -
- - - - -
+
+ + + + +
} @if (hotelForm.get("contactType")?.value == "SMS") { -
- - - - -
+
+ + + + +
} - + Cancel
diff --git a/src/app/new-hotel/new-hotel.component.spec.ts b/src/app/new-hotel/new-hotel.component.spec.ts index 33b658c..458edbb 100644 --- a/src/app/new-hotel/new-hotel.component.spec.ts +++ b/src/app/new-hotel/new-hotel.component.spec.ts @@ -8,9 +8,8 @@ describe('NewHotelComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [NewHotelComponent] - }) - .compileComponents(); + imports: [NewHotelComponent], + }).compileComponents(); fixture = TestBed.createComponent(NewHotelComponent); component = fixture.componentInstance; diff --git a/src/app/new-hotel/new-hotel.component.ts b/src/app/new-hotel/new-hotel.component.ts index 103e99f..e5d2daf 100644 --- a/src/app/new-hotel/new-hotel.component.ts +++ b/src/app/new-hotel/new-hotel.component.ts @@ -1,6 +1,13 @@ import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; -import { AbstractControl, FormArray, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { + AbstractControl, + FormArray, + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; import { Router, RouterLink } from '@angular/router'; import { Hotel } from '../HotelItem/hotel'; import { NgFor, NgIf } from '@angular/common'; @@ -11,41 +18,46 @@ import { CrossValidator } from '../crossValidator.service'; standalone: true, imports: [ReactiveFormsModule, NgIf, NgFor, RouterLink], templateUrl: './new-hotel.component.html', - styleUrl: './new-hotel.component.css' + styleUrl: './new-hotel.component.css', }) export class NewHotelComponent { - public hotelForm!: FormGroup - public hotel!: Hotel + public hotelForm!: FormGroup; + public hotel!: Hotel; errorMessages: Record = {}; private validationErrorMessages: Record = { - required: "This field is required", - minlength: "The value is too short", - maxlength: "The value is too long", - pattern: "The value format is incorrect" + required: 'This field is required', + minlength: 'The value is too short', + maxlength: 'The value is too long', + pattern: 'The value format is incorrect', }; private fullFormValidationErrorMessages: Record = { - mismatch: "The name and description have to be the same", - } + mismatch: 'The name and description have to be the same', + }; updateErrorMessages(): void { this.errorMessages = {}; - Object.keys(this.hotelForm.controls).forEach(field => { + Object.keys(this.hotelForm.controls).forEach((field) => { const control = this.hotelForm.get(field); if (control && control.errors && control.touched) { this.errorMessages[field] = Object.keys(control.errors) - .map(errorKey => this.validationErrorMessages[errorKey] || `Unknown error: ${errorKey}`) + .map( + (errorKey) => + this.validationErrorMessages[errorKey] || + `Unknown error: ${errorKey}`, + ) .join(' '); } }); - if (this.hotelForm.errors) { - Object.keys(this.hotelForm.errors).forEach(errorKey => { - const errorMessage = this.fullFormValidationErrorMessages[errorKey] || `Unknown error: ${errorKey}`; + Object.keys(this.hotelForm.errors).forEach((errorKey) => { + const errorMessage = + this.fullFormValidationErrorMessages[errorKey] || + `Unknown error: ${errorKey}`; this.errorMessages['form'] = errorMessage; }); } @@ -60,27 +72,29 @@ export class NewHotelComponent { tags.push(new FormControl(tag, [Validators.required])); } - - this.hotelForm = new FormGroup({ - name: new FormControl("", Validators.required), - description: new FormControl("", Validators.required), - price: new FormControl(0, Validators.required), - imageUrl: new FormControl("", Validators.required), - rating: new FormControl(0, Validators.required), - contactType: new FormControl('None'), - email: new FormControl(''), - emailConfirmation: new FormControl(''), - phone: new FormControl(''), - phoneConfirmation: new FormControl(''), - tags: new FormArray(tags) - }, { validators: new CrossValidator().onlyAllowNameAndDescriptionSame() }) + this.hotelForm = new FormGroup( + { + name: new FormControl('', Validators.required), + description: new FormControl('', Validators.required), + price: new FormControl(0, Validators.required), + imageUrl: new FormControl('', Validators.required), + rating: new FormControl(0, Validators.required), + contactType: new FormControl('None'), + email: new FormControl(''), + emailConfirmation: new FormControl(''), + phone: new FormControl(''), + phoneConfirmation: new FormControl(''), + tags: new FormArray(tags), + }, + { validators: new CrossValidator().crossValidate() }, + ); this.hotelForm.valueChanges.subscribe(() => this.updateErrorMessages()); this.hotelForm.valueChanges.subscribe(() => this.formUpdated()); } formUpdated() { - console.log(this.hotelForm.get("contactType")?.value); + console.log(this.hotelForm.get('contactType')?.value); } getTags() { @@ -91,27 +105,27 @@ export class NewHotelComponent { this.getTags().removeAt(this.getTags().controls.indexOf(tagElement)); } - addTag() { this.getTags().push(new FormControl('', [Validators.required])); } - constructor(public http: HttpClient, public router: Router) { - - } + constructor( + public http: HttpClient, + public router: Router, + ) {} submit(): void { console.log(this.hotelForm.value); const hotel: Hotel = { id: 0, - hotelName: this.hotelForm.get("name")?.value, - description: this.hotelForm.get("description")?.value, - price: this.hotelForm.get("price")?.value, - imageUrl: this.hotelForm.get("imageUrl")?.value, - rating: this.hotelForm.get("rating")?.value, - tags: this.hotelForm.get("tags")?.value - } - this.http.post("/api/hotels/", hotel).subscribe(); - this.router.navigate(["/"]); + hotelName: this.hotelForm.get('name')?.value, + description: this.hotelForm.get('description')?.value, + price: this.hotelForm.get('price')?.value, + imageUrl: this.hotelForm.get('imageUrl')?.value, + rating: this.hotelForm.get('rating')?.value, + tags: this.hotelForm.get('tags')?.value, + }; + this.http.post('/api/hotels/', hotel).subscribe(); + this.router.navigate(['/']); } } diff --git a/src/app/star-rating/star-rating.component.spec.ts b/src/app/star-rating/star-rating.component.spec.ts index f9778b3..ab87615 100644 --- a/src/app/star-rating/star-rating.component.spec.ts +++ b/src/app/star-rating/star-rating.component.spec.ts @@ -8,9 +8,8 @@ describe('StarRatingComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [StarRatingComponent] - }) - .compileComponents(); + imports: [StarRatingComponent], + }).compileComponents(); fixture = TestBed.createComponent(StarRatingComponent); component = fixture.componentInstance; diff --git a/src/app/star-rating/star-rating.component.ts b/src/app/star-rating/star-rating.component.ts index 2a0fdf3..bba79d8 100644 --- a/src/app/star-rating/star-rating.component.ts +++ b/src/app/star-rating/star-rating.component.ts @@ -6,7 +6,7 @@ import { Component, Input } from '@angular/core'; standalone: true, imports: [NgClass, NgFor], templateUrl: './star-rating.component.html', - styleUrl: './star-rating.component.css' + styleUrl: './star-rating.component.css', }) export class StarRatingComponent { @Input() public rating: number = 0; diff --git a/src/app/test/test.component.html b/src/app/test/test.component.html index f0778f5..193b9c3 100644 --- a/src/app/test/test.component.html +++ b/src/app/test/test.component.html @@ -2,9 +2,14 @@
- + - +
diff --git a/src/app/test/test.component.spec.ts b/src/app/test/test.component.spec.ts index d233ca5..ed2384b 100644 --- a/src/app/test/test.component.spec.ts +++ b/src/app/test/test.component.spec.ts @@ -8,9 +8,8 @@ describe('TestComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [TestComponent] - }) - .compileComponents(); + imports: [TestComponent], + }).compileComponents(); fixture = TestBed.createComponent(TestComponent); component = fixture.componentInstance; diff --git a/src/app/test/test.component.ts b/src/app/test/test.component.ts index bf2a97a..a844d05 100644 --- a/src/app/test/test.component.ts +++ b/src/app/test/test.component.ts @@ -6,7 +6,7 @@ import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; standalone: true, imports: [ReactiveFormsModule], templateUrl: './test.component.html', - styleUrl: './test.component.css' + styleUrl: './test.component.css', }) export class TestComponent { public loginForm!: FormGroup; @@ -19,8 +19,8 @@ export class TestComponent { setUpLoginForm(): FormGroup { return new FormGroup({ - username: new FormControl("Jan"), - password: new FormControl('') + username: new FormControl('Jan'), + password: new FormControl(''), }); } diff --git a/src/currency.pipe.ts b/src/currency.pipe.ts index 353920a..35cbcf3 100644 --- a/src/currency.pipe.ts +++ b/src/currency.pipe.ts @@ -1,11 +1,11 @@ -import {Pipe, PipeTransform} from '@angular/core'; +import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'jkcurrency', - standalone: true + standalone: true, }) export class CurrencyPipe implements PipeTransform { transform(value: string): string { - return value.replaceAll("L", "P"); + return value.replaceAll('L', 'P'); } } diff --git a/src/index.html b/src/index.html index 639aa9b..ca1f2f5 100644 --- a/src/index.html +++ b/src/index.html @@ -1,14 +1,14 @@ - - - HotelManager - - - - - - - - + + + HotelManager + + + + + + + + diff --git a/src/main.ts b/src/main.ts index 35b00f3..8882c45 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,5 +2,6 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; -bootstrapApplication(AppComponent, appConfig) - .catch((err) => console.error(err)); +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err), +); diff --git a/src/styles.css b/src/styles.css index cea93df..ba14716 100644 --- a/src/styles.css +++ b/src/styles.css @@ -8,17 +8,17 @@ } .input-field { - @apply border-red-500 text-3xl rounded-full bg-gray-500 font-bold p-3 m-3 border-8 + @apply border-red-500 text-3xl rounded-full bg-gray-500 font-bold p-3 m-3 border-8; } .back-button { - @apply border-black rounded bg-blue-500 border-[30px] m-3 text-3xl font-bold p-3 + @apply border-black rounded bg-blue-500 border-[30px] m-3 text-3xl font-bold p-3; } .submit-button { - @apply border-black rounded-full bg-green-500 border-[30px] m-3 text-3xl font-bold p-3 + @apply border-black rounded-full bg-green-500 border-[30px] m-3 text-3xl font-bold p-3; } .delete-button { - @apply border-black rounded bg-red-500 border-[30px] m-3 text-3xl font-bold p-3 + @apply border-black rounded bg-red-500 border-[30px] m-3 text-3xl font-bold p-3; } diff --git a/src/text.pipe.ts b/src/text.pipe.ts index cccbe4e..6355c79 100644 --- a/src/text.pipe.ts +++ b/src/text.pipe.ts @@ -1,11 +1,11 @@ -import {Pipe, PipeTransform} from '@angular/core'; +import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'text', - standalone: true + standalone: true, }) export class TextPipe implements PipeTransform { transform(value: string): string { - return value.replaceAll("L", "P"); + return value.replaceAll('L', 'P'); } } diff --git a/tailwind.config.js b/tailwind.config.js index 154e026..0a71a8e 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,11 +1,9 @@ /** @type {import('tailwindcss').Config} */ -const colors = require('tailwindcss/colors'); +const colors = require("tailwindcss/colors"); module.exports = { - content: [ - "./src/**/*.{html,ts}", - ], + content: ["./src/**/*.{html,ts}"], theme: { extend: { colors: { @@ -13,16 +11,15 @@ module.exports = { }, keyframes: { shake: { - '0%, 100%': { transform: 'translateX(0)' }, - '25%': { transform: 'translateX(-30px)' }, - '75%': { transform: 'translateX(30px)' }, + "0%, 100%": { transform: "translateX(0)" }, + "25%": { transform: "translateX(-30px)" }, + "75%": { transform: "translateX(30px)" }, }, }, animation: { - shake: 'shake 10s ease-in-out infinite', + shake: "shake 10s ease-in-out infinite", }, }, }, plugins: [], -} - +}; diff --git a/tsconfig.app.json b/tsconfig.app.json index 3775b37..8886e90 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -6,10 +6,6 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": [ - "src/main.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/tsconfig.json b/tsconfig.json index a9ae8b0..87b1c0c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,10 +18,7 @@ "importHelpers": true, "target": "ES2022", "module": "ES2022", - "lib": [ - "ES2022", - "dom" - ] + "lib": ["ES2022", "dom"] }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 5fb748d..e00e30e 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -4,12 +4,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": [ - "jasmine" - ] + "types": ["jasmine"] }, - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] }