fix(storefront): add missing placeholder image asset and onerror fallback

getMainImage() referenced /assets/images/placeholder.svg as the no-image
fallback, but src/assets/images/ never existed - any item with zero
photos rendered a browser broken-image icon instead of a placeholder.
Added the asset.

Also added an (error) handler (onImageError) on every dynamic <img> that
renders a user/admin-supplied URL (product card, cart line item, cart
payment QR code, product gallery main + thumbnails) so a 404'd/broken
image URL swaps to the shared placeholder instead of shipping broken.
This commit is contained in:
sdarbinyan
2026-07-26 00:12:43 +04:00
parent 6c6fa00ccf
commit 3e54e88db7
8 changed files with 29 additions and 8 deletions

View File

@@ -31,7 +31,7 @@
}
@default {
<img [src]="media[selectedIndex].url" [alt]="media[selectedIndex].alt" loading="eager" decoding="async" />
<img [src]="media[selectedIndex].url" [alt]="media[selectedIndex].alt" loading="eager" decoding="async" (error)="onImageError($event)" />
}
}
</div>
@@ -45,7 +45,7 @@
} @else if (item.type !== 'image') {
<span class="product-gallery-doc">{{ item.type }}</span>
}
<img [src]="item.thumbnailUrl" [alt]="item.alt + ' ' + ($index + 1)" loading="lazy" decoding="async" />
<img [src]="item.thumbnailUrl" [alt]="item.alt + ' ' + ($index + 1)" loading="lazy" decoding="async" (error)="onImageError($event)" />
</button>
}
</div>

View File

@@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { Product } from '../../../../../core/products/models/product-domain.model';
import { getMainImage } from '../../../../../utils/item.utils';
import { getMainImage, onImageError } from '../../../../../utils/item.utils';
import { TranslatePipe } from '../../../../../i18n/translate.pipe';
type ProductMediaType = 'image' | 'video' | 'pdf' | 'manual' | 'warranty';
@@ -22,6 +22,8 @@ interface GalleryMediaItem {
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProductGalleryComponent {
readonly onImageError = onImageError;
@Input({ required: true }) product!: Product;
@Input() selectedIndex = 0;