feat: implement store home page with product listing, pagination, and error handling

This commit is contained in:
ncoronel 2026-06-30 08:47:57 -03:00
parent b2796a2383
commit 74144b6d2c
4 changed files with 36 additions and 12 deletions

View File

@ -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)
};
}

View File

@ -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[];
}

View File

@ -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,

View File

@ -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
}))
);