diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2025-05-31 02:33:14 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2025-05-31 02:33:14 +0000 |
| commit | 2a1dea70b8f0062fe8eebeb7139a7b77a24e220b (patch) | |
| tree | e7a5db13b2655cbdfb1c81859e240652fdc87bbb /src-migrate/modules/cart/stores | |
| parent | 0b2e31247d4fe7eb1432079979478a0cfc38d049 (diff) | |
| parent | 2732c04b36f98a25895826b28003b1e2c56ad952 (diff) | |
Merged in fix_responsive_cart (pull request #413)
<miqdad> Fix unresponsive cart
Diffstat (limited to 'src-migrate/modules/cart/stores')
| -rw-r--r-- | src-migrate/modules/cart/stores/useCartStore.ts | 151 |
1 files changed, 131 insertions, 20 deletions
diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts index e7d2cdd3..dc47b011 100644 --- a/src-migrate/modules/cart/stores/useCartStore.ts +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -1,6 +1,12 @@ import { create } from 'zustand'; import { CartItem, CartProps } from '~/types/cart'; import { getUserCart } from '~/services/cart'; +import { + syncCartWithCookie, + getCartDataFromCookie, + getSelectedItemsFromCookie, + forceResetAllSelectedItems, +} from '~/utils/cart'; type State = { cart: CartProps | null; @@ -17,6 +23,8 @@ type State = { type Action = { loadCart: (userId: number) => Promise<void>; updateCartItem: (updateCart: CartProps) => void; + forceResetSelection: () => void; + clearCart: () => void; }; export const useCartStore = create<State & Action>((set, get) => ({ @@ -29,50 +37,153 @@ export const useCartStore = create<State & Action>((set, get) => ({ tax: 0, grandTotal: 0, }, + loadCart: async (userId) => { - if (get().isLoadCart === true) return; + if (get().isLoadCart) return; set({ isLoadCart: true }); - const cart: CartProps = (await getUserCart(userId)) as CartProps; - set({ cart }); - set({ isLoadCart: false }); - const summary = computeSummary(cart); - set({ summary }); + try { + const cart: CartProps = (await getUserCart(userId)) as CartProps; + + // Sync with cookie data + const syncResult = syncCartWithCookie(cart); + + if (syncResult?.needsUpdate && cart.products) { + const selectedItems = getSelectedItemsFromCookie(); + + const updatedCart = { + ...cart, + products: cart.products.map((item) => ({ + ...item, + selected: + selectedItems[item.id] !== undefined + ? selectedItems[item.id] + : item.selected, + })), + }; + + set({ cart: updatedCart }); + } else { + set({ cart }); + } + + // Update summary + const summary = computeSummary(get().cart!); + set({ summary }); + } catch (error) { + console.error('Failed to load cart:', error); + + // Fallback to cookie data + await handleFallbackFromCookie(); + } finally { + set({ isLoadCart: false }); + } }, + updateCartItem: (updatedCart) => { - const cart = get().cart; + set({ cart: updatedCart }); + syncCartWithCookie(updatedCart); + + const summary = computeSummary(updatedCart); + set({ summary }); + }, + + forceResetSelection: () => { + const { cart } = get(); if (!cart) return; + forceResetAllSelectedItems(); + + const updatedCart = { + ...cart, + products: cart.products.map((item) => ({ ...item, selected: false })), + }; + set({ cart: updatedCart }); + const summary = computeSummary(updatedCart); set({ summary }); }, + clearCart: () => { + set({ + cart: null, + summary: { + subtotal: 0, + discount: 0, + total: 0, + tax: 0, + grandTotal: 0, + }, + }); + }, })); +// Helper function for cookie fallback +const handleFallbackFromCookie = async () => { + try { + const cartData = getCartDataFromCookie(); + + if (Object.keys(cartData).length === 0) return; + + const products = Object.values(cartData).map(transformCookieItemToProduct); + + const fallbackCart: CartProps = { + product_total: products.length, + products, + }; + + useCartStore.setState({ cart: fallbackCart }); + + const summary = computeSummary(fallbackCart); + useCartStore.setState({ summary }); + } catch (error) { + console.error('Cookie fallback failed:', error); + } +}; + +// Helper function to transform cookie item to product format +const transformCookieItemToProduct = (item: any): CartItem => ({ + cart_id: item.cart_id, + id: item.id, + cart_type: item.cart_type, + product_id: item.product?.id, + product_name: item.product?.name, + program_line_id: item.program_line?.id, + program_line_name: item.program_line?.name, + quantity: item.quantity, + selected: item.selected, + price: item.price, + package_price: item.package_price, + source: item.source, +}); + +// Helper function to compute cart summary const computeSummary = (cart: CartProps) => { + if (!cart?.products) { + return { subtotal: 0, discount: 0, total: 0, grandTotal: 0, tax: 0 }; + } + + const PPN = parseFloat(process.env.NEXT_PUBLIC_PPN || '0'); let subtotal = 0; let discount = 0; - const PPN: number = process.env.NEXT_PUBLIC_PPN ? parseFloat(process.env.NEXT_PUBLIC_PPN) : 0; - - for (const item of cart?.products) { + for (const item of cart.products) { if (!item.selected) continue; - let price = 0; - if (item.cart_type === 'promotion') - price = (item?.package_price || 0) * item.quantity; - else if (item.cart_type === 'product') - price = item.price.price * item.quantity; + const price = + item.cart_type === 'promotion' + ? (item?.package_price || 0) * item.quantity + : item.price.price * item.quantity; subtotal += price; discount += price - item.price.price_discount * item.quantity; } - let total = subtotal - discount; - let grandTotal = total * PPN; - let tax = grandTotal - total; - // let grandTotal = total + tax; - return { subtotal, discount, total, grandTotal, tax }; + const total = subtotal - discount; + const grandTotal = total * (1 + PPN); + const tax = grandTotal - total; + + return { subtotal, discount, total, grandTotal, tax }; };
\ No newline at end of file |
