From 1890b50e0d95dbfad9b4f179d0a41a20d3951360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=85=E2=80=9A=20Miczek?= Date: Sat, 17 Oct 2026 13:29:41 +0200 Subject: [PATCH] Add shop skeleton loading and subtle reveal animations. Co-authored-by: Cursor --- .../src/app/features/cart/cart.component.html | 24 ++++-- .../src/app/features/cart/cart.component.ts | 12 ++- .../src/app/features/home/home.component.html | 33 ++++++-- .../src/app/features/home/home.component.ts | 19 ++++- .../products/product-detail.component.html | 61 +++++++++++--- .../products/product-detail.component.ts | 16 +++- .../products/product-list.component.html | 16 +++- .../products/product-list.component.ts | 14 +++- .../shared/cart-added-modal.component.html | 2 +- .../shared/product-card-skeleton.component.ts | 32 ++++++++ src/shop/src/styles.css | 80 +++++++++++++++++++ 11 files changed, 274 insertions(+), 35 deletions(-) create mode 100644 src/shop/src/app/shared/product-card-skeleton.component.ts diff --git a/src/shop/src/app/features/cart/cart.component.html b/src/shop/src/app/features/cart/cart.component.html index adb1fe5..40aceb4 100644 --- a/src/shop/src/app/features/cart/cart.component.html +++ b/src/shop/src/app/features/cart/cart.component.html @@ -243,16 +243,28 @@

{{ 'common.loading' | translate }}

} - @if (recommended().length > 0) { + @if (recommendedLoading() || recommended().length > 0) {

{{ 'cart.recommended' | translate }}

-
- @for (product of recommended(); track product.id) { - - } -
+ @if (recommendedLoading()) { +
+ @for (i of recommendedSkeletonSlots; track i) { + + } +
+ } @else { +
+ @for (product of recommended(); track product.id) { + + } +
+ }
} diff --git a/src/shop/src/app/features/cart/cart.component.ts b/src/shop/src/app/features/cart/cart.component.ts index c92c46a..2549147 100644 --- a/src/shop/src/app/features/cart/cart.component.ts +++ b/src/shop/src/app/features/cart/cart.component.ts @@ -24,6 +24,7 @@ import { ShellComponent, ProductCardComponent, } from '../../shared/layout/layout.components'; +import { ProductCardSkeletonComponent } from '../../shared/product-card-skeleton.component'; import { FreeShippingBarComponent } from '../../shared/free-shipping-bar.component'; import { CartService, CatalogService } from '../../core/shop.services'; import { ProductListItem } from '../../core/models'; @@ -34,6 +35,7 @@ import { ProductListItem } from '../../core/models'; imports: [ ShellComponent, ProductCardComponent, + ProductCardSkeletonComponent, FreeShippingBarComponent, FormsModule, I18nCurrencyPipe, @@ -56,6 +58,8 @@ export class CartPageComponent { readonly i18n = this.#i18n; readonly cart = this.#cart.cart; readonly recommended = signal([]); + readonly recommendedLoading = signal(true); + readonly recommendedSkeletonSlots = [0, 1, 2, 3]; discountCode = ''; readonly discountMessage = signal(''); readonly error = signal(''); @@ -67,11 +71,15 @@ export class CartPageComponent { effect(() => { this.#i18n.locale(); this.#cart.load(); + this.recommendedLoading.set(true); this.#catalog.getProducts({ pageSize: 8 }).subscribe({ - next: (res) => + next: (res) => { this.recommended.set( res.items.filter((p) => p.isInStock).slice(0, 4), - ), + ); + this.recommendedLoading.set(false); + }, + error: () => this.recommendedLoading.set(false), }); }); } diff --git a/src/shop/src/app/features/home/home.component.html b/src/shop/src/app/features/home/home.component.html index 202b793..33c3afd 100644 --- a/src/shop/src/app/features/home/home.component.html +++ b/src/shop/src/app/features/home/home.component.html @@ -18,7 +18,8 @@