From 74144b6d2cae1691a6d371b342e68db4a82e4db4 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Tue, 30 Jun 2026 08:47:57 -0300 Subject: [PATCH] feat: implement store home page with product listing, pagination, and error handling --- src/app/app.routes.spec.ts | 7 +++++ .../services/catalog/catalog.interface.ts | 10 ++++--- .../store-home-page.component.spec.ts | 27 ++++++++++++++----- .../store-home-page.component.ts | 4 +-- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/app/app.routes.spec.ts b/src/app/app.routes.spec.ts index e4ada11..ec7d978 100644 --- a/src/app/app.routes.spec.ts +++ b/src/app/app.routes.spec.ts @@ -31,6 +31,13 @@ function createTenantServiceStub( tenant: tenantState.asReadonly(), status: statusState.asReadonly(), getTenant: () => tenantState(), + getTenantApiUrl: () => { + const tenantVal = tenantState(); + if (!tenantVal) { + throw new Error('No se pudo resolver el tenant activo.'); + } + return `http://localhost:8000/api/tenants/${tenantVal.codigo}`; + }, bootstrap: vi.fn().mockResolvedValue(undefined) }; } diff --git a/src/app/core/services/catalog/catalog.interface.ts b/src/app/core/services/catalog/catalog.interface.ts index 0faebb2..ab5d17d 100644 --- a/src/app/core/services/catalog/catalog.interface.ts +++ b/src/app/core/services/catalog/catalog.interface.ts @@ -1,11 +1,13 @@ export interface Product { id: number; tenant_codigo: string; - categoria_id: number; + category_id: number; + brand_id: number | null; slug: string; nombre: string; - descripcion?: string; + descripcion: string; precio: string; - created_at?: string; - updated_at?: string; + category: string; + brand: string | null; + images: string[]; } diff --git a/src/app/features/store/pages/store-home-page/store-home-page.component.spec.ts b/src/app/features/store/pages/store-home-page/store-home-page.component.spec.ts index ffe3e59..4a6ba18 100644 --- a/src/app/features/store/pages/store-home-page/store-home-page.component.spec.ts +++ b/src/app/features/store/pages/store-home-page/store-home-page.component.spec.ts @@ -38,18 +38,28 @@ describe('StoreHomePageComponent', () => { { id: 1, tenant_codigo: 'test', - categoria_id: 10, + category_id: 10, + brand_id: null, slug: 'auriculares-bluetooth', nombre: 'Auriculares Bluetooth', - precio: '24999' + descripcion: 'Auriculares bluetooth de prueba', + precio: '24999', + category: 'Tecnología', + brand: null, + images: [] }, { id: 2, tenant_codigo: 'test', - categoria_id: 11, + category_id: 11, + brand_id: null, slug: 'teclado-mecanico', nombre: 'Teclado Mecanico', - precio: '18999' + descripcion: 'Teclado mecánico de prueba', + precio: '18999', + category: 'Tecnología', + brand: null, + images: [] } ]; @@ -97,10 +107,15 @@ describe('StoreHomePageComponent', () => { { id: 3, tenant_codigo: 'test', - categoria_id: 12, + category_id: 12, + brand_id: null, slug: 'mouse-gamer', nombre: 'Mouse Gamer', - precio: '15999' + descripcion: 'Mouse gamer de prueba', + precio: '15999', + category: 'Tecnología', + brand: null, + images: [] } ], 2, diff --git a/src/app/features/store/pages/store-home-page/store-home-page.component.ts b/src/app/features/store/pages/store-home-page/store-home-page.component.ts index f097236..ad7fd88 100644 --- a/src/app/features/store/pages/store-home-page/store-home-page.component.ts +++ b/src/app/features/store/pages/store-home-page/store-home-page.component.ts @@ -13,7 +13,7 @@ interface StoreHomeProductCardViewModel { originalPrice: number; discount: null; transferPrice: null; - imageUrl: null; + imageUrl: string | null; } @Component({ @@ -42,7 +42,7 @@ export class StoreHomePageComponent implements OnInit, OnDestroy { originalPrice: this.parseProductPrice(product.precio), discount: null, transferPrice: null, - imageUrl: null + imageUrl: product.images?.[0] ?? null })) );