diff options
| author | Miqdad <ahmadmiqdad27@gmail.com> | 2025-05-22 10:05:09 +0700 |
|---|---|---|
| committer | Miqdad <ahmadmiqdad27@gmail.com> | 2025-05-22 10:05:09 +0700 |
| commit | 09cebc9020c4f1995a73305187bc1576e339d183 (patch) | |
| tree | 7617d74533d23277690886709fe6b9d68006814d /src-migrate/pages | |
| parent | 7d4445bb9bad3d6c945503086a07bd882536e5f6 (diff) | |
<miqdad> disable button when updating checkboxes and change summary design
Diffstat (limited to 'src-migrate/pages')
| -rw-r--r-- | src-migrate/pages/shop/cart/index.tsx | 98 |
1 files changed, 64 insertions, 34 deletions
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> |
