feat(cart): implement add to cart functionality and display empty cart message

This commit is contained in:
2026-07-20 17:11:06 -03:00
parent 98e899c5bf
commit dafaa85480
8 changed files with 142 additions and 36 deletions

View File

@@ -21,6 +21,7 @@
[items]="group.items"
[loading]="isGroupLoading(group.id)"
(buy)="onBuyProduct($event)"
(addToCart)="onAddToCart($event)"
(pageChange)="onPageChange(group.id, $event)"
/>
</app-store-section>

View File

@@ -1,14 +1,18 @@
import { TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { Subject, of } from 'rxjs';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { ApiPaginatedResponse } from '../../../../core/services/api-paginated-response.interface';
import { CartService } from '../../../../core/services/cart/cart.service';
import {
CatalogFeaturedGroup,
CatalogFeaturedItem,
} from '../../../../core/services/catalog/catalog.interface';
import { CatalogService } from '../../../../core/services/catalog/catalog.service';
import { ToastService } from '../../../../core/services/toast.service';
import { ProductListComponent } from '../../../../shared/components/product-list/product-list.component';
import { StoreHomePageComponent } from './store-home-page.component';
import {
STORE_HOME_PRODUCTS_ERROR_MESSAGE,
@@ -213,4 +217,34 @@ describe('StoreHomePageComponent', () => {
'No pudimos cargar los productos en este momento.',
);
});
it('adds a product-list cart event to the cart', async () => {
const catalogServiceStub = { getCatalog: vi.fn(), getFeaturedGroupItems: vi.fn() };
const cartServiceStub = {
addItem: vi.fn().mockReturnValue(
of({ data: {}, message: 'Producto agregado correctamente' }),
),
};
const toastServiceStub = { success: vi.fn(), danger: vi.fn() };
await TestBed.configureTestingModule({
imports: [StoreHomePageComponent],
providers: [
provideActivatedRoute({ response: createCatalog(), error: null }),
{ provide: CatalogService, useValue: catalogServiceStub },
{ provide: CartService, useValue: cartServiceStub },
{ provide: ToastService, useValue: toastServiceStub },
],
}).compileComponents();
const fixture = TestBed.createComponent(StoreHomePageComponent);
fixture.detectChanges();
const productList = fixture.debugElement.query(By.directive(ProductListComponent))
.componentInstance as ProductListComponent;
productList.addToCart.emit({ product: pageOneItems[0], quantity: 3, variant: 12 });
expect(cartServiceStub.addItem).toHaveBeenCalledWith(1, 12, 3);
expect(toastServiceStub.success).toHaveBeenCalledWith('Producto agregado correctamente');
});
});

View File

@@ -6,14 +6,18 @@ import {
inject,
signal,
} from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { CartService } from '../../../../core/services/cart/cart.service';
import { CatalogFeaturedGroup } from '../../../../core/services/catalog/catalog.interface';
import { CatalogService } from '../../../../core/services/catalog/catalog.service';
import { TenantService } from '../../../../core/services/tenant.service';
import { ToastService } from '../../../../core/services/toast.service';
import {
ProductListComponent,
ProductListCartEvent,
ProductListItem,
} from '../../../../shared/components/product-list/product-list.component';
import { HeroBannerComponent } from '../../../../shared/components/hero-banner/hero-banner.component';
@@ -31,10 +35,12 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StoreHomePageComponent implements OnInit, OnDestroy {
private readonly cartService = inject(CartService);
private readonly catalogService = inject(CatalogService);
private readonly route = inject(ActivatedRoute);
private readonly router = inject(Router);
private readonly tenantService = inject(TenantService);
private readonly toastService = inject(ToastService);
protected readonly tenant = this.tenantService.tenant;
protected readonly catalog = signal<CatalogFeaturedGroup[]>([]);
@@ -105,6 +111,21 @@ export class StoreHomePageComponent implements OnInit, OnDestroy {
this.router.navigate(['/producto', product.id]);
}
protected onAddToCart(event: ProductListCartEvent): void {
this.cartService
.addItem(event.product.id, event.variant ?? null, event.quantity)
.subscribe({
next: (response) => {
this.toastService.success(response.message || 'Producto agregado al carrito');
},
error: (error: HttpErrorResponse) => {
const message =
error.error?.message || 'No se pudo agregar el producto al carrito.';
this.toastService.danger(message);
},
});
}
private loadCatalog(): void {
this.loading.set(true);
this.error.set(null);