'use client'; import React, { createContext, useContext, useReducer, useEffect, ReactNode } from 'react'; import { toast } from 'sonner'; import { cartReducer, getCartTotals } from '@/domain/cart/cart-domain'; import type { CartItem, NewCartItem } from '@/domain/cart/entities'; import { container } from '@/infrastructure/di/container'; import { playAddSound } from '@/infrastructure/audio/web-audio-sound-adapter'; export type { CartItem }; interface CartContextType { items: CartItem[]; isOpen: boolean; totalItems: number; totalPrice: number; addToCart: (item: NewCartItem) => void; removeFromCart: (id: string) => void; updateQuantity: (id: string, quantity: number) => void; clearCart: () => void; toggleCart: () => void; openCart: () => void; closeCart: () => void; } const CartContext = createContext(undefined); export function CartProvider({ children }: { children: ReactNode }) { const [state, dispatch] = useReducer(cartReducer, { items: [], isOpen: false, }); useEffect(() => { const savedItems = container.cartRepository.load(); if (savedItems.length > 0) { dispatch({ type: 'RESTORE_ITEMS', payload: savedItems }); } }, []); useEffect(() => { container.cartRepository.save(state.items); }, [state.items]); const { totalItems, totalPrice } = getCartTotals(state.items); const addToCart = (item: NewCartItem) => { dispatch({ type: 'ADD_ITEM', payload: item }); playAddSound(); const priceLabel = item.pricingMode === 'weight' ? `${item.pricePerHalfKg ?? item.price} kr / ½ kg` : `${item.price} kr`; toast.success(`Added ${item.name} to cart`, { description: priceLabel, action: { label: 'View Cart', onClick: () => dispatch({ type: 'OPEN_CART' }), }, }); }; const removeFromCart = (id: string) => { dispatch({ type: 'REMOVE_ITEM', payload: id }); }; const updateQuantity = (id: string, quantity: number) => { dispatch({ type: 'UPDATE_QUANTITY', payload: { id, quantity } }); }; const clearCart = () => { dispatch({ type: 'CLEAR_CART' }); }; const toggleCart = () => { dispatch({ type: 'TOGGLE_CART' }); }; const openCart = () => { dispatch({ type: 'OPEN_CART' }); }; const closeCart = () => { dispatch({ type: 'CLOSE_CART' }); }; return ( {children} ); } export function useCart() { const context = useContext(CartContext); if (context === undefined) { throw new Error('useCart must be used within a CartProvider'); } return context; }