From 57b96493fb3efd177ce250ca430137db943ddbfa Mon Sep 17 00:00:00 2001 From: w3bdesign <45217974+w3bdesign@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:33:09 +0200 Subject: [PATCH 1/3] Refactor cart store to use useAsyncQuery and improve mutations Replaces manual cart fetching with useAsyncQuery for better reactivity and error handling. Refactors add, update, and clear cart actions to use dedicated mutation instances, consolidates loading state, and improves cart clearing logic for immediate UI updates. Removes unused variables and streamlines error handling. --- store/useCart.js | 82 +++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/store/useCart.js b/store/useCart.js index 2e52493a..2c8d2884 100644 --- a/store/useCart.js +++ b/store/useCart.js @@ -1,6 +1,6 @@ import { defineStore } from "pinia"; +import { computed, ref, watch } from "vue"; import { useMutation } from "@vue/apollo-composable"; -import { computed, ref } from "vue"; import ADD_TO_CART_MUTATION from "@/apollo/mutations/ADD_TO_CART_MUTATION.gql"; import UPDATE_CART_MUTATION from "@/apollo/mutations/UPDATE_CART_MUTATION.gql"; @@ -10,29 +10,26 @@ export const useCart = defineStore( "cartState", () => { const cart = ref([]); - const loading = ref(false); - const error = ref(null); const cartTotals = ref({}); - const { $apollo } = useNuxtApp(); - - const fetchCart = async () => { - try { - const { data } = await useAsyncData("cart", async () => { - const { data } = await $apollo.client.query({ - query: GET_CART_QUERY, - fetchPolicy: "network-only", - }); - return data.cart; - }); + const { + data: cartData, + pending: loading, + error, + refresh: refetchCart, + } = useAsyncQuery(GET_CART_QUERY); - if (data.value) { - updateCartState(data.value); + watch( + cartData, + (newCartData) => { + if (newCartData && newCartData.cart) { + updateCartState(newCartData.cart); + } else if (newCartData && newCartData.cart === null) { + updateCartState(null); } - } catch (e) { - error.value = e; - } - }; + }, + { immediate: true }, + ); const updateCartState = (newCart) => { if (!newCart) { @@ -64,62 +61,61 @@ export const useCart = defineStore( }; }; + const { mutate: addToCartMutation, loading: addToCartLoading } = + useMutation(ADD_TO_CART_MUTATION); + const { mutate: updateCartMutation, loading: updateCartLoading } = + useMutation(UPDATE_CART_MUTATION); + const addToCart = async (product, quantity = 1) => { - loading.value = true; - error.value = null; try { - const { mutate } = useMutation(ADD_TO_CART_MUTATION); - await mutate({ + await addToCartMutation({ input: { productId: product.databaseId, quantity: quantity, }, }); - await fetchCart(); + await refetchCart(); } catch (err) { - error.value = err; - } finally { - loading.value = false; + console.error("Error adding to cart:", err); } }; const updateCartItemQuantity = async (key, quantity) => { - loading.value = true; - error.value = null; try { - const { mutate } = useMutation(UPDATE_CART_MUTATION); - await mutate({ + await updateCartMutation({ input: { - items: [{ key, quantity }], + items: Array.isArray(key) ? key : [{ key, quantity }], }, }); - await fetchCart(); + await refetchCart(); } catch (err) { - error.value = err; - await fetchCart(); - } finally { - loading.value = false; + console.error("Error updating cart item quantity:", err); + await refetchCart(); } }; const removeProductFromCart = async (key) => { try { - const isLastItem = cart.value.length === 1; + const isLastItem = + cart.value.length === 1 && cart.value[0].key === key; await updateCartItemQuantity(key, 0); if (isLastItem) { + updateCartState(null); // Clear cart locally to update UI instantly await navigateTo("/"); } } catch (err) { - error.value = err; + console.error("Error removing product from cart:", err); } }; const clearCart = async () => { + if (!cart.value.length) return; const itemKeys = cart.value.map((item) => ({ key: item.key, quantity: 0, })); await updateCartItemQuantity(itemKeys); + updateCartState(null); // Clear cart locally }; const cartQuantity = computed(() => { @@ -136,7 +132,9 @@ export const useCart = defineStore( return { cart, - loading, + loading: computed( + () => loading.value || addToCartLoading.value || updateCartLoading.value, + ), error, cartTotals, addToCart, @@ -146,7 +144,7 @@ export const useCart = defineStore( cartQuantity, cartSubtotal, cartTotal, - fetchCart, + refetch: refetchCart, }; }, { From 0d492126f89597fc437bf463e089796677c3f02d Mon Sep 17 00:00:00 2001 From: w3bdesign <45217974+w3bdesign@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:35:09 +0200 Subject: [PATCH 2/3] Remove async cart fetch on plugin initialization The cartUpdater plugin no longer fetches the cart asynchronously during initialization. It now simply initializes the cart store by calling useCart(). --- plugins/cartUpdater.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/cartUpdater.js b/plugins/cartUpdater.js index 6ef602d6..32262d2b 100644 --- a/plugins/cartUpdater.js +++ b/plugins/cartUpdater.js @@ -1,6 +1,5 @@ import { useCart } from "@/store/useCart"; -export default defineNuxtPlugin(async (nuxtApp) => { - const cart = useCart(); - await cart.fetchCart(); +export default defineNuxtPlugin(() => { + useCart(); }); From ba3cdaa769fc61dae90b731707c0f238d4deab91 Mon Sep 17 00:00:00 2001 From: w3bdesign <45217974+w3bdesign@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:37:29 +0200 Subject: [PATCH 3/3] Refactor cart removal and loading state formatting Simplified the isLastItem assignment in removeProductFromCart and improved formatting for the loading computed property for better readability. --- store/useCart.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/store/useCart.js b/store/useCart.js index 2c8d2884..978d6df0 100644 --- a/store/useCart.js +++ b/store/useCart.js @@ -96,8 +96,7 @@ export const useCart = defineStore( const removeProductFromCart = async (key) => { try { - const isLastItem = - cart.value.length === 1 && cart.value[0].key === key; + const isLastItem = cart.value.length === 1 && cart.value[0].key === key; await updateCartItemQuantity(key, 0); if (isLastItem) { updateCartState(null); // Clear cart locally to update UI instantly @@ -133,7 +132,8 @@ export const useCart = defineStore( return { cart, loading: computed( - () => loading.value || addToCartLoading.value || updateCartLoading.value, + () => + loading.value || addToCartLoading.value || updateCartLoading.value, ), error, cartTotals,