feat: add ProductCard component with currency formatting and price calculation logic
This commit is contained in:
@@ -2,34 +2,35 @@
|
||||
<!-- Image section -->
|
||||
<div class="product-card__image-container position-relative bg-light">
|
||||
@if (imageUrl()) {
|
||||
<img [src]="imageUrl()" [alt]="title()" class="product-card__image w-100 h-100 object-fit-cover" />
|
||||
<img [src]="imageUrl()" [alt]="title()" class="product-card__image w-100 h-100 object-fit-cover" />
|
||||
} @else {
|
||||
<div class="product-card__image-placeholder w-100 h-100 d-flex align-items-center justify-content-center bg-light text-muted">
|
||||
<i class="fa-solid fa-image fa-2x"></i>
|
||||
</div>
|
||||
<div
|
||||
class="product-card__image-placeholder w-100 h-100 d-flex align-items-center justify-content-center bg-light text-muted">
|
||||
<i class="fa-solid fa-image fa-2x"></i>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Discount badge in top right -->
|
||||
@if (discount() && discount()! > 0) {
|
||||
<span class="product-card__discount-badge position-absolute top-0 end-0 bg-primary text-white px-2 py-1">
|
||||
-{{ discount() }}%
|
||||
</span>
|
||||
<span class="product-card__discount-badge position-absolute top-0 end-0 bg-primary text-white px-2 py-1">
|
||||
-{{ discount() }}%
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Content section -->
|
||||
<div class="product-card__body p-3 d-flex flex-column align-items-center text-center flex-grow-1">
|
||||
<!-- Product Title -->
|
||||
<h3 class="product-card__title text-uppercase text-black mb-3">{{ title() }}</h3>
|
||||
<h3 class="product-card__title text-uppercase text-black mb-4">{{ title() }}</h3>
|
||||
|
||||
<!-- Prices Area -->
|
||||
<div class="product-card__prices d-flex align-items-center justify-content-center gap-2 mb-2">
|
||||
<div class="product-card__prices d-flex align-items-center justify-content-center gap-2">
|
||||
<!-- Discounted (computado) Price -->
|
||||
<span class="product-card__price-discounted text-primary">{{ formattedDiscountedPrice() }}</span>
|
||||
|
||||
<!-- Original strikethrough Price (only if discount exists) -->
|
||||
@if (discount() && discount()! > 0) {
|
||||
<span class="product-card__price-original text-decoration-line-through">{{ formattedOriginalPrice() }}</span>
|
||||
<span class="product-card__price-original text-decoration-line-through">{{ formattedOriginalPrice() }}</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -46,5 +47,4 @@
|
||||
</app-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
.product-card {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 411px;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
&__image-container {
|
||||
width: 100%;
|
||||
max-height: 50%;
|
||||
aspect-ratio: 1 / 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -37,7 +38,7 @@
|
||||
&__price-discounted {
|
||||
color: var(--tenant-primary) !important;
|
||||
font-size: 24px;
|
||||
font-weight: 425;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +54,7 @@
|
||||
}
|
||||
|
||||
&__price-transfer-value {
|
||||
font-weight: 400;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
&__price-transfer-label {
|
||||
@@ -64,7 +65,7 @@
|
||||
app-button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
|
||||
::ng-deep .btn {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
@@ -72,5 +73,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -64,6 +64,6 @@ export class ProductCardComponent {
|
||||
const rounded = Math.round(value);
|
||||
const parts = rounded.toString().split('.');
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
||||
return `$ ${parts.join(',')}`;
|
||||
return `$${parts.join(',')}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user