From 09cebc9020c4f1995a73305187bc1576e339d183 Mon Sep 17 00:00:00 2001
From: Miqdad <ahmadmiqdad27@gmail.com>
Date: Thu, 22 May 2025 10:05:09 +0700
Subject: <miqdad> disable button when updating checkboxes and change summary
 design

---
 src-migrate/modules/cart/components/ItemSelect.tsx | 43 ++++++++++++++++++----
 1 file changed, 35 insertions(+), 8 deletions(-)

(limited to 'src-migrate/modules/cart/components/ItemSelect.tsx')

diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx
index 733ee64d..70b656ec 100644
--- a/src-migrate/modules/cart/components/ItemSelect.tsx
+++ b/src-migrate/modules/cart/components/ItemSelect.tsx
@@ -8,6 +8,7 @@ import { toast } from 'react-hot-toast';
 import {
   getSelectedItemsFromCookie,
   updateSelectedItemInCookie,
+  checkboxUpdateState,
 } from '~/utils/cart';
 
 type Props = {
@@ -19,6 +20,20 @@ const CartItemSelect = ({ item }: Props) => {
   const { updateCartItem, cart, loadCart } = useCartStore();
   const [isUpdating, setIsUpdating] = useState<boolean>(false);
   const [localSelected, setLocalSelected] = useState<boolean>(item.selected);
+  const [isGlobalUpdating, setIsGlobalUpdating] = useState<boolean>(false);
+
+  // Subscribe to global checkbox update state
+  useEffect(() => {
+    const handleUpdateStateChange = (isUpdating) => {
+      setIsGlobalUpdating(isUpdating);
+    };
+
+    checkboxUpdateState.addListener(handleUpdateStateChange);
+
+    return () => {
+      checkboxUpdateState.removeListener(handleUpdateStateChange);
+    };
+  }, []);
 
   // Initialize local state from cookie or server
   useEffect(() => {
@@ -54,7 +69,7 @@ const CartItemSelect = ({ item }: Props) => {
       setLocalSelected(item.selected);
 
       // Save this state to cookie for future use
-      updateSelectedItemInCookie(item.id, item.selected);
+      updateSelectedItemInCookie(item.id, item.selected, false); // don't notify for initial sync
     }
   }, [item.id, item.selected, localSelected, cart, updateCartItem, isUpdating]);
 
@@ -70,9 +85,12 @@ const CartItemSelect = ({ item }: Props) => {
       setLocalSelected(newSelectedState);
       setIsUpdating(true);
 
+      // Start the update - notify global state with this checkbox's ID
+      checkboxUpdateState.startUpdate(item.id);
+
       try {
-        // Update cookie immediately
-        updateSelectedItemInCookie(item.id, newSelectedState);
+        // The cookie update is now handled inside the function with notification
+        updateSelectedItemInCookie(item.id, newSelectedState, false); // We already started above
 
         // Update cart state immediately for UI responsiveness
         const updatedCartItems = cart.products.map((cartItem) =>
@@ -91,6 +109,7 @@ const CartItemSelect = ({ item }: Props) => {
           id: item.id,
           qty: item.quantity,
           selected: newSelectedState,
+          purchase_tax_id: item.purchase_tax_id || null, // Ensure null for numeric fields
         });
 
         // Reload cart to ensure consistency
@@ -102,18 +121,26 @@ const CartItemSelect = ({ item }: Props) => {
         // Revert local state on error
         setLocalSelected(!newSelectedState);
 
-        // Update cookie back
-        updateSelectedItemInCookie(item.id, !newSelectedState);
+        // Revert cookie change
+        updateSelectedItemInCookie(item.id, !newSelectedState, false);
 
         // Reload cart to get server state
         loadCart(auth.id);
       } finally {
         setIsUpdating(false);
+
+        // End the update - notify global state with this checkbox's ID
+        checkboxUpdateState.endUpdate(item.id);
       }
     },
     [auth, cart, item, isUpdating, updateCartItem, loadCart]
   );
 
+  // Determine if THIS specific checkbox should be disabled - only disable
+  // if this specific checkbox is updating
+  const isDisabled =
+    isUpdating || checkboxUpdateState.isCheckboxUpdating(item.id);
+
   return (
     <div className='w-6 my-auto relative'>
       <Checkbox
@@ -122,9 +149,9 @@ const CartItemSelect = ({ item }: Props) => {
         size='lg'
         isChecked={localSelected}
         onChange={handleChange}
-        isDisabled={isUpdating}
-        opacity={isUpdating ? 0.5 : 1}
-        cursor={isUpdating ? 'not-allowed' : 'pointer'}
+        isDisabled={isDisabled}
+        opacity={isDisabled ? 0.5 : 1}
+        cursor={isDisabled ? 'not-allowed' : 'pointer'}
         _disabled={{
           opacity: 0.5,
           cursor: 'not-allowed',
-- 
cgit v1.2.3

