import { Checkbox } from '@chakra-ui/react'; import React, { useState, useCallback, useEffect } from 'react'; import { getAuth } from '~/libs/auth'; import { CartItem } from '~/types/cart'; import { upsertUserCart } from '~/services/cart'; import { useCartStore } from '../stores/useCartStore'; import { toast } from 'react-hot-toast'; import { getSelectedItemsFromCookie, updateSelectedItemInCookie, checkboxUpdateState, } from '~/utils/cart'; interface Props { item: CartItem; } const CartItemSelect: React.FC = ({ item }) => { const auth = getAuth(); const { updateCartItem, cart, loadCart } = useCartStore(); const [isUpdating, setIsUpdating] = useState(false); const [localSelected, setLocalSelected] = useState(item.selected); // Subscribe to global checkbox update state useEffect(() => { const handleUpdateStateChange = (isUpdating: boolean): void => { // This component doesn't need to react to global state changes // Individual checkboxes are managed independently }; checkboxUpdateState.addListener(handleUpdateStateChange); return () => checkboxUpdateState.removeListener(handleUpdateStateChange); }, []); // Sync local state with cookie and server data useEffect(() => { if (isUpdating) return; const selectedItems = getSelectedItemsFromCookie() as Record< number, boolean >; const storedState = selectedItems[item.id]; if (storedState !== undefined) { // Update local state if cookie differs if (localSelected !== storedState) { setLocalSelected(storedState); } // Sync cart state with cookie if needed if (storedState !== item.selected && cart) { const updatedCartItems = cart.products.map((cartItem) => cartItem.id === item.id ? { ...cartItem, selected: storedState } : cartItem ); updateCartItem({ ...cart, products: updatedCartItems }); } } else { // Initialize cookie with server state setLocalSelected(item.selected); updateSelectedItemInCookie(item.id, item.selected, false); } }, [item.id, item.selected, localSelected, cart, updateCartItem, isUpdating]); const handleChange = useCallback( async (e: React.ChangeEvent): Promise => { if (typeof auth !== 'object' || !cart || isUpdating) return; const newSelectedState = e.target.checked; // Update local state immediately setLocalSelected(newSelectedState); setIsUpdating(true); checkboxUpdateState.startUpdate(); try { // Update cookie immediately for responsive UI updateSelectedItemInCookie(item.id, newSelectedState, false); // Update cart state optimistically const updatedCartItems = cart.products.map((cartItem) => cartItem.id === item.id ? { ...cartItem, selected: newSelectedState } : cartItem ); updateCartItem({ ...cart, products: updatedCartItems }); // Send update to server await upsertUserCart({ userId: auth.id, type: item.cart_type, id: item.id, qty: item.quantity, selected: newSelectedState, // purchase_tax_id: item.purchase_tax_id, // vendor_id: item.vendor_id }); // Reload cart for consistency await loadCart(auth.id); } catch (error) { console.error('Failed to update item selection:', error); toast.error('Gagal memperbarui pilihan barang'); // Revert changes on error setLocalSelected(!newSelectedState); updateSelectedItemInCookie(item.id, !newSelectedState, false); loadCart(auth.id); } finally { setIsUpdating(false); checkboxUpdateState.endUpdate(); } }, [auth, cart, item, isUpdating, updateCartItem, loadCart] ); const isDisabled: boolean = isUpdating; return (
); }; export default CartItemSelect;