feat(store-home): implement resolver for product data and enhance component logic for improved error handling and loading states

This commit is contained in:
2026-07-08 16:04:11 -03:00
parent efa0d48a40
commit 6c00a3e2bb
8 changed files with 285 additions and 136 deletions

View File

@@ -1,20 +1,32 @@
<div class="product-card border rounded shadow-sm bg-white overflow-hidden d-flex flex-column h-100">
<div
class="product-card border rounded shadow-sm bg-white overflow-hidden d-flex flex-column h-100"
>
<!-- 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" />
@if (imageUrl(); as imageSrc) {
<img
[ngSrc]="imageSrc"
[alt]="title()"
[priority]="imagePriority()"
fill
sizes="(min-width: 1200px) 25vw, (min-width: 768px) 50vw, 100vw"
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>
@@ -26,11 +38,15 @@
<!-- Prices Area -->
<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>
<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>
@@ -47,4 +63,4 @@
</app-button>
</div>
</div>
</div>
</div>

View File

@@ -1,13 +1,14 @@
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
import { NgOptimizedImage } from '@angular/common';
import { ButtonComponent } from '../button/button.component';
@Component({
selector: 'app-product-card',
standalone: true,
imports: [ButtonComponent],
imports: [ButtonComponent, NgOptimizedImage],
templateUrl: './product-card.component.html',
styleUrl: './product-card.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProductCardComponent {
// Configurable inputs
@@ -17,6 +18,7 @@ export class ProductCardComponent {
readonly discount = input<number | null>(null);
readonly transferPrice = input<number | null>(null);
readonly buttonText = input<string>('Comprar');
readonly imagePriority = input<boolean>(false);
// Interactive events
readonly buy = output<void>();