Description
Implement a fully functional shopping cart for oreel-web using Zustand as the state management solution. The cart must persist locally for guest users (e.g., localStorage) and sync with the backend for authenticated users. Users should be able to modify item quantities, remove items, and see real‑time subtotal updates. The cart page will display all line items, a subtotal, and a clear path to checkout.
Acceptance Criteria
Cart store (Zustand) includes:
State: items: CartItem[] (each with id, variantId, name, price, quantity, image, maxStock).
Actions: addItem, updateQuantity, removeItem, clearCart, syncWithBackend.
Selectors: subtotal, totalItems, isCartEmpty.
Persistence for guest users:
Cart data is saved to localStorage on every change.
On page reload, the cart is rehydrated from localStorage.
A unique anonymous session ID may be used for tracking (optional).
Server‑side sync for logged‑in users:
When a user logs in, the local cart is merged with the server cart (backend endpoint POST /api/cart/sync or similar).
After login, all cart mutations (add, update, remove) are sent to the backend to keep the server cart updated.
On logout, the cart persists locally but is not cleared (or can be cleared based on UX decision).
Cart UI components:
Cart dropdown / mini‑cart (in header): shows a summary (item count + total) and a few line items with a link to full cart page.
Cart page (/cart) displays:
Table/list of line items with product image, name, variant (if any), unit price, quantity selector (with +/- buttons), remove button, and line total.
Subtotal (sum of line totals).
"Proceed to Checkout" button (links to /checkout – can be a placeholder for now).
Continue shopping link.
Quantity updates are debounced or optimistic with error handling (e.g., cannot exceed stock).
Edge cases handled:
Adding duplicate item + variant increases quantity (up to stock limit).
Removing last item shows empty cart state with friendly message and CTA to browse products.
Stock validation: backend should reject quantity exceeding available stock; frontend shows error toast.
Implementation Notes
Use Zustand with persist middleware for localStorage (from zustand/middleware).
For authenticated sync, call backend endpoints after each mutation. The store should have a flag isAuthenticated that determines whether to sync.
Backend cart endpoints expected (to be implemented separately):
GET /api/cart – fetch user’s cart.
POST /api/cart/items – add/update item.
DELETE /api/cart/items/:id – remove item.
POST /api/cart/sync – merge guest cart on login.
For MVP, if backend is not ready, mock the sync with console.log and a simulated delay, but keep the integration points clear.
Quantity picker should respect maxStock (disable increment beyond stock, decrement down to 1).
Description
Implement a fully functional shopping cart for
oreel-webusing Zustand as the state management solution. The cart must persist locally for guest users (e.g.,localStorage) and sync with the backend for authenticated users. Users should be able to modify item quantities, remove items, and see real‑time subtotal updates. The cart page will display all line items, a subtotal, and a clear path to checkout.Acceptance Criteria
items: CartItem[](each withid,variantId,name,price,quantity,image,maxStock).addItem,updateQuantity,removeItem,clearCart,syncWithBackend.subtotal,totalItems,isCartEmpty.localStorageon every change.localStorage.POST /api/cart/syncor similar)./cart) displays:/checkout– can be a placeholder for now).Implementation Notes
persistmiddleware forlocalStorage(fromzustand/middleware).isAuthenticatedthat determines whether to sync.GET /api/cart– fetch user’s cart.POST /api/cart/items– add/update item.DELETE /api/cart/items/:id– remove item.POST /api/cart/sync– merge guest cart on login.console.logand a simulated delay, but keep the integration points clear.maxStock(disable increment beyond stock, decrement down to 1).