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/modules/cart/stores/useCartStore.ts | 135 ++++++++++++++++++++++-- 1 file changed, 126 insertions(+), 9 deletions(-) (limited to 'src-migrate/modules/cart/stores') diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts index e7d2cdd3..d211304a 100644 --- a/src-migrate/modules/cart/stores/useCartStore.ts +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -1,6 +1,15 @@ import { create } from 'zustand'; import { CartItem, CartProps } from '~/types/cart'; import { getUserCart } from '~/services/cart'; +import { + syncCartWithCookie, + getCartDataFromCookie, + getSelectedItemsFromCookie, + updateSelectedItemInCookie, + setAllSelectedInCookie, + removeCartItemsFromCookie, + forceResetAllSelectedItems, +} from '~/utils/cart'; type State = { cart: CartProps | null; @@ -17,6 +26,8 @@ type State = { type Action = { loadCart: (userId: number) => Promise; updateCartItem: (updateCart: CartProps) => void; + syncCartWithCookieAndUpdate: (cart: CartProps) => { needsUpdate: boolean }; + forceResetSelection: () => void; }; export const useCartStore = create((set, get) => ({ @@ -29,34 +40,140 @@ export const useCartStore = create((set, get) => ({ tax: 0, grandTotal: 0, }, + loadCart: async (userId) => { if (get().isLoadCart === true) return; set({ isLoadCart: true }); - const cart: CartProps = (await getUserCart(userId)) as CartProps; - set({ cart }); - set({ isLoadCart: false }); + try { + // Fetch cart from API + const cart: CartProps = (await getUserCart(userId)) as CartProps; - const summary = computeSummary(cart); - set({ summary }); + // Sync with cookie and get updated data if needed + const { needsUpdate } = get().syncCartWithCookieAndUpdate(cart); + + // If no update needed from cookie, just set the cart directly + if (!needsUpdate) { + set({ cart }); + } + + // Update summary with current cart + const summary = computeSummary(get().cart!); + set({ summary }); + } catch (error) { + console.error('Failed to load cart from API:', error); + + // Fallback to cookie if API fails + try { + const cartData = getCartDataFromCookie(); + if (Object.keys(cartData).length > 0) { + // Transform cart data from cookie to expected format + const products = Object.values(cartData).map((item) => ({ + 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, + })); + + const fallbackCart: CartProps = { + product_total: products.length, + products, + }; + + set({ cart: fallbackCart }); + const summary = computeSummary(fallbackCart); + set({ summary }); + } + } catch (cookieError) { + console.error('Failed to fallback to cookie:', cookieError); + } + } finally { + set({ isLoadCart: false }); + } }, + updateCartItem: (updatedCart) => { const cart = get().cart; if (!cart) return; set({ cart: updatedCart }); + + // Sync updated cart with cookie + syncCartWithCookie(updatedCart); + const summary = computeSummary(updatedCart); set({ summary }); }, + syncCartWithCookieAndUpdate: (cart) => { + if (!cart) return { needsUpdate: false }; + + // Sync cart with cookie + const result = syncCartWithCookie(cart); + + // If we need to update the cart based on cookie data + if (result.needsUpdate && cart.products) { + // Create updated cart with selections from cookie + const selectedItems = getSelectedItemsFromCookie(); + + const updatedCart = { + ...cart, + products: cart.products.map((item) => ({ + ...item, + selected: + selectedItems[item.id] !== undefined + ? selectedItems[item.id] + : item.selected, + })), + }; + + // Update the store + set({ cart: updatedCart }); + } + + return result; + }, + + forceResetSelection: () => { + const { cart } = get(); + if (!cart) return; + + // Reset all selections in cookie + forceResetAllSelectedItems(); + + // Update the cart in state + const updatedCart = { + ...cart, + products: cart.products.map((item) => ({ + ...item, + selected: false, + })), + }; + + set({ cart: updatedCart }); + + // Update summary + const summary = computeSummary(updatedCart); + set({ summary }); + }, })); const computeSummary = (cart: CartProps) => { let subtotal = 0; let discount = 0; - const PPN: number = process.env.NEXT_PUBLIC_PPN ? parseFloat(process.env.NEXT_PUBLIC_PPN) : 0; - + const PPN: number = process.env.NEXT_PUBLIC_PPN + ? parseFloat(process.env.NEXT_PUBLIC_PPN) + : 0; + for (const item of cart?.products) { if (!item.selected) continue; @@ -74,5 +191,5 @@ const computeSummary = (cart: CartProps) => { let tax = grandTotal - total; // let grandTotal = total + tax; - return { subtotal, discount, total, grandTotal, tax }; -}; \ No newline at end of file + return { subtotal, discount, total, grandTotal, tax }; +}; -- 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/modules/cart/stores/useCartStore.ts | 198 ++++++++++++------------ 1 file changed, 96 insertions(+), 102 deletions(-) (limited to 'src-migrate/modules/cart/stores') diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts index d211304a..dc47b011 100644 --- a/src-migrate/modules/cart/stores/useCartStore.ts +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -5,9 +5,6 @@ import { syncCartWithCookie, getCartDataFromCookie, getSelectedItemsFromCookie, - updateSelectedItemInCookie, - setAllSelectedInCookie, - removeCartItemsFromCookie, forceResetAllSelectedItems, } from '~/utils/cart'; @@ -26,8 +23,8 @@ type State = { type Action = { loadCart: (userId: number) => Promise; updateCartItem: (updateCart: CartProps) => void; - syncCartWithCookieAndUpdate: (cart: CartProps) => { needsUpdate: boolean }; forceResetSelection: () => void; + clearCart: () => void; }; export const useCartStore = create((set, get) => ({ @@ -42,154 +39,151 @@ export const useCartStore = create((set, get) => ({ }, loadCart: async (userId) => { - if (get().isLoadCart === true) return; + if (get().isLoadCart) return; set({ isLoadCart: true }); + try { - // Fetch cart from API const cart: CartProps = (await getUserCart(userId)) as CartProps; - // Sync with cookie and get updated data if needed - const { needsUpdate } = get().syncCartWithCookieAndUpdate(cart); - - // If no update needed from cookie, just set the cart directly - if (!needsUpdate) { + // 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 with current cart + // Update summary const summary = computeSummary(get().cart!); set({ summary }); } catch (error) { - console.error('Failed to load cart from API:', error); - - // Fallback to cookie if API fails - try { - const cartData = getCartDataFromCookie(); - if (Object.keys(cartData).length > 0) { - // Transform cart data from cookie to expected format - const products = Object.values(cartData).map((item) => ({ - 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, - })); - - const fallbackCart: CartProps = { - product_total: products.length, - products, - }; - - set({ cart: fallbackCart }); - const summary = computeSummary(fallbackCart); - set({ summary }); - } - } catch (cookieError) { - console.error('Failed to fallback to cookie:', cookieError); - } + console.error('Failed to load cart:', error); + + // Fallback to cookie data + await handleFallbackFromCookie(); } finally { set({ isLoadCart: false }); } }, updateCartItem: (updatedCart) => { - const cart = get().cart; - if (!cart) return; - set({ cart: updatedCart }); - - // Sync updated cart with cookie syncCartWithCookie(updatedCart); const summary = computeSummary(updatedCart); set({ summary }); }, - syncCartWithCookieAndUpdate: (cart) => { - if (!cart) return { needsUpdate: false }; - - // Sync cart with cookie - const result = syncCartWithCookie(cart); - - // If we need to update the cart based on cookie data - if (result.needsUpdate && cart.products) { - // Create updated cart with selections from cookie - const selectedItems = getSelectedItemsFromCookie(); - - const updatedCart = { - ...cart, - products: cart.products.map((item) => ({ - ...item, - selected: - selectedItems[item.id] !== undefined - ? selectedItems[item.id] - : item.selected, - })), - }; - - // Update the store - set({ cart: updatedCart }); - } - - return result; - }, - forceResetSelection: () => { const { cart } = get(); if (!cart) return; - // Reset all selections in cookie forceResetAllSelectedItems(); - // Update the cart in state const updatedCart = { ...cart, - products: cart.products.map((item) => ({ - ...item, - selected: false, - })), + products: cart.products.map((item) => ({ ...item, selected: false })), }; set({ cart: updatedCart }); - // Update summary 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; + + 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 -- cgit v1.2.3 From 3f992f62c54e09254c48d653c2cd138df1cbd8e2 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Sat, 31 May 2025 14:33:24 +0700 Subject: fix error deployment --- src-migrate/modules/cart/stores/useCartStore.ts | 98 +++++++++++++++++-------- 1 file changed, 66 insertions(+), 32 deletions(-) (limited to 'src-migrate/modules/cart/stores') diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts index dc47b011..69cf0384 100644 --- a/src-migrate/modules/cart/stores/useCartStore.ts +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -8,24 +8,32 @@ import { forceResetAllSelectedItems, } from '~/utils/cart'; -type State = { +interface Summary { + subtotal: number; + discount: number; + total: number; + tax: number; + grandTotal: number; +} + +interface SyncResult { + cartData?: Record; + selectedItems?: Record; + needsUpdate: boolean; +} + +interface State { cart: CartProps | null; isLoadCart: boolean; - summary: { - subtotal: number; - discount: number; - total: number; - tax: number; - grandTotal: number; - }; -}; + summary: Summary; +} -type Action = { +interface Action { loadCart: (userId: number) => Promise; updateCartItem: (updateCart: CartProps) => void; forceResetSelection: () => void; clearCart: () => void; -}; +} export const useCartStore = create((set, get) => ({ cart: null, @@ -38,7 +46,7 @@ export const useCartStore = create((set, get) => ({ grandTotal: 0, }, - loadCart: async (userId) => { + loadCart: async (userId: number): Promise => { if (get().isLoadCart) return; set({ isLoadCart: true }); @@ -47,12 +55,15 @@ export const useCartStore = create((set, get) => ({ const cart: CartProps = (await getUserCart(userId)) as CartProps; // Sync with cookie data - const syncResult = syncCartWithCookie(cart); + const syncResult = syncCartWithCookie(cart) as SyncResult; if (syncResult?.needsUpdate && cart.products) { - const selectedItems = getSelectedItemsFromCookie(); + const selectedItems = getSelectedItemsFromCookie() as Record< + number, + boolean + >; - const updatedCart = { + const updatedCart: CartProps = { ...cart, products: cart.products.map((item) => ({ ...item, @@ -81,7 +92,7 @@ export const useCartStore = create((set, get) => ({ } }, - updateCartItem: (updatedCart) => { + updateCartItem: (updatedCart: CartProps): void => { set({ cart: updatedCart }); syncCartWithCookie(updatedCart); @@ -89,13 +100,13 @@ export const useCartStore = create((set, get) => ({ set({ summary }); }, - forceResetSelection: () => { + forceResetSelection: (): void => { const { cart } = get(); if (!cart) return; forceResetAllSelectedItems(); - const updatedCart = { + const updatedCart: CartProps = { ...cart, products: cart.products.map((item) => ({ ...item, selected: false })), }; @@ -106,7 +117,7 @@ export const useCartStore = create((set, get) => ({ set({ summary }); }, - clearCart: () => { + clearCart: (): void => { set({ cart: null, summary: { @@ -121,13 +132,15 @@ export const useCartStore = create((set, get) => ({ })); // Helper function for cookie fallback -const handleFallbackFromCookie = async () => { +const handleFallbackFromCookie = async (): Promise => { try { - const cartData = getCartDataFromCookie(); + const cartData = getCartDataFromCookie() as Record; if (Object.keys(cartData).length === 0) return; - const products = Object.values(cartData).map(transformCookieItemToProduct); + const products: CartItem[] = Object.values(cartData).map( + transformCookieItemToProduct + ); const fallbackCart: CartProps = { product_total: products.length, @@ -145,22 +158,43 @@ const handleFallbackFromCookie = async () => { // Helper function to transform cookie item to product format const transformCookieItemToProduct = (item: any): CartItem => ({ + image_program: item.image_program || '', 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, + can_buy: true, + cart_type: item.cart_type, + id: item.id, + name: item.product?.name || item.program_line?.name || '', + stock: 0, + is_in_bu: false, + on_hand_qty: 0, + available_quantity: 0, + weight: 0, + attributes: [], + parent: { + id: 0, + name: '', + image: '', + }, + price: item.price || { + price: 0, + discount_percentage: 0, + price_discount: 0, + }, + manufacture: { + id: 0, + name: '', + }, + has_flashsale: false, + subtotal: 0, + code: item.code, + image: item.image, package_price: item.package_price, - source: item.source, }); // Helper function to compute cart summary -const computeSummary = (cart: CartProps) => { +const computeSummary = (cart: CartProps): Summary => { if (!cart?.products) { return { subtotal: 0, discount: 0, total: 0, grandTotal: 0, tax: 0 }; } @@ -186,4 +220,4 @@ const computeSummary = (cart: CartProps) => { const tax = grandTotal - total; return { subtotal, discount, total, grandTotal, tax }; -}; \ No newline at end of file +}; -- cgit v1.2.3 From 11ee2946884ddac60947761a04f3dda295781ec5 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 4 Jun 2025 10:27:02 +0700 Subject: fix cart tax --- src-migrate/modules/cart/stores/useCartStore.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src-migrate/modules/cart/stores') diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts index 69cf0384..be48b1ed 100644 --- a/src-migrate/modules/cart/stores/useCartStore.ts +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -193,13 +193,12 @@ const transformCookieItemToProduct = (item: any): CartItem => ({ package_price: item.package_price, }); -// Helper function to compute cart summary const computeSummary = (cart: CartProps): Summary => { if (!cart?.products) { return { subtotal: 0, discount: 0, total: 0, grandTotal: 0, tax: 0 }; } - const PPN = parseFloat(process.env.NEXT_PUBLIC_PPN || '0'); + const PPN = parseFloat(process.env.NEXT_PUBLIC_PPN || '1.11'); let subtotal = 0; let discount = 0; @@ -216,8 +215,10 @@ const computeSummary = (cart: CartProps): Summary => { } const total = subtotal - discount; - const grandTotal = total * (1 + PPN); - const tax = grandTotal - total; + + // PERBAIKAN: + const tax = total * (PPN - 1); + const grandTotal = total + tax; return { subtotal, discount, total, grandTotal, tax }; }; -- cgit v1.2.3