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/utils | |
| parent | 7d4445bb9bad3d6c945503086a07bd882536e5f6 (diff) | |
<miqdad> disable button when updating checkboxes and change summary design
Diffstat (limited to 'src-migrate/utils')
| -rw-r--r-- | src-migrate/utils/cart.js | 102 | ||||
| -rw-r--r-- | src-migrate/utils/checkBoxState.js | 89 |
2 files changed, 189 insertions, 2 deletions
diff --git a/src-migrate/utils/cart.js b/src-migrate/utils/cart.js index 431ff530..f474cbde 100644 --- a/src-migrate/utils/cart.js +++ b/src-migrate/utils/cart.js @@ -1,5 +1,6 @@ // cart-cookie-utils.js import Cookies from 'js-cookie'; +import checkboxUpdateState from './checkBoxState'; // Constants const CART_ITEMS_COOKIE = 'cart_data'; @@ -165,9 +166,19 @@ export const syncCartWithCookie = (cart) => { * Update selected status item di cookie * @param {number} productId ID produk * @param {boolean} isSelected Status selected baru + * @param {boolean} notifyUpdate Whether to notify checkbox update state (default: true) */ -export const updateSelectedItemInCookie = (productId, isSelected) => { +export const updateSelectedItemInCookie = ( + productId, + isSelected, + notifyUpdate = true +) => { try { + // Notify checkbox update state if requested + if (notifyUpdate) { + checkboxUpdateState.startUpdate(); + } + const selectedItems = getSelectedItemsFromCookie(); selectedItems[productId] = isSelected; setSelectedItemsToCookie(selectedItems); @@ -188,6 +199,11 @@ export const updateSelectedItemInCookie = (productId, isSelected) => { } catch (error) { console.error('Error updating selected item in cookie:', error); return {}; + } finally { + // End update notification if requested + if (notifyUpdate) { + checkboxUpdateState.endUpdate(); + } } }; @@ -195,9 +211,19 @@ export const updateSelectedItemInCookie = (productId, isSelected) => { * Set semua item menjadi selected atau unselected di cookie * @param {Array} productIds Array product IDs * @param {boolean} isSelected Status selected baru + * @param {boolean} notifyUpdate Whether to notify checkbox update state (default: true) */ -export const setAllSelectedInCookie = (productIds, isSelected) => { +export const setAllSelectedInCookie = ( + productIds, + isSelected, + notifyUpdate = true +) => { try { + // Notify checkbox update state if requested + if (notifyUpdate) { + checkboxUpdateState.startUpdate(); + } + const selectedItems = getSelectedItemsFromCookie(); productIds.forEach((id) => { @@ -221,6 +247,11 @@ export const setAllSelectedInCookie = (productIds, isSelected) => { } catch (error) { console.error('Error setting all selected in cookie:', error); return {}; + } finally { + // End update notification if requested + if (notifyUpdate) { + checkboxUpdateState.endUpdate(); + } } }; @@ -263,10 +294,37 @@ export const removeCartItemsFromCookie = (cartIds) => { }; /** + * Hapus item selected dari cookie berdasarkan product IDs + * @param {Array} productIds Array product IDs untuk dihapus + */ +export const removeSelectedItemsFromCookie = (productIds) => { + try { + const selectedItems = getSelectedItemsFromCookie(); + + // Hapus dari selectedItems + productIds.forEach((productId) => { + if (selectedItems[productId] !== undefined) { + delete selectedItems[productId]; + } + }); + + // Simpan kembali ke cookie + setSelectedItemsToCookie(selectedItems); + + return { selectedItems }; + } catch (error) { + console.error('Error removing selected items from cookie:', error); + return {}; + } +}; + +/** * Force reset semua selected items ke unselected state */ export const forceResetAllSelectedItems = () => { try { + checkboxUpdateState.startUpdate(); + const cartData = getCartDataFromCookie(); const selectedItems = {}; @@ -286,5 +344,45 @@ export const forceResetAllSelectedItems = () => { } catch (error) { console.error('Error resetting all selected items:', error); return {}; + } finally { + checkboxUpdateState.endUpdate(); } }; + +/** + * Sync selected items between cookie and cart data + * @param {Array} cartProducts Products array from cart + */ +export const syncSelectedItemsWithCookie = (cartProducts) => { + try { + if (!cartProducts || !Array.isArray(cartProducts)) { + return { items: {}, needsUpdate: false }; + } + + const selectedItems = getSelectedItemsFromCookie(); + let needsUpdate = false; + + // Check if we need to update any items based on cookie values + cartProducts.forEach((product) => { + if (product.id && selectedItems[product.id] !== undefined) { + if (product.selected !== selectedItems[product.id]) { + needsUpdate = true; + } + } else if (product.id) { + // If not in cookie, add with current value + selectedItems[product.id] = product.selected; + } + }); + + // Update the cookie with the latest values + setSelectedItemsToCookie(selectedItems); + + return { items: selectedItems, needsUpdate }; + } catch (error) { + console.error('Error syncing selected items with cookie:', error); + return { items: {}, needsUpdate: false }; + } +}; + +// Export the checkbox update state for use in components +export { checkboxUpdateState }; diff --git a/src-migrate/utils/checkBoxState.js b/src-migrate/utils/checkBoxState.js new file mode 100644 index 00000000..0c58321f --- /dev/null +++ b/src-migrate/utils/checkBoxState.js @@ -0,0 +1,89 @@ +// ~/modules/cart/utils/checkboxUpdateState.js + +/** + * Enhanced state manager for checkbox updates + * Tracks both global update state and individual checkbox update states + */ + +// Track the number of ongoing updates +let updateCount = 0; +let listeners = []; + +// Track which checkboxes are currently updating by ID +let updatingCheckboxIds = new Set(); + +const checkboxUpdateState = { + // Check if any checkboxes are currently updating (for buttons) + isUpdating: () => updateCount > 0, + + // Check if a specific checkbox is updating (for disabling just that checkbox) + isCheckboxUpdating: (itemId) => updatingCheckboxIds.has(itemId.toString()), + + // Start an update for a specific checkbox + startUpdate: (itemId = null) => { + updateCount++; + + // If an item ID is provided, mark it as updating + if (itemId !== null) { + updatingCheckboxIds.add(itemId.toString()); + } + + notifyListeners(); + return updateCount; + }, + + // End an update for a specific checkbox + endUpdate: (itemId = null) => { + updateCount = Math.max(0, updateCount - 1); + + // If an item ID is provided, remove it from updating set + if (itemId !== null) { + updatingCheckboxIds.delete(itemId.toString()); + } + + notifyListeners(); + return updateCount; + }, + + // Reset the update counter and clear all updating checkboxes + reset: () => { + updateCount = 0; + updatingCheckboxIds.clear(); + notifyListeners(); + }, + + // Get IDs of all checkboxes currently updating (for debugging) + getUpdatingCheckboxIds: () => [...updatingCheckboxIds], + + // Add a listener function to be called when update state changes + addListener: (callback) => { + if (typeof callback === 'function') { + listeners.push(callback); + + // Immediately call with current state + callback(updateCount > 0); + } + }, + + // Remove a listener + removeListener: (callback) => { + listeners = listeners.filter((listener) => listener !== callback); + }, + + // Get current counter (for debugging) + getUpdateCount: () => updateCount, +}; + +// Private function to notify all listeners of state changes +function notifyListeners() { + const isUpdating = updateCount > 0; + listeners.forEach((listener) => { + try { + listener(isUpdating); + } catch (error) { + console.error('Error in checkbox update state listener:', error); + } + }); +} + +export default checkboxUpdateState; |
