feat: add star rating component and integrate it in HotelItem
This commit is contained in:
parent
ee61ef13db
commit
e8683dad06
@ -7,4 +7,4 @@
|
|||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<img src="{{hotel.imageUrl}}" alt="Hotel">
|
<img src="{{hotel.imageUrl}}" alt="Hotel">
|
||||||
<p class="border-b border-black">{{hotel.rating}}</p>
|
<app-star-rating [rating]="hotel.rating"></app-star-rating>
|
||||||
|
@ -4,12 +4,13 @@ import { Input } from "@angular/core";
|
|||||||
import { Hotel } from "./hotel";
|
import { Hotel } from "./hotel";
|
||||||
import { CurrencyPipe } from "@angular/common";
|
import { CurrencyPipe } from "@angular/common";
|
||||||
import { FormsModule } from "@angular/forms";
|
import { FormsModule } from "@angular/forms";
|
||||||
|
import { StarRatingComponent } from "../star-rating/star-rating.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-hotel-item',
|
selector: 'app-hotel-item',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
templateUrl: './HotelItem.component.html',
|
templateUrl: './HotelItem.component.html',
|
||||||
imports: [ChildComponent, CurrencyPipe, FormsModule],
|
imports: [ChildComponent, CurrencyPipe, FormsModule, StarRatingComponent],
|
||||||
})
|
})
|
||||||
export class HotelItem {
|
export class HotelItem {
|
||||||
@Input() public hotel!: Hotel;
|
@Input() public hotel!: Hotel;
|
||||||
|
0
src/app/star-rating/star-rating.component.css
Normal file
0
src/app/star-rating/star-rating.component.css
Normal file
139
src/app/star-rating/star-rating.component.html
Normal file
139
src/app/star-rating/star-rating.component.html
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex flex-inline">
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating > 0 && rating < 1) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating >= 1) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-inline">
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating > 1 && rating < 2) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating >= 2) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-inline">
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating > 2 && rating < 3) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating >= 3) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-inline">
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating > 3 && rating < 4) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating >= 4) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-inline">
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating > 4 && rating < 5) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
[ngClass]="{ 'hidden': !(rating >= 5) }"
|
||||||
|
class="w-4 h-4 text-yellow-300 me-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 22 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<p class="ms-1 text-sm font-medium text-gray-500 dark:text-gray-400">
|
||||||
|
{{ rating }}
|
||||||
|
</p>
|
||||||
|
<p class="ms-1 text-sm font-medium text-gray-500 dark:text-gray-400">
|
||||||
|
out of
|
||||||
|
</p>
|
||||||
|
<p class="ms-1 text-sm font-medium text-gray-500 dark:text-gray-400">5</p>
|
||||||
|
</div>
|
23
src/app/star-rating/star-rating.component.spec.ts
Normal file
23
src/app/star-rating/star-rating.component.spec.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { StarRatingComponent } from './star-rating.component';
|
||||||
|
|
||||||
|
describe('StarRatingComponent', () => {
|
||||||
|
let component: StarRatingComponent;
|
||||||
|
let fixture: ComponentFixture<StarRatingComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [StarRatingComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(StarRatingComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
19
src/app/star-rating/star-rating.component.ts
Normal file
19
src/app/star-rating/star-rating.component.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { NgClass } from '@angular/common';
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-star-rating',
|
||||||
|
standalone: true,
|
||||||
|
imports: [NgClass],
|
||||||
|
templateUrl: './star-rating.component.html',
|
||||||
|
styleUrl: './star-rating.component.css'
|
||||||
|
})
|
||||||
|
export class StarRatingComponent {
|
||||||
|
@Input() public rating: number = 0;
|
||||||
|
public stars: number[] = [];
|
||||||
|
|
||||||
|
public setRating(rating: number) {
|
||||||
|
this.rating = rating;
|
||||||
|
this.stars = Array(rating).fill(0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user