diff options
Diffstat (limited to 'frontend/src/context/cart-context.js')
-rw-r--r-- | frontend/src/context/cart-context.js | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/frontend/src/context/cart-context.js b/frontend/src/context/cart-context.js new file mode 100644 index 0000000..8d173b7 --- /dev/null +++ b/frontend/src/context/cart-context.js @@ -0,0 +1,120 @@ +import { createContext, useContext, useState, useEffect } from 'react'; +import { toast } from 'sonner'; + +const CartContext = createContext(); + +export const CartProvider = ({ children }) => { + const [items, setItems] = useState([]); + const [total, setTotal] = useState(0); + + // Load cart from localStorage on initial load + useEffect(() => { + if (typeof window !== 'undefined') { + const savedCart = localStorage.getItem('cart'); + if (savedCart) { + try { + const parsedCart = JSON.parse(savedCart); + setItems(parsedCart); + calculateTotal(parsedCart); + } catch (error) { + console.error('Failed to parse cart from localStorage:', error); + } + } + } + }, []); + + // Save cart to localStorage whenever it changes + useEffect(() => { + if (typeof window !== 'undefined') { + localStorage.setItem('cart', JSON.stringify(items)); + calculateTotal(items); + } + }, [items]); + + // Calculate total price + const calculateTotal = (cartItems) => { + const sum = cartItems.reduce((acc, item) => acc + item.price * item.quantity, 0); + setTotal(sum); + }; + + // Add item to cart + const addItem = (item) => { + setItems((prevItems) => { + // Check if item already exists in cart + const existingItemIndex = prevItems.findIndex((i) => i.id === item.id); + + if (existingItemIndex !== -1) { + // Item exists, update quantity + const updatedItems = [...prevItems]; + updatedItems[existingItemIndex] = { + ...updatedItems[existingItemIndex], + quantity: updatedItems[existingItemIndex].quantity + 1, + }; + toast.success(`Added another ${item.name} to your cart`); + return updatedItems; + } else { + // Item doesn't exist, add new item + toast.success(`Added ${item.name} to your cart`); + return [...prevItems, { ...item, quantity: 1 }]; + } + }); + }; + + // Remove item from cart + const removeItem = (itemId) => { + setItems((prevItems) => { + const itemToRemove = prevItems.find((item) => item.id === itemId); + if (itemToRemove) { + toast.success(`Removed ${itemToRemove.name} from your cart`); + } + return prevItems.filter((item) => item.id !== itemId); + }); + }; + + // Update item quantity + const updateQuantity = (itemId, quantity) => { + if (quantity < 1) return; + + setItems((prevItems) => + prevItems.map((item) => + item.id === itemId ? { ...item, quantity } : item + ) + ); + }; + + // Clear cart + const clearCart = () => { + setItems([]); + toast.success('Cart cleared'); + }; + + // Get cart item count + const getItemCount = () => { + return items.reduce((count, item) => count + item.quantity, 0); + }; + + return ( + <CartContext.Provider + value={{ + items, + total, + addItem, + removeItem, + updateQuantity, + clearCart, + getItemCount, + }} + > + {children} + </CartContext.Provider> + ); +}; + +// Custom hook to use cart context +export const useCart = () => { + const context = useContext(CartContext); + if (!context) { + throw new Error('useCart must be used within a CartProvider'); + } + return context; +};
\ No newline at end of file |