This commit is contained in:
csimonis 2024-09-17 10:18:51 +02:00
parent 763d01d561
commit 27feb24461
11 changed files with 186 additions and 7 deletions

View file

@ -0,0 +1 @@

View file

@ -3,13 +3,15 @@ import {Child1Component} from "./child/child-1/child-1.component";
import {Child2Component} from "./child/child-2/child-2.component"; import {Child2Component} from "./child/child-2/child-2.component";
import {ParentComponent} from "./child/parent/parent.component"; import {ParentComponent} from "./child/parent/parent.component";
import {HotelsComponent} from "./hotel/hotels.component"; import {HotelsComponent} from "./hotel/hotels.component";
import {IdkComponent} from "./idek/idk.component";
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
standalone: true, standalone: true,
imports: [Child1Component, Child2Component, ParentComponent, HotelsComponent], imports: [Child1Component, Child2Component, ParentComponent, HotelsComponent, IdkComponent],
template: ` template: `
<app-hotels></app-hotels> <app-hotels></app-hotels>
<app-idk></app-idk>
` `
}) })
export class AppComponent { export class AppComponent {

View file

@ -1,8 +1,14 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; 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 {registerLocaleData} from "@angular/common";
import localeDe from "@angular/common/locales/de"
import localeCn from "@angular/common/locales/en"
import localeJap from "@angular/common/locales/en"
registerLocaleData(localeDe, 'de-DE')
registerLocaleData(localeCn, 'cn-CN')
registerLocaleData(localeJap, 'ja-JP')
export const appConfig: ApplicationConfig = { export const appConfig: ApplicationConfig = {
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)] providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
}; };

View file

@ -1,21 +1,30 @@
import {Component, Input} from "@angular/core"; import {Component, Input} from "@angular/core";
import {Hotel} from "./hotel" import {Hotel} from "./hotel"
import {CurrencyPipe} from "@angular/common";
import {Lang} from "../idek/lang";
import {StarComponent} from "../star/star.component";
@Component({ @Component({
standalone: true, standalone: true,
selector: 'app-hotel', selector: 'app-hotel',
imports: [
CurrencyPipe,
StarComponent
],
template: ` template: `
<div style="border: white 2px; border-radius: 2px"> <div style="border: white 2px; border-radius: 2px">
<p class="name">Name: {{hotel.hotelName}}</p> <p class="name">Name: {{ hotel.hotelName }}</p>
<p>Beschreibung: {{hotel.description}}</p> <p>Beschreibung: {{ hotel.description }}</p>
<p>Preis: {{hotel.price}}/nacht</p> <p>Preis: {{ hotel.price | currency: currency.currency : 'symbol' : '2.2-2' : currency.code }}/nacht</p>
<p>Sterne: {{hotel.rating}}/5</p> <p>Sterne: <app-star [rating]="hotel.rating"></app-star></p>
<img width="64" height="64" src="{{hotel.imageUrl}}"> <img width="64" height="64" src="{{hotel.imageUrl}}">
</div> </div>
` `
}) })
export class HotelComponent { export class HotelComponent {
@Input()
public currency: Lang = {name: 'de', code: 'de-DE', currency: 'EUR'}
@Input() @Input()
public hotel!: Hotel; public hotel!: Hotel;
} }

View file

@ -2,15 +2,21 @@ import {Component} from "@angular/core";
import {HotelComponent} from "./hotel.component"; import {HotelComponent} from "./hotel.component";
import {Hotel} from "./hotel"; import {Hotel} from "./hotel";
import {FormsModule} from "@angular/forms"; import {FormsModule} from "@angular/forms";
import {Lang} from "../idek/lang";
@Component({ @Component({
standalone: true, standalone: true,
template: ` template: `
<select [ngModel]="currency" (ngModelChange)="setCurrency($event)">
@for (currency of currencies; track null) {
<option value="{{currency.name}}">{{currency.name}}</option>
}
</select>
<form> <form>
<input name="search" [ngModel]="search" (ngModelChange)="searchEvent($event)"> <input name="search" [ngModel]="search" (ngModelChange)="searchEvent($event)">
</form> </form>
@for (hotel of matchingHotels; track hotel.hotelId) { @for (hotel of matchingHotels; track hotel.hotelId) {
<app-hotel [hotel]="hotel"></app-hotel> <app-hotel [hotel]="hotel" [currency]="currency"></app-hotel>
<hr> <hr>
} @empty { } @empty {
<h1>no matching results for {{search}}</h1> <h1>no matching results for {{search}}</h1>
@ -22,12 +28,46 @@ import {FormsModule} from "@angular/forms";
export class HotelsComponent { export class HotelsComponent {
public search: string = ''; public search: string = '';
public currency: Lang = {name: 'de', code: 'de-DE', currency: 'EUR'};
public currencies: Lang[] = [
{
name: 'de',
code: 'de-DE',
currency: 'EUR'
},
{
name: 'en',
code: 'en-US',
currency: 'USD'
},
{
name: 'jap',
code: 'ja-JP',
currency: 'JPY'
},
{
name: 'cn',
code: 'cn-CN',
currency: 'CNY'
}
]
public matchingHotels: Hotel[] = []; public matchingHotels: Hotel[] = [];
constructor() { constructor() {
this.matchingHotels = this.hotels; this.matchingHotels = this.hotels;
} }
public setCurrency(currencyInput: string): void {
for (const currency of this.currencies) {
if (currency.name === currencyInput) {
this.currency = currency;
break;
}
}
}
public searchEvent(input: string) { public searchEvent(input: string) {
this.search = input.toLowerCase(); this.search = input.toLowerCase();
this.matchingHotels = [] this.matchingHotels = []

View file

@ -0,0 +1,54 @@
import {Component} from "@angular/core";
import {CurrencyPipe, UpperCasePipe} from "@angular/common";
import {TestPipe} from "./test.pipe";
import {FormsModule} from "@angular/forms";
import {Lang} from "./lang";
@Component({
selector: 'app-idk',
standalone: true,
imports: [UpperCasePipe, TestPipe, CurrencyPipe, FormsModule],
template: `
<select [ngModel]="currency" (ngModelChange)="setCurrency($event)">
@for (currency of currencies; track null) {
<option value="{{currency.name}}">{{currency.name}}</option>
}
</select>
{{ 234 | currency : currency.currency : 'symbol' : '2.2-2' : currency.code }}
`
})
export class IdkComponent {
public currency: Lang = {name: 'de', code: 'de-DE', currency: 'EUR'};
public currencies: Lang[] = [
{
name: 'de',
code: 'de-DE',
currency: 'EUR'
},
{
name: 'en',
code: 'en-US',
currency: 'USD'
},
{
name: 'jap',
code: 'ja-JP',
currency: 'JPY'
},
{
name: 'cn',
code: 'cn-CN',
currency: 'CNY'
}
]
public setCurrency(currencyInput: string): void {
for (const currency of this.currencies) {
if (currency.name === currencyInput) {
this.currency = currency;
break;
}
}
}
}

5
src/app/idek/lang.ts Normal file
View file

@ -0,0 +1,5 @@
export interface Lang {
code: string;
name: string;
currency: string;
}

11
src/app/idek/test.pipe.ts Normal file
View file

@ -0,0 +1,11 @@
import {Pipe, PipeTransform} from "@angular/core";
@Pipe({
name: 'idk',
standalone: true,
})
export class TestPipe implements PipeTransform {
transform(value: string): string {
return value.toLowerCase().replaceAll('l', 'p');
}
}

View file

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { StarComponent } from './star.component';
describe('StarComponent', () => {
let component: StarComponent;
let fixture: ComponentFixture<StarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [StarComponent]
})
.compileComponents();
fixture = TestBed.createComponent(StarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,27 @@
import {Component, Input} from '@angular/core';
@Component({
selector: 'app-star',
standalone: true,
imports: [],
template: `
@for (_ of getList(); track null) {
test
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="m5.825 21l1.625-7.025L2 9.25l7.2-.625L12 2l2.8 6.625l7.2.625l-5.45 4.725L18.175 21L12 17.275z"/></svg>
}
@if (rating % 1 >= 0.5) {
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="m15.15 16.85l-.825-3.6l2.775-2.4l-3.65-.325l-1.45-3.4v7.8zM5.825 21l1.625-7.025L2 9.25l7.2-.625L12 2l2.8 6.625l7.2.625l-5.45 4.725L18.175 21L12 17.275z"/></svg>
}
`,
})
export class StarComponent {
@Input()
public rating: number = 0;
public getList(): null[] {
console.log(this.rating)
console.log(Array(this.rating).fill(null))
return Array(this.rating).fill(null);
}
}

View file

@ -8,6 +8,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js" integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js" integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap-grid.min.css" integrity="sha512-i1b/nzkVo97VN5WbEtaPebBG8REvjWeqNclJ6AItj7msdVcaveKrlIIByDpvjk5nwHjXkIqGZscVxOrTb9tsMA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap-grid.min.css" integrity="sha512-i1b/nzkVo97VN5WbEtaPebBG8REvjWeqNclJ6AItj7msdVcaveKrlIIByDpvjk5nwHjXkIqGZscVxOrTb9tsMA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/4.0.0/iconfont/material-icons.min.css" referrerpolicy="no-referrer" />
</head> </head>
<body> <body>
<app-root></app-root> <app-root></app-root>