Wishlist and Shopping Cart
Relevant source files
The following files were used as context for generating this wiki page:
- frontend/src/redux/actions/wishlist.js
- frontend/src/redux/actions/cart.js
- frontend/src/components/Wishlist/Wishlist.jsx
- frontend/src/components/cart/Cart.jsx
- frontend/src/components/Route/ProductCard/ProductCard.jsx
- frontend/src/components/Products/ProductDetails.jsx
- frontend/src/components/Layout/Header.jsx
- frontend/src/components/Route/ProductDetailsCard/ProductDetailsCard.jsx
The Wishlist and Shopping Cart are fundamental e-commerce features within the application, enabling users to save products for future consideration (Wishlist) or gather them for immediate purchase (Shopping Cart). Both systems are implemented entirely on the client-side, utilizing Redux for state management and the browser's localStorage to ensure data persistence across user sessions.
These features are integrated throughout the user interface, with access points in the main header, on product listing cards, and on product detail pages. The UI for both the cart and wishlist is presented as a slide-in side panel, providing a consistent and non-disruptive user experience.
Architecture and Data Flow
The core of the cart and wishlist functionality relies on a client-side architecture using Redux for state management. User interactions with products trigger Redux actions, which in turn update the application's state. This state is then synchronized with the browser's localStorage to persist the data.
State Management with Redux
The application state for the cart and wishlist is managed in separate slices of the Redux store. Actions are dispatched from various UI components to add, remove, or update items.
The general data flow for adding an item is as follows:
- A user clicks an "Add to Cart" or "Add to Wishlist" button in a component (e.g.,
ProductCard,ProductDetails). - The component's event handler dispatches a Redux action (e.g.,
addTocart,addToWishlist) with the product data. - The action creator dispatches an object with a
typeandpayloadto the Redux store. - The corresponding reducer handles the action, updating the
cartorwishlistarray in the state. - The action creator then updates
localStoragewith the new state, ensuring persistence. - Components subscribed to the Redux store (like
Header,Cart,Wishlist) re-render to reflect the updated state.
This diagram illustrates the Redux data flow for adding an item to the cart or wishlist.
Redux Actions
The following actions manage the state of the cart and wishlist.
| Action | File | Description |
|---|---|---|
addTocart | cart.js | Adds a product to the cart or updates its quantity. |
removeFromCart | cart.js | Removes a product from the cart based on its ID. |
addToWishlist | wishlist.js | Adds a product to the wishlist. |
removeFromWishlist | wishlist.js | Removes a product from the wishlist based on its ID. |
Sources: frontend/src/redux/actions/cart.js, frontend/src/redux/actions/wishlist.js
The actions are responsible for both dispatching the state change and persisting it to localStorage.
// frontend/src/redux/actions/wishlist.js
// add to wishlist
export const addToWishlist = (data) => async (dispatch, getState) => {
dispatch({
type: "addToWishlist",
payload: data,
});
localStorage.setItem("wishlistItems", JSON.stringify(getState().wishlist.wishlist));
return data;
};
Sources: frontend/src/redux/actions/wishlist.js:2-10
Shopping Cart
The Shopping Cart allows users to collect items for purchase. It is accessible via an icon in the Header and through "Add to cart" buttons on product cards and detail pages.
Core Components
| Component | File | Description |
|---|---|---|
Cart | Cart.jsx | The main slide-in panel that displays all items in the cart, the total price, and a link to checkout. |
CartSingle | Cart.jsx | Renders a single item within the cart, including controls for quantity and removal. |
Header | Header.jsx | Displays the cart icon with a badge showing the number of items and toggles the Cart panel. |
Sources: frontend/src/components/cart/Cart.jsx, frontend/src/components/Layout/Header.jsx
Functionality
Adding to Cart
When a user adds an item, the addToCartHandler function is called. This function first checks if the item already exists in the cart. If it does, a toast notification informs the user. It also checks if the product is in stock. If both checks pass, it dispatches the addTocart action.
// frontend/src/components/Route/ProductCard/ProductCard.jsx
const addToCartHandler = (id) => {
const isItemExists = cart && cart.find((i) => i.id == id);
if (isItemExists) {
toast.error("The product is already in the cart!");
} else {
if (data.stock < 1) {
toast.error("The product is out of stock!");
} else {
const cartData = { ...data, qty: 1 };
dispatch(addTocart(cartData));
toast.success("Added to cart!");
}
}
};
Sources: frontend/src/components/Route/ProductCard/ProductCard.jsx:58-71
Updating Quantity
Inside the Cart component, users can increment or decrement the quantity of an item. The increment and decrement functions in CartSingle dispatch the addTocart action with the updated quantity, which overwrites the existing item in the Redux store. The increment function also checks against the product's stock limit.
Sources: frontend/src/components/cart/Cart.jsx:89-105
Sequence Diagram: Add to Cart
This diagram shows the sequence of events when a user adds a product to the cart from a ProductCard.
Wishlist
The Wishlist allows users to save products they are interested in. It functions similarly to the cart, with its own state slice, actions, and UI panel.
Core Components
| Component | File | Description |
|---|---|---|
Wishlist | Wishlist.jsx | The main slide-in panel that displays all favorited items. |
CartSingle | Wishlist.jsx | This component is reused from the cart to display a single wishlist item. It provides options to remove the item or move it to the cart. |
Header | Header.jsx | Displays the wishlist heart icon with a badge showing the item count and toggles the Wishlist panel. |
Sources: frontend/src/components/Wishlist/Wishlist.jsx, frontend/src/components/Layout/Header.jsx
Functionality
Adding and Removing from Wishlist
Users can add or remove items from their wishlist using a heart icon, typically found on ProductCard and ProductDetails pages. The toggleWishlist function checks if the item is already in the wishlist and dispatches either addToWishlist or removeFromWishlist accordingly.
// frontend/src/components/Products/ProductDetails.jsx
const toggleWishlist = () => {
setClick(!click);
click ? dispatch(removeFromWishlist(data)) : dispatch(addToWishlist(data));
};
Sources: frontend/src/components/Products/ProductDetails.jsx:35-38
Moving Item from Wishlist to Cart
The Wishlist panel provides a feature to move an item directly to the shopping cart. The addToCartHandler in Wishlist.jsx dispatches the addTocart action for the selected item and then closes the wishlist panel.
// frontend/src/components/Wishlist/Wishlist.jsx
const addToCartHandler = (data) => {
const newData = { ...data, qty: 1 };
dispatch(addTocart(newData));
setOpenWishlist(false);
};
Sources: frontend/src/components/Wishlist/Wishlist.jsx:19-23
This flow is visualized in the sequence diagram below.
Summary
The Wishlist and Shopping Cart features are implemented as robust, client-side modules using React and Redux. State changes are managed through a clear set of Redux actions, and data is persisted in localStorage to provide a seamless user experience across sessions. The modular component structure (Cart.jsx, Wishlist.jsx, ProductCard.jsx) allows for easy integration and management of these essential e-commerce functionalities throughout the application.