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/pages/shop/cart/index.tsx | 98 +++++++++++++++++++++++------------
 1 file changed, 64 insertions(+), 34 deletions(-)

(limited to 'src-migrate/pages/shop/cart/index.tsx')

diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx
index 475a4259..eefe8d09 100644
--- a/src-migrate/pages/shop/cart/index.tsx
+++ b/src-migrate/pages/shop/cart/index.tsx
@@ -32,8 +32,12 @@ import {
   setAllSelectedInCookie,
   removeSelectedItemsFromCookie,
   forceResetAllSelectedItems,
+  checkboxUpdateState,
 } from '~/utils/cart';
 
+// Special ID for the "select all" checkbox
+const SELECT_ALL_ID = 'select_all_checkbox';
+
 const CartPage = () => {
   const router = useRouter();
   const auth = getAuth();
@@ -46,6 +50,22 @@ const CartPage = () => {
   const [isTop, setIsTop] = useState(true);
   const [isUpdating, setIsUpdating] = useState(false);
   const [isStateMismatch, setIsStateMismatch] = useState(false);
+  const [isAnyCheckboxUpdating, setIsAnyCheckboxUpdating] = useState(false);
+
+  // Subscribe to checkbox update state changes
+  useEffect(() => {
+    const handleUpdateStateChange = (isUpdating) => {
+      setIsAnyCheckboxUpdating(isUpdating);
+    };
+
+    // Add listener for checkbox update state changes
+    checkboxUpdateState.addListener(handleUpdateStateChange);
+
+    // Cleanup listener on component unmount
+    return () => {
+      checkboxUpdateState.removeListener(handleUpdateStateChange);
+    };
+  }, []);
 
   // Function to check if cart state is inconsistent
   const checkCartStateMismatch = () => {
@@ -91,11 +111,14 @@ const CartPage = () => {
       console.error('Error checking cart state mismatch:', error);
       return false;
     }
-  }; // Function to reset all selected items when state is inconsistent
+  };
+
+  // Function to reset all selected items when state is inconsistent
   const handleResetSelections = () => {
     if (!cart) return;
 
     setIsUpdating(true);
+
     try {
       // Use the forceResetSelection function from the store
       useCartStore.getState().forceResetSelection();
@@ -115,6 +138,7 @@ const CartPage = () => {
             id: item.id,
             qty: item.quantity,
             selected: false,
+            purchase_tax_id: item.purchase_tax_id || null, // Fix integer field issue
           })
         );
 
@@ -123,7 +147,9 @@ const CartPage = () => {
           .catch((error) => {
             console.error('Error updating selections to server:', error);
           })
-          .finally(() => setIsUpdating(false));
+          .finally(() => {
+            setIsUpdating(false);
+          });
       } else {
         setIsUpdating(false);
       }
@@ -211,7 +237,7 @@ const CartPage = () => {
   }, [cart]);
 
   const handleCheckout = () => {
-    if (isUpdating || isLoadDelete) {
+    if (isUpdating || isLoadDelete || isAnyCheckboxUpdating) {
       toast.error('Harap tunggu pembaruan selesai');
       return;
     }
@@ -219,7 +245,7 @@ const CartPage = () => {
   };
 
   const handleQuotation = () => {
-    if (isUpdating || isLoadDelete) {
+    if (isUpdating || isLoadDelete || isAnyCheckboxUpdating) {
       toast.error('Harap tunggu pembaruan selesai');
       return;
     }
@@ -234,6 +260,12 @@ const CartPage = () => {
     if (cart && !isUpdating && typeof auth === 'object') {
       const newSelectedState = !hasSelectedAll;
 
+      // Set updating flag
+      setIsUpdating(true);
+
+      // Notify checkbox update state system with the special select all ID
+      checkboxUpdateState.startUpdate(SELECT_ALL_ID);
+
       // Update UI immediately
       const updatedCart = {
         ...cart,
@@ -249,9 +281,7 @@ const CartPage = () => {
       const productIds = cart.products.map((item) => item.id);
 
       // Update cookies immediately for responsive UI
-      setAllSelectedInCookie(productIds, newSelectedState);
-
-      setIsUpdating(true);
+      setAllSelectedInCookie(productIds, newSelectedState, false); // We're already notifying
 
       try {
         // Update all items on server in background
@@ -262,6 +292,7 @@ const CartPage = () => {
             id: item.id,
             qty: item.quantity,
             selected: newSelectedState,
+            purchase_tax_id: item.purchase_tax_id || null, // Fix integer field issue
           })
         );
 
@@ -282,11 +313,14 @@ const CartPage = () => {
         updateCartItem(revertedCart);
 
         // Revert cookies
-        setAllSelectedInCookie(productIds, !newSelectedState);
+        setAllSelectedInCookie(productIds, !newSelectedState, false);
 
         toast.error('Gagal memperbarui pilihan');
       } finally {
         setIsUpdating(false);
+
+        // End update notification
+        checkboxUpdateState.endUpdate(SELECT_ALL_ID);
       }
     }
   };
@@ -295,6 +329,8 @@ const CartPage = () => {
     if (typeof auth !== 'object' || !cart) return;
 
     setIsLoadDelete(true);
+    checkboxUpdateState.startUpdate('delete_operation'); // Use special ID for delete
+
     try {
       const itemsToDelete = cart.products.filter((item) => item.selected);
       const itemIdsToDelete = itemsToDelete.map((item) => item.id);
@@ -313,9 +349,18 @@ const CartPage = () => {
       toast.error('Gagal menghapus item');
     } finally {
       setIsLoadDelete(false);
+      checkboxUpdateState.endUpdate('delete_operation');
     }
   };
 
+  // Check if buttons should be disabled
+  const areButtonsDisabled =
+    isUpdating || isLoadDelete || isAnyCheckboxUpdating;
+
+  // Only disable the select all checkbox if it specifically is updating
+  const isSelectAllDisabled =
+    isUpdating || checkboxUpdateState.isCheckboxUpdating(SELECT_ALL_ID);
+
   return (
     <>
       <div
@@ -325,16 +370,6 @@ const CartPage = () => {
       >
         <div className='flex items-center justify-between mb-2'>
           <h1 className={style.title}>Keranjang Belanja</h1>
-          {isStateMismatch && (
-            <Button
-              colorScheme='red'
-              size='sm'
-              isLoading={isUpdating}
-              onClick={handleResetSelections}
-            >
-              Reset Pilihan
-            </Button>
-          )}
         </div>
 
         <div className='h-2' />
@@ -346,9 +381,9 @@ const CartPage = () => {
               size='lg'
               isChecked={hasSelectedAll}
               onChange={handleChange}
-              isDisabled={isUpdating || isLoadDelete}
-              opacity={isUpdating ? 0.5 : 1}
-              cursor={isUpdating ? 'not-allowed' : 'pointer'}
+              isDisabled={isSelectAllDisabled}
+              opacity={isSelectAllDisabled ? 0.5 : 1}
+              cursor={isSelectAllDisabled ? 'not-allowed' : 'pointer'}
               _disabled={{
                 opacity: 0.5,
                 cursor: 'not-allowed',
@@ -363,6 +398,7 @@ const CartPage = () => {
             <Tooltip
               label={clsxm({
                 'Tidak ada item yang dipilih': !hasSelected,
+                'Harap tunggu pembaruan selesai': areButtonsDisabled,
               })}
             >
               <Button
@@ -371,7 +407,7 @@ const CartPage = () => {
                 colorScheme='red'
                 w='auto'
                 size={device.isMobile ? 'sm' : 'md'}
-                isDisabled={!hasSelected || isUpdating}
+                isDisabled={!hasSelected || areButtonsDisabled}
                 onClick={handleDelete}
               >
                 {isLoadDelete && <Spinner size='xs' />}
@@ -453,7 +489,7 @@ const CartPage = () => {
               <Tooltip
                 label={clsxm({
                   'Barang promo tidak dapat dibuat quotation': hasSelectedPromo,
-                  'Harap tunggu pembaruan selesai': isUpdating,
+                  'Harap tunggu pembaruan selesai': areButtonsDisabled,
                   'Tidak ada item yang dipilih': !hasSelected,
                 })}
               >
@@ -461,14 +497,11 @@ const CartPage = () => {
                   colorScheme='yellow'
                   w='full'
                   isDisabled={
-                    hasSelectedPromo ||
-                    !hasSelected ||
-                    isUpdating ||
-                    isLoadDelete
+                    hasSelectedPromo || !hasSelected || areButtonsDisabled
                   }
                   onClick={handleQuotation}
                 >
-                  {isUpdating ? <Spinner size='sm' mr={2} /> : null}
+                  {areButtonsDisabled ? <Spinner size='sm' mr={2} /> : null}
                   Quotation
                 </Button>
               </Tooltip>
@@ -477,21 +510,18 @@ const CartPage = () => {
                   label={clsxm({
                     'Tidak ada item yang dipilih': !hasSelected,
                     'Terdapat item yang tidak ada harga': hasSelectNoPrice,
-                    'Harap tunggu pembaruan selesai': isUpdating,
+                    'Harap tunggu pembaruan selesai': areButtonsDisabled,
                   })}
                 >
                   <Button
                     colorScheme='red'
                     w='full'
                     isDisabled={
-                      !hasSelected ||
-                      hasSelectNoPrice ||
-                      isUpdating ||
-                      isLoadDelete
+                      !hasSelected || hasSelectNoPrice || areButtonsDisabled
                     }
                     onClick={handleCheckout}
                   >
-                    {isUpdating ? <Spinner size='sm' mr={2} /> : null}
+                    {areButtonsDisabled ? <Spinner size='sm' mr={2} /> : null}
                     Checkout
                   </Button>
                 </Tooltip>
-- 
cgit v1.2.3

