Skip to content

Commit c1a3062

Browse files
committed
Update useCart.js
1 parent 231621d commit c1a3062

File tree

1 file changed

+112
-88
lines changed

1 file changed

+112
-88
lines changed

store/useCart.js

Lines changed: 112 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,127 @@
11
import { defineStore } from "pinia";
2-
2+
import { useQuery, useMutation } from "@vue/apollo-composable";
3+
import { computed, ref, watch } from "vue";
34
import ADD_TO_CART_MUTATION from "@/apollo/mutations/ADD_TO_CART_MUTATION.gql";
5+
import UPDATE_CART_MUTATION from "@/apollo/mutations/UPDATE_CART_MUTATION.gql";
6+
import GET_CART_QUERY from "@/apollo/queries/GET_CART_QUERY.gql";
47

5-
/**
6-
* Manages a shopping cart store using the Pinia library.
7-
*
8-
* @typedef {Object} CartState
9-
* @property {Array} cart - The array representing the cart.
10-
* @property {boolean} loading - The loading status of the cart.
11-
* @property {string|null} error - The error message, if any.
12-
*/
8+
export const useCart = defineStore("cartState", () => {
9+
const cart = ref([]);
10+
const loading = ref(false);
11+
const error = ref(null);
12+
const cartTotals = ref({});
1313

14-
const state = {
15-
cart: [],
16-
loading: false,
17-
error: null,
18-
};
14+
const { result: cartResult, loading: cartLoading, refetch } = useQuery(GET_CART_QUERY, null, { fetchPolicy: 'network-only' });
1915

20-
export const useCart = defineStore("cartState", {
21-
state: () => state,
22-
actions: {
23-
async addToCart(product) {
24-
this.loading = true;
25-
try {
26-
const { mutate } = useMutation(ADD_TO_CART_MUTATION);
27-
const response = await mutate({
28-
input: {
29-
productId: product.databaseId,
30-
quantity: 1,
31-
},
32-
});
16+
watch(cartResult, (newCartResult) => {
17+
if (newCartResult && newCartResult.cart) {
18+
cart.value = newCartResult.cart.contents.nodes.map(item => ({
19+
key: item.key,
20+
product: item.product.node,
21+
variation: item.variation ? item.variation.node : null,
22+
quantity: item.quantity,
23+
total: item.total,
24+
subtotal: item.subtotal,
25+
subtotalTax: item.subtotalTax
26+
}));
3327

34-
if (response.data && response.data.addToCart) {
35-
this.loading = false;
36-
const newCartItem = response.data.addToCart.cartItem;
37-
const foundProductInCartIndex = this.cart.findIndex(
38-
(cartProduct) => newCartItem.product.node.slug === cartProduct.slug
39-
);
28+
cartTotals.value = {
29+
subtotal: newCartResult.cart.subtotal,
30+
subtotalTax: newCartResult.cart.subtotalTax,
31+
shippingTax: newCartResult.cart.shippingTax,
32+
shippingTotal: newCartResult.cart.shippingTotal,
33+
total: newCartResult.cart.total,
34+
totalTax: newCartResult.cart.totalTax,
35+
feeTax: newCartResult.cart.feeTax,
36+
feeTotal: newCartResult.cart.feeTotal,
37+
discountTax: newCartResult.cart.discountTax,
38+
discountTotal: newCartResult.cart.discountTotal
39+
};
40+
}
41+
});
4042

41-
if (foundProductInCartIndex > -1) {
42-
this.cart[foundProductInCartIndex].quantity += 1;
43-
} else {
44-
// We need to construct a cart item that matches the expected structure in `this.cart`
45-
const productCopy = {
46-
...newCartItem.product.node,
47-
quantity: newCartItem.quantity,
48-
price: newCartItem.total, // Assuming 'total' is the price for one item
49-
slug: newCartItem.product.node.slug,
50-
};
43+
const addToCart = async (product, quantity = 1) => {
44+
loading.value = true;
45+
error.value = null;
46+
try {
47+
const { mutate } = useMutation(ADD_TO_CART_MUTATION);
48+
await mutate({
49+
input: {
50+
productId: product.databaseId,
51+
quantity: quantity,
52+
},
53+
});
54+
await refetch();
55+
} catch (err) {
56+
console.error("Error adding to cart:", err);
57+
error.value = err.message || "An error occurred while adding to cart.";
58+
} finally {
59+
loading.value = false;
60+
}
61+
};
5162

52-
this.cart.push(productCopy);
53-
}
54-
} else {
55-
// Handle the case where the mutation does not return the expected data
56-
this.error = "Did not receive expected cart data from the server.";
57-
}
58-
} catch (error) {
59-
this.error = error.message || "An error occurred while adding to cart.";
60-
} finally {
61-
this.loading = false;
62-
}
63-
},
63+
const updateCartItemQuantity = async (key, quantity) => {
64+
loading.value = true;
65+
error.value = null;
66+
try {
67+
const { mutate } = useMutation(UPDATE_CART_MUTATION);
68+
await mutate({
69+
input: {
70+
items: [{ key, quantity }],
71+
},
72+
});
73+
await refetch();
74+
} catch (err) {
75+
console.error("Error updating cart:", err);
76+
error.value = err.message || "An error occurred while updating the cart.";
77+
} finally {
78+
loading.value = false;
79+
}
80+
};
6481

65-
removeProductFromCart(product) {
66-
this.cart.splice(this.cart.indexOf(product), 1);
67-
},
68-
clearCart() {
69-
this.cart.length = 0;
70-
},
71-
},
72-
getters: {
73-
getCartQuantity() {
74-
if (!this.cart) {
75-
console.error("Cart is undefined");
76-
return 0;
77-
}
78-
return this.cart.reduce((total, product) => total + product.quantity, 0);
79-
},
82+
const removeProductFromCart = async (key) => {
83+
return updateCartItemQuantity(key, 0);
84+
};
8085

81-
getCartTotal() {
82-
const currencySymbol = useRuntimeConfig().public.currencySymbol || "kr";
83-
84-
const total = this.cart.reduce((total, product) => {
85-
// Assuming product.price is a string that includes the currency symbol
86-
const numericPrice = product.price
87-
.replace(currencySymbol, "")
88-
.replace(/[^0-9.]+/g, "");
86+
const clearCart = async () => {
87+
loading.value = true;
88+
error.value = null;
89+
try {
90+
for (const item of cart.value) {
91+
await removeProductFromCart(item.key);
92+
}
93+
} catch (err) {
94+
console.error("Error clearing cart:", err);
95+
error.value = err.message || "An error occurred while clearing the cart.";
96+
} finally {
97+
loading.value = false;
98+
}
99+
};
89100

90-
// Convert the cleaned string to a floating-point number
91-
const price = parseFloat(numericPrice);
101+
const cartQuantity = computed(() => {
102+
return cart.value.reduce((total, item) => total + item.quantity, 0);
103+
});
92104

93-
const productTotal = price * product.quantity;
105+
const cartSubtotal = computed(() => {
106+
return cartTotals.value.subtotal || '0';
107+
});
94108

95-
return total + productTotal;
96-
}, 0);
109+
const cartTotal = computed(() => {
110+
return cartTotals.value.total || '0';
111+
});
97112

98-
// Format the total with the currency symbol and return it
99-
return `${currencySymbol} ${total.toFixed(2)}`;
100-
},
101-
},
102-
persist: true,
113+
return {
114+
cart,
115+
loading,
116+
error,
117+
cartTotals,
118+
addToCart,
119+
updateCartItemQuantity,
120+
removeProductFromCart,
121+
clearCart,
122+
cartQuantity,
123+
cartSubtotal,
124+
cartTotal,
125+
refetch,
126+
};
103127
});

0 commit comments

Comments
 (0)