summaryrefslogtreecommitdiff
path: root/src-migrate/modules/cart/stores
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2025-07-29 09:46:05 +0700
committerit-fixcomart <it@fixcomart.co.id>2025-07-29 09:46:05 +0700
commit077467cf53b46d8049df8b812577cd1a03011eba (patch)
tree0dc641a9acb1237a3caca3f7f8a157a3e938c0b8 /src-migrate/modules/cart/stores
parent0d28dc8ff5fb8c5399e356ed6ecae4fce2019ca6 (diff)
parentdc31efb2fec4c7b79917324d922ae820c4b5bb50 (diff)
<hafid> merging new release
Diffstat (limited to 'src-migrate/modules/cart/stores')
-rw-r--r--src-migrate/modules/cart/stores/useCartStore.ts214
1 files changed, 180 insertions, 34 deletions
diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts
index e7d2cdd3..be48b1ed 100644
--- a/src-migrate/modules/cart/stores/useCartStore.ts
+++ b/src-migrate/modules/cart/stores/useCartStore.ts
@@ -1,23 +1,39 @@
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 = {
+interface Summary {
+ subtotal: number;
+ discount: number;
+ total: number;
+ tax: number;
+ grandTotal: number;
+}
+
+interface SyncResult {
+ cartData?: Record<string, any>;
+ selectedItems?: Record<number, boolean>;
+ 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<void>;
updateCartItem: (updateCart: CartProps) => void;
-};
+ forceResetSelection: () => void;
+ clearCart: () => void;
+}
export const useCartStore = create<State & Action>((set, get) => ({
cart: null,
@@ -29,50 +45,180 @@ export const useCartStore = create<State & Action>((set, get) => ({
tax: 0,
grandTotal: 0,
},
- loadCart: async (userId) => {
- if (get().isLoadCart === true) return;
+
+ loadCart: async (userId: number): Promise<void> => {
+ if (get().isLoadCart) return;
set({ isLoadCart: true });
- const cart: CartProps = (await getUserCart(userId)) as CartProps;
- set({ cart });
- set({ isLoadCart: false });
- const summary = computeSummary(cart);
+ try {
+ const cart: CartProps = (await getUserCart(userId)) as CartProps;
+
+ // Sync with cookie data
+ const syncResult = syncCartWithCookie(cart) as SyncResult;
+
+ if (syncResult?.needsUpdate && cart.products) {
+ const selectedItems = getSelectedItemsFromCookie() as Record<
+ number,
+ boolean
+ >;
+
+ const updatedCart: CartProps = {
+ ...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: CartProps): void => {
+ set({ cart: updatedCart });
+ syncCartWithCookie(updatedCart);
+
+ const summary = computeSummary(updatedCart);
set({ summary });
},
- updateCartItem: (updatedCart) => {
- const cart = get().cart;
+
+ forceResetSelection: (): void => {
+ const { cart } = get();
if (!cart) return;
+ forceResetAllSelectedItems();
+
+ const updatedCart: CartProps = {
+ ...cart,
+ products: cart.products.map((item) => ({ ...item, selected: false })),
+ };
+
set({ cart: updatedCart });
+
const summary = computeSummary(updatedCart);
set({ summary });
},
+ clearCart: (): void => {
+ set({
+ cart: null,
+ summary: {
+ subtotal: 0,
+ discount: 0,
+ total: 0,
+ tax: 0,
+ grandTotal: 0,
+ },
+ });
+ },
}));
-const computeSummary = (cart: CartProps) => {
+// Helper function for cookie fallback
+const handleFallbackFromCookie = async (): Promise<void> => {
+ try {
+ const cartData = getCartDataFromCookie() as Record<string, any>;
+
+ if (Object.keys(cartData).length === 0) return;
+
+ const products: CartItem[] = 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 => ({
+ image_program: item.image_program || '',
+ cart_id: item.cart_id,
+ quantity: item.quantity,
+ selected: item.selected,
+ 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,
+});
+
+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 || '1.11');
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 };
-}; \ No newline at end of file
+ const total = subtotal - discount;
+
+ // PERBAIKAN:
+ const tax = total * (PPN - 1);
+ const grandTotal = total + tax;
+
+ return { subtotal, discount, total, grandTotal, tax };
+};