diff --git a/src/app/features/store/pages/store-home-page/store-home-page.component.html b/src/app/features/store/pages/store-home-page/store-home-page.component.html index f3e0759..da12b25 100644 --- a/src/app/features/store/pages/store-home-page/store-home-page.component.html +++ b/src/app/features/store/pages/store-home-page/store-home-page.component.html @@ -18,6 +18,7 @@ - @for (item of itemData(); track item.id; let index = $index) { -
- @switch (effectiveLayout()) { - @case ('row') { - - } - @case ('column_with_cart') { - - } - @default { - - } + +
+ @switch (effectiveLayout()) { + @case ('row') { + } -
- } -
+ @case ('column_with_cart') { + + } + @default { + + } + } + + + +@if (groupLayout() === 'carousel') { + +} @else { +
+ @for (item of itemData(); track item.id; let index = $index) { + + } +
+} @if (pagination(); as paginatedItems) { @if (paginatedItems.meta.last_page > 1) { diff --git a/src/app/shared/components/product-list/product-list.component.scss b/src/app/shared/components/product-list/product-list.component.scss index 3788053..c7f95b8 100644 --- a/src/app/shared/components/product-list/product-list.component.scss +++ b/src/app/shared/components/product-list/product-list.component.scss @@ -32,6 +32,15 @@ &__item { min-width: 0; + + &--carousel { + width: clamp(15rem, 30vw, 18rem); + height: 100%; + } + + &--carousel-row { + width: clamp(18rem, 70vw, 32rem); + } } } diff --git a/src/app/shared/components/product-list/product-list.component.spec.ts b/src/app/shared/components/product-list/product-list.component.spec.ts index cb72da0..90baa90 100644 --- a/src/app/shared/components/product-list/product-list.component.spec.ts +++ b/src/app/shared/components/product-list/product-list.component.spec.ts @@ -3,7 +3,10 @@ import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform- import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; import { ApiPaginatedResponse } from '../../../core/services/api-paginated-response.interface'; -import { CatalogFeaturedItems } from '../../../core/services/catalog/catalog.interface'; +import { + CatalogFeaturedItems, + CatalogGroupLayout, +} from '../../../core/services/catalog/catalog.interface'; import { ProductListComponent, ProductListItem, ProductListLayout } from './product-list.component'; describe('ProductListComponent', () => { @@ -42,10 +45,12 @@ describe('ProductListComponent', () => { async function render( layout: ProductListLayout, productItems: CatalogFeaturedItems = paginatedItems(), + groupLayout: CatalogGroupLayout = 'paginated', ) { await TestBed.configureTestingModule({ imports: [ProductListComponent] }).compileComponents(); const fixture = TestBed.createComponent(ProductListComponent); fixture.componentRef.setInput('layout', layout); + fixture.componentRef.setInput('groupLayout', groupLayout); fixture.componentRef.setInput('items', productItems); fixture.detectChanges(); @@ -134,10 +139,21 @@ describe('ProductListComponent', () => { }); it('renders plain items without pagination', async () => { - const fixture = await render('row', items); + const fixture = await render('row', items, 'simple'); const element = fixture.nativeElement as HTMLElement; expect(element.querySelectorAll('app-product-row-card')).toHaveLength(2); expect(element.querySelector('app-paginator')).toBeNull(); }); + + it('renders carousel groups with the reusable carousel', async () => { + const fixture = await render('column_with_image', items, 'carousel'); + const element = fixture.nativeElement as HTMLElement; + + expect(element.querySelector('app-carousel')).not.toBeNull(); + expect(element.querySelector('.product-list')).toBeNull(); + expect(element.querySelectorAll('app-product-column-with-image')).toHaveLength(2); + expect(element.querySelectorAll('.product-list__item--carousel')).toHaveLength(2); + expect(element.querySelector('app-paginator')).toBeNull(); + }); }); diff --git a/src/app/shared/components/product-list/product-list.component.ts b/src/app/shared/components/product-list/product-list.component.ts index f267faa..4f97f77 100644 --- a/src/app/shared/components/product-list/product-list.component.ts +++ b/src/app/shared/components/product-list/product-list.component.ts @@ -9,13 +9,16 @@ import { output, signal, } from '@angular/core'; +import { NgTemplateOutlet } from '@angular/common'; import { CatalogFeaturedItem, CatalogFeaturedItems, CatalogFeaturedItemVariant, + CatalogGroupLayout, CatalogProductLayout, } from '../../../core/services/catalog/catalog.interface'; +import { CarouselComponent } from '../carousel/carousel.component'; import { PaginatorComponent } from '../paginator/paginator.component'; import { ProductColumnWithImageComponent } from '../product-column-with-image/product-column-with-image.component'; import { @@ -37,6 +40,8 @@ export interface ProductListCartEvent { @Component({ selector: 'app-product-list', imports: [ + CarouselComponent, + NgTemplateOutlet, ProductColumnWithImageComponent, PaginatorComponent, ProductRowCardComponent, @@ -51,6 +56,7 @@ export class ProductListComponent { private readonly mobile = signal(false); readonly layout = input.required(); + readonly groupLayout = input.required(); readonly items = input.required(); readonly loading = input(false); @@ -71,6 +77,7 @@ export class ProductListComponent { return Array.isArray(items) ? null : items; }); + protected readonly trackProduct = (_index: number, item: ProductListItem): number => item.id; constructor() { afterNextRender(() => {