From 7d4445bb9bad3d6c945503086a07bd882536e5f6 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 19 May 2025 11:02:19 +0700 Subject: fix unresponsive cart select --- src-migrate/utils/cart.js | 290 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 src-migrate/utils/cart.js (limited to 'src-migrate/utils') diff --git a/src-migrate/utils/cart.js b/src-migrate/utils/cart.js new file mode 100644 index 00000000..431ff530 --- /dev/null +++ b/src-migrate/utils/cart.js @@ -0,0 +1,290 @@ +// cart-cookie-utils.js +import Cookies from 'js-cookie'; + +// Constants +const CART_ITEMS_COOKIE = 'cart_data'; +const SELECTED_ITEMS_COOKIE = 'cart_selected_items'; +const COOKIE_EXPIRY_DAYS = 7; // Cookie akan berlaku selama 7 hari + +/** + * Mengambil data cart lengkap dari cookie + * @returns {Object} Object dengan key cart_id dan value cart item data lengkap + */ +export const getCartDataFromCookie = () => { + try { + const storedData = Cookies.get(CART_ITEMS_COOKIE); + return storedData ? JSON.parse(storedData) : {}; + } catch (error) { + console.error('Error reading cart data from cookie:', error); + return {}; + } +}; + +/** + * Menyimpan data cart lengkap ke cookie + * @param {Object} cartData Object dengan key cart_id dan value cart item data lengkap + */ +export const setCartDataToCookie = (cartData) => { + try { + Cookies.set(CART_ITEMS_COOKIE, JSON.stringify(cartData), { + expires: COOKIE_EXPIRY_DAYS, + path: '/', + sameSite: 'strict', + }); + } catch (error) { + console.error('Error saving cart data to cookie:', error); + } +}; + +/** + * Mengambil state selected items dari cookie + * @returns {Object} Object dengan key product id dan value boolean selected status + */ +export const getSelectedItemsFromCookie = () => { + try { + const storedItems = Cookies.get(SELECTED_ITEMS_COOKIE); + return storedItems ? JSON.parse(storedItems) : {}; + } catch (error) { + console.error('Error reading selected items from cookie:', error); + return {}; + } +}; + +/** + * Menyimpan state selected items ke cookie + * @param {Object} items Object dengan key product id dan value boolean selected status + */ +export const setSelectedItemsToCookie = (items) => { + try { + Cookies.set(SELECTED_ITEMS_COOKIE, JSON.stringify(items), { + expires: COOKIE_EXPIRY_DAYS, + path: '/', + sameSite: 'strict', + }); + } catch (error) { + console.error('Error saving selected items to cookie:', error); + } +}; + +/** + * Transform cart items dari format API ke format yang lebih simpel untuk disimpan di cookie + * @param {Array} cartItems Array cart items dari API + * @returns {Object} Object dengan key cart_id dan value cart item data + */ +export const transformCartItemsForCookie = (cartItems) => { + if (!cartItems || !Array.isArray(cartItems)) return {}; + + const cartData = {}; + + cartItems.forEach((item) => { + // Skip items yang tidak memiliki cart_id + if (!item.cart_id) return; + + cartData[item.cart_id] = { + id: item.id, + cart_id: item.cart_id, + cart_type: item.cart_type, + product: item.product_id + ? { + id: item.product_id, + name: item.product_name || '', + } + : null, + program_line: item.program_line_id + ? { + id: item.program_line_id, + name: item.program_line_name || '', + } + : null, + quantity: item.quantity, + selected: item.selected, + price: item.price, + package_price: item.package_price, + source: item.source || 'add_to_cart', + }; + }); + + return cartData; +}; + +/** + * Sinkronisasi cart data dan selected items dari server dengan cookie + * @param {Object} cart Cart object dari API + * @returns {Object} Object yang berisi updated cartData dan selectedItems + */ +export const syncCartWithCookie = (cart) => { + try { + if (!cart || !cart.products) return { needsUpdate: false }; + + // Transform data dari API ke format cookie + const serverCartData = transformCartItemsForCookie(cart.products); + + // Ambil data lama dari cookie + const existingCartData = getCartDataFromCookie(); + + // Ambil selected status dari cookie + const selectedItems = getSelectedItemsFromCookie(); + + // Gabungkan data cart, prioritaskan data server + const mergedCartData = { ...existingCartData, ...serverCartData }; + + // Periksa apakah ada perbedaan status selected + let needsUpdate = false; + + // Update selected status berdasarkan cookie jika ada + for (const cartId in mergedCartData) { + const item = mergedCartData[cartId]; + if (item.id && selectedItems[item.id] !== undefined) { + // Jika status di cookie berbeda dengan di cart + if (item.selected !== selectedItems[item.id]) { + needsUpdate = true; + item.selected = selectedItems[item.id]; + } + } else if (item.id) { + // Jika tidak ada di cookie, tambahkan dari cart + selectedItems[item.id] = item.selected; + } + } + + // Simpan kembali ke cookie + setCartDataToCookie(mergedCartData); + setSelectedItemsToCookie(selectedItems); + + return { + cartData: mergedCartData, + selectedItems, + needsUpdate, + }; + } catch (error) { + console.error('Error syncing cart with cookie:', error); + return { needsUpdate: false }; + } +}; + +/** + * Update selected status item di cookie + * @param {number} productId ID produk + * @param {boolean} isSelected Status selected baru + */ +export const updateSelectedItemInCookie = (productId, isSelected) => { + try { + const selectedItems = getSelectedItemsFromCookie(); + selectedItems[productId] = isSelected; + setSelectedItemsToCookie(selectedItems); + + // Update juga di cart data + const cartData = getCartDataFromCookie(); + + for (const cartId in cartData) { + const item = cartData[cartId]; + if (item.id === productId) { + item.selected = isSelected; + } + } + + setCartDataToCookie(cartData); + + return { selectedItems, cartData }; + } catch (error) { + console.error('Error updating selected item in cookie:', error); + return {}; + } +}; + +/** + * Set semua item menjadi selected atau unselected di cookie + * @param {Array} productIds Array product IDs + * @param {boolean} isSelected Status selected baru + */ +export const setAllSelectedInCookie = (productIds, isSelected) => { + try { + const selectedItems = getSelectedItemsFromCookie(); + + productIds.forEach((id) => { + if (id) selectedItems[id] = isSelected; + }); + + setSelectedItemsToCookie(selectedItems); + + // Update juga di cart data + const cartData = getCartDataFromCookie(); + + for (const cartId in cartData) { + if (productIds.includes(cartData[cartId].id)) { + cartData[cartId].selected = isSelected; + } + } + + setCartDataToCookie(cartData); + + return { selectedItems, cartData }; + } catch (error) { + console.error('Error setting all selected in cookie:', error); + return {}; + } +}; + +/** + * Hapus item dari cookie + * @param {Array} cartIds Array cart IDs untuk dihapus + */ +export const removeCartItemsFromCookie = (cartIds) => { + try { + const cartData = getCartDataFromCookie(); + const selectedItems = getSelectedItemsFromCookie(); + const productIdsToRemove = []; + + // Hapus item dari cartData dan catat product IDs + cartIds.forEach((cartId) => { + if (cartData[cartId]) { + if (cartData[cartId].id) { + productIdsToRemove.push(cartData[cartId].id); + } + delete cartData[cartId]; + } + }); + + // Hapus dari selectedItems + productIdsToRemove.forEach((productId) => { + if (selectedItems[productId] !== undefined) { + delete selectedItems[productId]; + } + }); + + // Simpan kembali ke cookie + setCartDataToCookie(cartData); + setSelectedItemsToCookie(selectedItems); + + return { cartData, selectedItems }; + } catch (error) { + console.error('Error removing cart items from cookie:', error); + return {}; + } +}; + +/** + * Force reset semua selected items ke unselected state + */ +export const forceResetAllSelectedItems = () => { + try { + const cartData = getCartDataFromCookie(); + const selectedItems = {}; + + // Reset semua selected status di cartData + for (const cartId in cartData) { + cartData[cartId].selected = false; + if (cartData[cartId].id) { + selectedItems[cartData[cartId].id] = false; + } + } + + // Simpan kembali ke cookie + setCartDataToCookie(cartData); + setSelectedItemsToCookie(selectedItems); + + return { cartData, selectedItems }; + } catch (error) { + console.error('Error resetting all selected items:', error); + return {}; + } +}; -- cgit v1.2.3 From 09cebc9020c4f1995a73305187bc1576e339d183 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 22 May 2025 10:05:09 +0700 Subject: disable button when updating checkboxes and change summary design --- src-migrate/utils/cart.js | 102 ++++++++++++++++++++++++++++++++++++- src-migrate/utils/checkBoxState.js | 89 ++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 src-migrate/utils/checkBoxState.js (limited to 'src-migrate/utils') 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(); + } } }; @@ -262,11 +293,38 @@ 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; -- cgit v1.2.3 From 4904573845478e7e9648735d008153728870a123 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 23 May 2025 09:37:46 +0700 Subject: fix cookie not updating when delete an item --- src-migrate/utils/cart.js | 68 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 20 deletions(-) (limited to 'src-migrate/utils') diff --git a/src-migrate/utils/cart.js b/src-migrate/utils/cart.js index f474cbde..1ddc5446 100644 --- a/src-migrate/utils/cart.js +++ b/src-migrate/utils/cart.js @@ -297,26 +297,10 @@ 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 {}; - } -}; +/** + * Hapus item selected dari cookie berdasarkan product IDs dan juga hapus dari cart data + * @param {Array} productIds Array product IDs untuk dihapus + */ /** * Force reset semua selected items ke unselected state @@ -386,3 +370,47 @@ export const syncSelectedItemsWithCookie = (cartProducts) => { // Export the checkbox update state for use in components export { checkboxUpdateState }; + +/** + * Hapus item selected dari cookie berdasarkan product IDs dan juga hapus dari cart data + * @param {Array} productIds Array product IDs untuk dihapus + */ +/** + * Hapus item selected dari cookie berdasarkan product IDs dan juga hapus dari cart data + * @param {Array} productIds Array product IDs untuk dihapus + */ +export const removeSelectedItemsFromCookie = (productIds) => { + try { + const selectedItems = getSelectedItemsFromCookie(); + const cartData = getCartDataFromCookie(); + const cartIdsToRemove = []; + + // Find cart IDs that match the product IDs + for (const cartId in cartData) { + if (productIds.includes(cartData[cartId].id)) { + cartIdsToRemove.push(cartId); + } + } + + // Remove from selectedItems + productIds.forEach((productId) => { + if (selectedItems[productId] !== undefined) { + delete selectedItems[productId]; + } + }); + + // Remove from cartData + cartIdsToRemove.forEach((cartId) => { + delete cartData[cartId]; + }); + + // Save both cookies + setSelectedItemsToCookie(selectedItems); + setCartDataToCookie(cartData); + + return { selectedItems, cartData }; + } catch (error) { + console.error('Error removing selected items from cookie:', error); + return {}; + } +}; -- cgit v1.2.3 From 582f00294ba924b105c789b43e6e92beaf99260f Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 23 May 2025 10:31:38 +0700 Subject: remove checkboxstate utils --- src-migrate/utils/checkBoxState.js | 89 -------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 src-migrate/utils/checkBoxState.js (limited to 'src-migrate/utils') diff --git a/src-migrate/utils/checkBoxState.js b/src-migrate/utils/checkBoxState.js deleted file mode 100644 index 0c58321f..00000000 --- a/src-migrate/utils/checkBoxState.js +++ /dev/null @@ -1,89 +0,0 @@ -// ~/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; -- cgit v1.2.3 From 31e27d92a1965f02b644a7d905366d7180d33c36 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 26 May 2025 10:38:39 +0700 Subject: add checkboxstate --- src-migrate/utils/checkBoxState.js | 89 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src-migrate/utils/checkBoxState.js (limited to 'src-migrate/utils') 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; -- cgit v1.2.3 From 8ef5d44ff4aaf3f8826ffbb28e4466451a750af1 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 26 May 2025 11:52:18 +0700 Subject: push --- src-migrate/utils/checkBoxState.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate/utils') diff --git a/src-migrate/utils/checkBoxState.js b/src-migrate/utils/checkBoxState.js index 0c58321f..8e65ea66 100644 --- a/src-migrate/utils/checkBoxState.js +++ b/src-migrate/utils/checkBoxState.js @@ -13,7 +13,7 @@ let listeners = []; let updatingCheckboxIds = new Set(); const checkboxUpdateState = { - // Check if any checkboxes are currently updating (for buttons) + // Check if any checkboxes are currently updating (for buttons quotation and checkout) isUpdating: () => updateCount > 0, // Check if a specific checkbox is updating (for disabling just that checkbox) -- cgit v1.2.3 From 1a247903bf7bb87e0a43b4e5e338ea67ec90e6de Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 26 May 2025 14:39:39 +0700 Subject: cleaning code --- src-migrate/utils/cart.js | 7 +++---- src-migrate/utils/checkBoxState.js | 20 +++++++++----------- 2 files changed, 12 insertions(+), 15 deletions(-) (limited to 'src-migrate/utils') diff --git a/src-migrate/utils/cart.js b/src-migrate/utils/cart.js index 1ddc5446..ebd771e5 100644 --- a/src-migrate/utils/cart.js +++ b/src-migrate/utils/cart.js @@ -117,7 +117,7 @@ export const syncCartWithCookie = (cart) => { try { if (!cart || !cart.products) return { needsUpdate: false }; - // Transform data dari API ke format cookie + // Transform data API ke cookie const serverCartData = transformCartItemsForCookie(cart.products); // Ambil data lama dari cookie @@ -126,7 +126,7 @@ export const syncCartWithCookie = (cart) => { // Ambil selected status dari cookie const selectedItems = getSelectedItemsFromCookie(); - // Gabungkan data cart, prioritaskan data server + // Gabungkan data cart, (prioritize data server) const mergedCartData = { ...existingCartData, ...serverCartData }; // Periksa apakah ada perbedaan status selected @@ -142,12 +142,11 @@ export const syncCartWithCookie = (cart) => { item.selected = selectedItems[item.id]; } } else if (item.id) { - // Jika tidak ada di cookie, tambahkan dari cart selectedItems[item.id] = item.selected; } } - // Simpan kembali ke cookie + // Simpan ke cookie setCartDataToCookie(mergedCartData); setSelectedItemsToCookie(selectedItems); diff --git a/src-migrate/utils/checkBoxState.js b/src-migrate/utils/checkBoxState.js index 8e65ea66..2b527f36 100644 --- a/src-migrate/utils/checkBoxState.js +++ b/src-migrate/utils/checkBoxState.js @@ -1,5 +1,3 @@ -// ~/modules/cart/utils/checkboxUpdateState.js - /** * Enhanced state manager for checkbox updates * Tracks both global update state and individual checkbox update states @@ -53,17 +51,17 @@ const checkboxUpdateState = { }, // Get IDs of all checkboxes currently updating (for debugging) - getUpdatingCheckboxIds: () => [...updatingCheckboxIds], + // getUpdatingCheckboxIds: () => [...updatingCheckboxIds], - // Add a listener function to be called when update state changes - addListener: (callback) => { - if (typeof callback === 'function') { - listeners.push(callback); + // // 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); - } - }, + // // Immediately call with current state + // callback(updateCount > 0); + // } + // }, // Remove a listener removeListener: (callback) => { -- cgit v1.2.3 From cca6d803fc4db729865def23004ab1c4bd279e24 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 26 May 2025 15:10:41 +0700 Subject: error checkboxstate --- src-migrate/utils/checkBoxState.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src-migrate/utils') diff --git a/src-migrate/utils/checkBoxState.js b/src-migrate/utils/checkBoxState.js index 2b527f36..8f7236c3 100644 --- a/src-migrate/utils/checkBoxState.js +++ b/src-migrate/utils/checkBoxState.js @@ -53,15 +53,15 @@ const checkboxUpdateState = { // 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); - // } - // }, + // 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) => { -- cgit v1.2.3 From 3feaad9127ff429b27f0eb69fa6ea539de2f2e8c Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 26 May 2025 20:00:17 +0700 Subject: Cleaning code --- src-migrate/utils/cart.js | 40 +++++++++++ src-migrate/utils/checkBoxState.js | 141 +++++++++++++++++++------------------ 2 files changed, 112 insertions(+), 69 deletions(-) (limited to 'src-migrate/utils') diff --git a/src-migrate/utils/cart.js b/src-migrate/utils/cart.js index ebd771e5..4bdee49a 100644 --- a/src-migrate/utils/cart.js +++ b/src-migrate/utils/cart.js @@ -413,3 +413,43 @@ export const removeSelectedItemsFromCookie = (productIds) => { return {}; } }; + +class QuantityUpdateState { + constructor() { + this.updateItems = new Set(); + this.listeners = new Set(); + } + + startUpdate(itemId) { + this.updateItems.add(itemId); + this.notifyListeners(); + } + + endUpdate(itemId) { + this.updateItems.delete(itemId); + this.notifyListeners(); + } + + isAnyQuantityUpdating() { + return this.updateItems.size > 0; + } + + isItemUpdating(itemId) { + return this.updateItems.has(itemId); + } + + addListener(callback) { + this.listeners.add(callback); + } + + removeListener(callback) { + this.listeners.delete(callback); + } + + notifyListeners() { + const isUpdating = this.isAnyQuantityUpdating(); + this.listeners.forEach(callback => callback(isUpdating)); + } +} + +export const quantityUpdateState = new QuantityUpdateState(); \ No newline at end of file diff --git a/src-migrate/utils/checkBoxState.js b/src-migrate/utils/checkBoxState.js index 8f7236c3..9568c321 100644 --- a/src-migrate/utils/checkBoxState.js +++ b/src-migrate/utils/checkBoxState.js @@ -1,87 +1,90 @@ /** - * Enhanced state manager for checkbox updates - * Tracks both global update state and individual checkbox update states + * State manager for checkbox updates + * Tracks global and individual checkbox update states */ +class CheckboxUpdateState { + constructor() { + this.updateCount = 0; + this.listeners = new Set(); + this.updatingCheckboxIds = new Set(); + } + + // Global update state (for buttons quotation and checkout) + isUpdating() { + return this.updateCount > 0; + } + + // Individual checkbox state + isCheckboxUpdating(itemId) { + return this.updatingCheckboxIds.has(String(itemId)); + } + + // Start update + startUpdate(itemId = null) { + this.updateCount++; -// 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 quotation and checkout) - 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()); + this.updatingCheckboxIds.add(String(itemId)); } - notifyListeners(); - return updateCount; - }, + this.notifyListeners(); + return this.updateCount; + } - // End an update for a specific checkbox - endUpdate: (itemId = null) => { - updateCount = Math.max(0, updateCount - 1); + // End update + endUpdate(itemId = null) { + this.updateCount = Math.max(0, this.updateCount - 1); - // If an item ID is provided, remove it from updating set if (itemId !== null) { - updatingCheckboxIds.delete(itemId.toString()); + this.updatingCheckboxIds.delete(String(itemId)); } - notifyListeners(); - return updateCount; - }, - - // Reset the update counter and clear all updating checkboxes - reset: () => { - updateCount = 0; - updatingCheckboxIds.clear(); - notifyListeners(); - }, + this.notifyListeners(); + return this.updateCount; + } - // Get IDs of all checkboxes currently updating (for debugging) - // getUpdatingCheckboxIds: () => [...updatingCheckboxIds], + // Reset all states + reset() { + this.updateCount = 0; + this.updatingCheckboxIds.clear(); + this.notifyListeners(); + } - // Add a listener function to be called when update state changes - addListener: (callback) => { + // Listener management + 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); + this.listeners.add(callback); + // Immediate callback with current state + callback(this.isUpdating()); } - }); + } + + removeListener(callback) { + this.listeners.delete(callback); + } + + // Debug helpers + getUpdateCount() { + return this.updateCount; + } + + getUpdatingCheckboxIds() { + return [...this.updatingCheckboxIds]; + } + + // Private method to notify listeners + notifyListeners() { + const isUpdating = this.isUpdating(); + + this.listeners.forEach((listener) => { + try { + listener(isUpdating); + } catch (error) { + console.error('Checkbox update state listener error:', error); + } + }); + } } +const checkboxUpdateState = new CheckboxUpdateState(); export default checkboxUpdateState; -- cgit v1.2.3