Shopping Cart
# Cart
This. **Introduction**
The-l-van/app/main/components/cart-page-content.tsx)
- [app/shop/cart/page.tsx](https://github.com/h/h/frontend-l-van/blob/main/app/shop/cart/page.tsx)
- [store/cart.store.ts://github.com/h/2/frontend-l- /blob/main/store/cart.store)
- [feature/cart/hooks/use-cart.ts://github. com/h/2/front-l- /blob/main/feature/cart/hook/use-cart.ts)
- [feature/cart/service/cart.service.ts://github. com/h/2/frontend-l- /blob/main/feature/cart/service/cart.service)
- [feature/cart/utils/index.ts://github.com/h/2/0-l- /blob/main/feature/cart/utils/index.tsx)
- [feature/db/types/index.ts://github.com/2/0-l- /blob/main/feature/cart/types/types/index.ts)
- [feature/ds/components/cart-item.tsx://github.com/2/0-l- /blob/main/feature/components/cart-item.tsx)
- [feature/cart/components/cart-summary.tsx://github.com/2/0-l- /blob/main/feature/cart/components/cart-summary.tsx)
- [feature/cart/service/cart.service.spec://github.com/2/0-l- /blob/main/feature/service/cart.service)
- [feature/checkout/hook/use-checkout.ts://github. com/2/0-l- /blob/main/feature/checkout/hook/use-checkout.tsx)
- [feature/checkout/components/order-summary.tsx://github. com/2/0-l- /blob/main/feature/order/components/order-summary.tsx)
- [feature/checkout/components/order-view.tsx://github.com/2/0-l- /blob/main/feature/order/components/order-view.tsx)
- [app/admin/products/new/page.tsx://github. com/2/0-l- /blob/main/app/admin/product/new/page.tsx)
- [app/admin/product/id]/edit/edit/page.tsx://github. com/2/0-l- /blob/main/app/admin/product/id/edit/page.tsx)
- [e2e/checkout-checkout.spec://github.com/2/0-l- /blob/main/e2e/checkout-checkout.spec)
- [types/index.ts://github. com/2/0-l- /blob/main/type/index.ts)
- [types/order.ts://github.com/2/0-l- /blob/main/type/cart.ts)
- [store/cart.store.ts://github. com/2/0-l- /blob/main/store/cart.store)
- [lib/cart/service/cart.service.spec.ts://github.com-l- /blob/main/feature/cart/service/cart.service.spec.ts)
- [e2e/checkout-checkout.spec://github. com/2/0-l- /blob/main/e2e/checkout-checkout.spec)
- [feature/checkout/hook/use-cart.spec://github. com/2/0-l- /blob/main/feature/cart/hook/use-cart.spec.tsx)
- [feature/checkout/service/checkout.service.spec.ts://github. com/2/0-l- /blob/main/feature/checkout/service/checkout.service.spec.ts)
- [README/cart/utils/index.ts://github. com/2/0-l- /blob/main/feature/utils/index.tsx)
- [README/cart/components/cart-content.tsx://github. com/2/0-l- /blob/main/cart/components/cart-content.tsx)
- [README/shop/cart/page.tsx](https://github.com/hngo232/frontend-l-van/blob/main/app/%28shop%29/cart/page.tsx)
- [e2e/checkout-flow.spec.ts](https://github.com/hngo232/frontend-l-van/blob/main/e2e/checkout-flow.spec.ts)
- [features/cart/components/cart-item.tsx](https://github.com/hngo232/frontend-l-van/blob/main/features/cart/components/cart-item.tsx)
- [features/cart/components/cart-summary.tsx](https://github.com/hngo232/frontend-l-van/blob/main/features/cart/components/cart-summary.tsx)
- [features/cart/hooks/use-cart.spec.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/cart/hooks/use-cart.spec.ts)
- [features/cart/hooks/use-cart.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/cart/hooks/use-cart.ts)
- [features/cart/services/cart.service.spec.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/cart/services/cart.service.spec.ts)
- [features/cart/services/cart.service.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/cart/services/cart.service.ts)
- [features/cart/utils/index.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/cart/utils/index.ts)
- [features/checkout/components/checkout-content.tsx](https://github.com/hngo232/frontend-l-van/blob/main/features/checkout/components/checkout-content.tsx)
- [features/checkout/hooks/use-checkout.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/checkout/hooks/use-checkout.ts)
- [features/checkout/services/checkout.service.spec.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/checkout/services/checkout.service.spec.ts)
- [features/checkout/services/checkout.service.ts](https://github.com/hngo232/frontend-l-van/blob/main/features/checkout/services/checkout.service.ts)
- [features/order/components/order-summary.tsx](https://github.com/hngo232/frontend-l-van/blob/main/features/order/components/order-summary.tsx)
- [features/order/components/order-view.tsx](https://github.com/hngo232/frontend-l-van/blob/main/features/order/components/order-view.tsx)
- [features/product/components/product-content.tsx](https://github.com/hngo232/frontend-l-van/blob/main/features/product/components/product-content.tsx)
- [store/cart.store.ts](https://github.com/hngo232/frontend-l-van/blob/main/store/cart.store.ts)
- [types/cart.ts](https://github.com/hngo232/frontend-l-van/blob/main/types/cart.ts)
- [types/index.ts](https://github.com/hngo232/frontend-l-van/blob/main/types/index.ts)
</summary>
</details>
# Shopping Cart
The shopping cart is a core feature of this e-commerce application, allowing users to collect products they intend to purchase. This document outlines the architecture, data flow, and key components of the shopping cart functionality.
## Architecture
The cart functionality is built using a combination of frontend components, state management with Zustand, and a backend API service.
### Directory Structure
The files related to the cart are organized as follows:
/
├── app/(shop)/cart/page.tsx # Cart page UI
├── features/
│ ├── cart/
│ │ ├── components/
│ │ │ ├── cart-item.tsx # Component for a single item in the cart
│ │ │ └── cart-summary.tsx # Component for the cart summary (total, etc.)
│ │ ├── hooks/
│ │ │ ├── use-cart.ts # Hook for cart state and actions
│ │ │ └── use-cart.spec.ts # Tests for use-cart hook
│ │ ├── services/
│ │ │ ├── cart.service.ts # Service for cart API calls
│ │ │ └── cart.service.spec.ts # Tests for cart.service
│ │ └── utils/
│ │ └── index.ts # Utility functions for the cart
│ ├── checkout/
│ │ ├── components/
│ │ │ └── checkout-content.tsx # Checkout page UI
│ │ ├── hooks/
│ │ │ └── use-checkout.ts # Hook for checkout logic
│ │ └── services/
│ │ ├── checkout.service.ts # Service for checkout API calls
│ │ └── checkout.service.spec.ts # Tests for checkout.service
│ └── order/
│ ├── components/
│ │ ├── order-summary.tsx # Component for order summary
│ │ └── order-view.tsx # Component to view a completed order
├── store/
│ └── cart.store.ts # Zustand store for cart state
└── types/
├── cart.ts # TypeScript types for the cart
└── index.ts # Common types
## Data Flow
### Adding an Item to the Cart
Viewing the Cart
Checkout Process
The checkout process is initiated from the cart page.
Key Components and Logic
useCart Hook
The useCart hook is the primary interface for interacting with the shopping cart from the UI. It provides the cart data, loading and error states, and functions to modify the cart.
- State:
cart: The current cart object (CartWithProducts).loading: Boolean indicating if a cart operation is in progress.error: String containing an error message if an operation fails.
- Actions:
fetchCart(): Fetches the user's cart from the backend.addItem(productId, quantity): Adds a product to the cart.updateItem(itemId, quantity): Updates the quantity of an item in the cart.removeItem(itemId): Removes an item from the cart.clearCart(): Removes all items from the cart.
- Derived State:
itemCount: Total number of items in the cart.total: Total price of all items in the cart.
Source: features/cart/hooks/use-cart.ts
cart.store.ts (Zustand Store)
This file defines the Zustand store for the cart. It holds the client-side state of the cart and provides actions to manipulate it. The useCart hook is built on top of this store.
The store manages cart, loading, and error states. Actions like fetchCart, addItem, updateItem, removeItem, and clearCart are defined here. They typically set the loading state, call the cart.service, and then update the cart or error state based on the API response.
Source: store/cart.store.ts
cart.service.ts
This service encapsulates all API interactions related to the cart. It uses a generic apiClient to make HTTP requests.
getCart():GET /api/cartaddItem(data):POST /api/cart/itemsupdateItem(data):PATCH /api/cart/itemsremoveItem(productId):DELETE /api/cart/itemsclearCart():DELETE /api/cart
It also includes a _unwrapCartWithProducts private method to transform the raw API response into the CartWithProducts type expected by the application.
Source: features/cart/services/cart.service.ts
checkout.service.ts
This service handles the logic for the checkout process.
validateCheckoutRequest(): Checks if the cart and address are valid before proceeding.processApiCheckout(): Handles checkout for payment methods that are processed on the server (e.g., COD). It creates an order via the API.processPaymentGateway(): Handles checkout for payment gateways. It creates an order and then a payment session, returning the necessary data for the client-side payment flow.
Source: features/checkout/services/checkout.service.ts
UI Components
CartPageContent: The main component for the/cartpage. It uses theuseCarthook to get cart data and rendersCartItemcomponents for each item and aCartSummarycomponent.
Source: features/cart/components/cart-page-content.tsxCartItem: Displays a single item in the cart, including product image, name, quantity, and price. It provides controls to update the quantity or remove the item.
Source: features/cart/components/cart-item.tsxCartSummary: Shows the subtotal, shipping, tax, and total amount for the cart. It includes the "Proceed to Checkout" button.
Source: features/cart/components/cart-summary.tsxCheckoutContent: The main component for the checkout page. It orchestrates address selection, payment method selection, and order placement using theuseCheckouthook.
Source: features/checkout/components/checkout-content.tsx
Data Models
The core data structures for the cart are defined in types/cart.ts.
| Type | Description |
|---|---|
Product | Basic product information. |
CartItem | An item in the cart, linking a product with a quantity. |
CartItemWithProduct | A CartItem with the full Product object embedded. |
Cart | The basic cart object, containing an array of CartItems. |
CartWithProducts | The cart object used in the frontend, with full product details in items. |
AddToCartRequest | The request payload for adding an item to the cart. |
UpdateCartItemRequest | The request payload for updating an item's quantity. |
Source: types/cart.ts
Testing
The cart feature has comprehensive testing coverage:
- Unit Tests:
use-cart.spec.ts: Tests the logic within theuseCarthook, mocking the Zustand store and auth state.cart.service.spec.ts: Tests the API service methods, mocking theapiClient.checkout.service.spec.ts: Tests the checkout service logic.
- End-to-End (E2E) Tests:
checkout-flow.spec.ts: Simulates a full user journey from adding a product to the cart to completing an order, using Playwright. This ensures all components and services work together correctly.
Sources: features/cart/hooks/use-cart.spec.ts, features/cart/services/cart.service.spec.ts, e2e/checkout-flow.spec.ts
Summary
The shopping cart is a well-structured and robust feature. It separates concerns effectively between UI components, state management, and API services. The use of a dedicated useCart hook provides a clean and simple API for components to interact with the cart, while the underlying Zustand store and services handle the complex logic of state management and backend communication. The checkout process builds upon the cart, guiding the user through the final steps of their purchase. Extensive unit and E2E tests ensure the reliability and correctness of the entire flow.