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.
P0-5: some catalog listings (live backend data, proxied third-party
marketplace via novo.market) carry HTML-entity-encoded markup in
their description field, e.g. '<attention>...</attention>'
and '"AppStops"' — rendered verbatim as visible text on
search-result cards and the PDP description tab.
Added a pure cleanDescription() util (item.utils.ts) that decodes
the common HTML entities and strips any resulting tag-like markup,
then wired it into ProductCardComponent (covers Home/Catalog/Search/
Wishlist/Compare/PDP-similar) and ProductDescriptionComponent (PDP
description tab). Output stays a plain string rendered via text
interpolation (never innerHTML), so this only cleans up display —
it introduces no HTML-rendering/XSS surface.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
P0-1: stock badge rendered the raw item.remainings value ('High',
etc) untranslated on every product card sitewide. Now maps to
catalog.stockHigh/Medium/Low/Out via the translate pipe; the 'out'
class check is now case-insensitive to match.
P0-2: favorite/share/quick-view action-button aria-labels rendered
literal 'catalog.favorite'/'catalog.share'/'catalog.quickView' keys
because they never existed in translations.ts/en.ts/ru.ts/hy.ts
(only catalog.compare existed, and it was likewise unused). Added
all 4 keys to the Translations interface and all 3 locales.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>