diff --git a/src/app/shared/components/product-list/product-list.component.html b/src/app/shared/components/product-list/product-list.component.html
index 77ccb6d..c3e9ff2 100644
--- a/src/app/shared/components/product-list/product-list.component.html
+++ b/src/app/shared/components/product-list/product-list.component.html
@@ -3,7 +3,7 @@
[class.product-list--row]="layout() === 'row'"
[class.product-list--column]="layout() !== 'row'"
>
- @for (item of items(); track item.id; let index = $index) {
+ @for (item of items().data; track item.id; let index = $index) {
@switch (layout()) {
@case ('row') {
@@ -38,3 +38,14 @@
}
+
+@if (items().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 26febf5..4752a6a 100644
--- a/src/app/shared/components/product-list/product-list.component.scss
+++ b/src/app/shared/components/product-list/product-list.component.scss
@@ -25,3 +25,7 @@
min-width: 0;
}
}
+
+.product-list__paginator {
+ margin-top: 1.5rem;
+}
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 f1a5031..bd969c5 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
@@ -1,7 +1,8 @@
import { TestBed, getTestBed } from '@angular/core/testing';
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
-import { afterEach, beforeAll, describe, expect, it } from 'vitest';
+import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
+import { ApiPaginatedResponse } from '../../../core/services/api-paginated-response.interface';
import { ProductListComponent, ProductListItem, ProductListLayout } from './product-list.component';
describe('ProductListComponent', () => {
@@ -38,12 +39,34 @@ describe('ProductListComponent', () => {
await TestBed.configureTestingModule({ imports: [ProductListComponent] }).compileComponents();
const fixture = TestBed.createComponent(ProductListComponent);
fixture.componentRef.setInput('layout', layout);
- fixture.componentRef.setInput('items', items);
+ fixture.componentRef.setInput('items', paginatedItems());
fixture.detectChanges();
return fixture;
}
+ function paginatedItems(currentPage = 1, lastPage = 2): ApiPaginatedResponse {
+ return {
+ data: items,
+ meta: {
+ current_page: currentPage,
+ from: 1,
+ last_page: lastPage,
+ links: [],
+ path: '/catalog/featured-groups/1/items',
+ per_page: 12,
+ to: 2,
+ total: 13,
+ },
+ links: {
+ first: '/catalog/featured-groups/1/items?page=1',
+ last: '/catalog/featured-groups/1/items?page=2',
+ prev: null,
+ next: '/catalog/featured-groups/1/items?page=2',
+ },
+ };
+ }
+
it('renders every row product at full available width', async () => {
const fixture = await render('row');
const element = fixture.nativeElement as HTMLElement;
@@ -70,4 +93,17 @@ describe('ProductListComponent', () => {
),
).toHaveLength(2);
});
+
+ it('renders pagination and emits the requested page', async () => {
+ const fixture = await render('row');
+ const pageChangeSpy = vi.fn();
+ fixture.componentInstance.pageChange.subscribe(pageChangeSpy);
+
+ const nextButton = (fixture.nativeElement as HTMLElement).querySelector(
+ '[data-testid="paginator-next"]',
+ ) as HTMLButtonElement;
+ nextButton.click();
+
+ expect(pageChangeSpy).toHaveBeenCalledWith(2);
+ });
});
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 8e0b399..af3ed5d 100644
--- a/src/app/shared/components/product-list/product-list.component.ts
+++ b/src/app/shared/components/product-list/product-list.component.ts
@@ -1,5 +1,7 @@
import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';
+import { ApiPaginatedResponse } from '../../../core/services/api-paginated-response.interface';
+import { PaginatorComponent } from '../paginator/paginator.component';
import { ProductColumnWithImageComponent } from '../product-column-with-image/product-column-with-image.component';
import {
ProductRowCardComponent,
@@ -35,6 +37,7 @@ export interface ProductListCartEvent {
selector: 'app-product-list',
imports: [
ProductColumnWithImageComponent,
+ PaginatorComponent,
ProductRowCardComponent,
ProductVerticalWithCartCardComponent,
],
@@ -44,10 +47,12 @@ export interface ProductListCartEvent {
})
export class ProductListComponent {
readonly layout = input.required();
- readonly items = input.required();
+ readonly items = input.required>();
+ readonly loading = input(false);
readonly buy = output();
readonly addToCart = output();
+ readonly pageChange = output();
protected price(item: ProductListItem): number {
const price = Number(item.precio);