diff --git a/src/components/PlansSection.tsx b/src/components/PlansSection.tsx index bb11a8d..c7e26be 100644 --- a/src/components/PlansSection.tsx +++ b/src/components/PlansSection.tsx @@ -53,7 +53,7 @@ const PlansSection = () => { const [checkoutLoading, setCheckoutLoading] = useState(false); const { products, isLoading: productsLoading } = useShopifyProducts("product_type:Abonnemang"); - const { addItem, getCheckoutUrl, isLoading: cartLoading } = useCartStore(); + const { addItem, getCheckoutUrl, clearCart, isLoading: cartLoading } = useCartStore(); const handleSelectPlan = async (plan: typeof planDetails[0]) => { // Find the matching Shopify product @@ -74,6 +74,9 @@ const PlansSection = () => { setSelectedPlan(plan.name); try { + // Clear any existing cart items first for a clean checkout + clearCart(); + await addItem({ product: shopifyProduct, variantId: variant.id, diff --git a/src/lib/shopify.ts b/src/lib/shopify.ts index d262494..9bc0a98 100644 --- a/src/lib/shopify.ts +++ b/src/lib/shopify.ts @@ -138,7 +138,29 @@ export const STOREFRONT_PRODUCTS_QUERY = ` // Cart mutations export const CART_QUERY = ` query cart($id: ID!) { - cart(id: $id) { id totalQuantity } + cart(id: $id) { + id + totalQuantity + checkoutUrl + lines(first: 100) { + edges { + node { + id + quantity + merchandise { + ... on ProductVariant { + id + title + price { + amount + currencyCode + } + } + } + } + } + } + } } `; diff --git a/src/stores/cartStore.ts b/src/stores/cartStore.ts index 2f4d015..1491575 100644 --- a/src/stores/cartStore.ts +++ b/src/stores/cartStore.ts @@ -208,15 +208,58 @@ export const useCartStore = create()( getCheckoutUrl: () => get().checkoutUrl, syncCart: async () => { - const { cartId, isSyncing, clearCart } = get(); + const { cartId, isSyncing, clearCart, items } = get(); if (!cartId || isSyncing) return; set({ isSyncing: true }); try { const data = await storefrontApiRequest(CART_QUERY, { id: cartId }); - if (!data) return; + if (!data) { + set({ isSyncing: false }); + return; + } + const cart = data?.data?.cart; - if (!cart || cart.totalQuantity === 0) clearCart(); + + // Cart doesn't exist or is empty - clear local state + if (!cart || cart.totalQuantity === 0) { + clearCart(); + return; + } + + // Sync local items with Shopify cart + const shopifyLines = cart.lines?.edges || []; + + // Build a map of Shopify line items by variant ID + const shopifyItemsMap = new Map(); + for (const edge of shopifyLines) { + const variantId = edge.node.merchandise.id; + shopifyItemsMap.set(variantId, { + lineId: edge.node.id, + quantity: edge.node.quantity + }); + } + + // Update local items to match Shopify state + const syncedItems = items + .filter(item => shopifyItemsMap.has(item.variantId)) + .map(item => { + const shopifyItem = shopifyItemsMap.get(item.variantId)!; + return { + ...item, + lineId: shopifyItem.lineId, + quantity: shopifyItem.quantity + }; + }); + + // Update checkout URL if available + const checkoutUrl = cart.checkoutUrl ? formatCheckoutUrl(cart.checkoutUrl) : get().checkoutUrl; + + if (syncedItems.length === 0) { + clearCart(); + } else { + set({ items: syncedItems, checkoutUrl }); + } } catch (error) { console.error('Failed to sync cart with Shopify:', error); } finally {