feat: add ProductCard component with currency formatting and price calculation logic

This commit is contained in:
2026-06-29 08:37:15 -03:00
parent d79d075c45
commit 77e4a22740
3 changed files with 19 additions and 19 deletions

View File

@@ -2,34 +2,35 @@
<!-- Image section --> <!-- Image section -->
<div class="product-card__image-container position-relative bg-light"> <div class="product-card__image-container position-relative bg-light">
@if (imageUrl()) { @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 { } @else {
<div class="product-card__image-placeholder w-100 h-100 d-flex align-items-center justify-content-center bg-light text-muted"> <div
<i class="fa-solid fa-image fa-2x"></i> class="product-card__image-placeholder w-100 h-100 d-flex align-items-center justify-content-center bg-light text-muted">
</div> <i class="fa-solid fa-image fa-2x"></i>
</div>
} }
<!-- Discount badge in top right --> <!-- Discount badge in top right -->
@if (discount() && discount()! > 0) { @if (discount() && discount()! > 0) {
<span class="product-card__discount-badge position-absolute top-0 end-0 bg-primary text-white px-2 py-1"> <span class="product-card__discount-badge position-absolute top-0 end-0 bg-primary text-white px-2 py-1">
-{{ discount() }}% -{{ discount() }}%
</span> </span>
} }
</div> </div>
<!-- Content section --> <!-- Content section -->
<div class="product-card__body p-3 d-flex flex-column align-items-center text-center flex-grow-1"> <div class="product-card__body p-3 d-flex flex-column align-items-center text-center flex-grow-1">
<!-- Product Title --> <!-- 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 --> <!-- 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 --> <!-- Discounted (computado) Price -->
<span class="product-card__price-discounted text-primary">{{ formattedDiscountedPrice() }}</span> <span class="product-card__price-discounted text-primary">{{ formattedDiscountedPrice() }}</span>
<!-- Original strikethrough Price (only if discount exists) --> <!-- Original strikethrough Price (only if discount exists) -->
@if (discount() && discount()! > 0) { @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> </div>
@@ -46,5 +47,4 @@
</app-button> </app-button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -6,7 +6,7 @@
.product-card { .product-card {
width: 100%; width: 100%;
height: 100%; max-height: 411px;
transition: transform 0.2s ease, box-shadow 0.2s ease; transition: transform 0.2s ease, box-shadow 0.2s ease;
&:hover { &:hover {
@@ -16,6 +16,7 @@
&__image-container { &__image-container {
width: 100%; width: 100%;
max-height: 50%;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
overflow: hidden; overflow: hidden;
} }
@@ -37,7 +38,7 @@
&__price-discounted { &__price-discounted {
color: var(--tenant-primary) !important; color: var(--tenant-primary) !important;
font-size: 24px; font-size: 24px;
font-weight: 425; font-weight: 700;
} }
@@ -53,7 +54,7 @@
} }
&__price-transfer-value { &__price-transfer-value {
font-weight: 400; font-weight: 700;
} }
&__price-transfer-label { &__price-transfer-label {
@@ -64,7 +65,7 @@
app-button { app-button {
display: block; display: block;
width: 100%; width: 100%;
::ng-deep .btn { ::ng-deep .btn {
width: 100%; width: 100%;
min-width: 100%; min-width: 100%;
@@ -72,5 +73,4 @@
} }
} }
} }
} }

View File

@@ -64,6 +64,6 @@ export class ProductCardComponent {
const rounded = Math.round(value); const rounded = Math.round(value);
const parts = rounded.toString().split('.'); const parts = rounded.toString().split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '.');
return `$ ${parts.join(',')}`; return `$${parts.join(',')}`;
} }
} }