import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, inject } from '@angular/core'; import { DecimalPipe } from '@angular/common'; import { RouterLink } from '@angular/router'; import { Product } from '../../core/products/models/product-domain.model'; import { LangRoutePipe } from '../../pipes/lang-route.pipe'; import { TranslatePipe } from '../../i18n/translate.pipe'; import { CurrencyConvertPipe } from '../../pipes/currency-convert.pipe'; import { LanguageService } from '../../services/language.service'; import { cleanDescription, getBadgeClass, getDiscountedPrice, getMainImage, onImageError } from '../../utils/item.utils'; const STOCK_LABEL_KEYS: Record = { high: 'catalog.stockHigh', medium: 'catalog.stockMedium', low: 'catalog.stockLow', out: 'catalog.stockOut' }; export type ProductCardAppearance = 'standard' | 'compact'; @Component({ selector: 'app-product-card', standalone: true, imports: [DecimalPipe, RouterLink, LangRoutePipe, TranslatePipe, CurrencyConvertPipe], templateUrl: './product-card.component.html', styleUrls: ['./product-card.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ProductCardComponent { private readonly languageService = inject(LanguageService); readonly displayCurrency = this.languageService.currentCurrency; @Input({ required: true }) item!: Product; @Input() title = ''; @Input() description = ''; @Input() addToCartLabel = ''; @Input() appearance: ProductCardAppearance = 'standard'; @Input() showDescription = false; @Input() showStock = true; @Input() showRating = true; @Input() showDiscountBadge = true; @Input() showFavoritePlaceholder = false; @Input() showComparePlaceholder = false; @Input() showQuickViewPlaceholder = false; @Input() showFavoriteAction = false; @Input() showCompareAction = false; @Input() showShareAction = false; @Input() isFavorite = false; @Input() isCompared = false; @Output() addToCart = new EventEmitter<{ itemID: number; event: Event }>(); @Output() preview = new EventEmitter(); @Output() selected = new EventEmitter<{ itemID: number; event: Event }>(); @Output() favoritePlaceholder = new EventEmitter(); @Output() comparePlaceholder = new EventEmitter(); @Output() quickViewPlaceholder = new EventEmitter(); @Output() favoriteToggled = new EventEmitter(); @Output() compareToggled = new EventEmitter(); @Output() shareRequested = new EventEmitter(); readonly getMainImage = getMainImage; readonly getDiscountedPrice = getDiscountedPrice; readonly getBadgeClass = getBadgeClass; readonly cleanDescription = cleanDescription; readonly onImageError = onImageError; onAddToCart(event: Event): void { this.addToCart.emit({ itemID: this.item.itemID, event }); } onSelected(event: Event): void { this.selected.emit({ itemID: this.item.itemID, event }); } onFavoritePlaceholder(event: Event): void { event.preventDefault(); event.stopPropagation(); this.favoritePlaceholder.emit(this.item.itemID); this.favoriteToggled.emit(this.item.itemID); } onComparePlaceholder(event: Event): void { event.preventDefault(); event.stopPropagation(); this.comparePlaceholder.emit(this.item.itemID); this.compareToggled.emit(this.item.itemID); } onQuickViewPlaceholder(event: Event): void { event.preventDefault(); event.stopPropagation(); this.quickViewPlaceholder.emit(this.item.itemID); } onShare(event: Event): void { event.preventDefault(); event.stopPropagation(); this.shareRequested.emit(this.item.itemID); } stockLabelKey(remainings: string): string { return STOCK_LABEL_KEYS[remainings.toLowerCase()] ?? STOCK_LABEL_KEYS['high']; } showFavoriteControl(): boolean { return this.showFavoriteAction || this.showFavoritePlaceholder; } showCompareControl(): boolean { return this.showCompareAction || this.showComparePlaceholder; } }