summaryrefslogtreecommitdiff
path: root/src-migrate/pages
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-05-22 10:05:09 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-05-22 10:05:09 +0700
commit09cebc9020c4f1995a73305187bc1576e339d183 (patch)
tree7617d74533d23277690886709fe6b9d68006814d /src-migrate/pages
parent7d4445bb9bad3d6c945503086a07bd882536e5f6 (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.tsx98
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>