|
@@ -1,128 +1,59 @@
|
|
|
"use client";
|
|
"use client";
|
|
|
|
|
|
|
|
-import { useCallback } from "react";
|
|
|
|
|
|
|
+import { useCallback, useState } from "react";
|
|
|
import { useCustomToast } from "./useToast";
|
|
import { useCustomToast } from "./useToast";
|
|
|
import { useAppDispatch } from "@/store/hooks";
|
|
import { useAppDispatch } from "@/store/hooks";
|
|
|
import { addItem, clearCart } from "@/store/slices/cart-slice";
|
|
import { addItem, clearCart } from "@/store/slices/cart-slice";
|
|
|
import { isObject } from "@utils/type-guards";
|
|
import { isObject } from "@utils/type-guards";
|
|
|
-import {
|
|
|
|
|
- setCookie,
|
|
|
|
|
- getIsGuest,
|
|
|
|
|
- getGuestCartToken,
|
|
|
|
|
- deleteGuestCookie
|
|
|
|
|
-} from "@utils/cookie-tools";
|
|
|
|
|
-import { useGuestCartToken } from "./useGuestCartToken";
|
|
|
|
|
-import { IS_GUEST,GUEST_CART_TOKEN,GUEST_CART_ID } from "@/utils/constants";
|
|
|
|
|
import { useMutation, useApolloClient } from "@apollo/client/react";
|
|
import { useMutation, useApolloClient } from "@apollo/client/react";
|
|
|
import {
|
|
import {
|
|
|
- CREATE_ADD_PRODUCT_IN_CART,
|
|
|
|
|
- REMOVE_CART_ITEM,
|
|
|
|
|
UPDATE_CART_ITEM,
|
|
UPDATE_CART_ITEM,
|
|
|
} from "@/graphql";
|
|
} from "@/graphql";
|
|
|
import { formatCartDetail } from "@/utils/cartDetailTools";
|
|
import { formatCartDetail } from "@/utils/cartDetailTools";
|
|
|
import {handleApolloBusinessError} from "@/lib/ApolloErrorHandler";
|
|
import {handleApolloBusinessError} from "@/lib/ApolloErrorHandler";
|
|
|
-
|
|
|
|
|
|
|
+import {addProductToCartAction, deleteCartProductAction} from '@/actions';
|
|
|
|
|
+import { AddToCartVariables, AddProductInCart } from "@/types/cart/type";
|
|
|
|
|
|
|
|
export const useAddProduct = () => {
|
|
export const useAddProduct = () => {
|
|
|
const dispatch = useAppDispatch();
|
|
const dispatch = useAppDispatch();
|
|
|
- const { createGuestToken } = useGuestCartToken();
|
|
|
|
|
const { showToast } = useCustomToast();
|
|
const { showToast } = useCustomToast();
|
|
|
const apolloClient = useApolloClient();
|
|
const apolloClient = useApolloClient();
|
|
|
-
|
|
|
|
|
- const [mutateAsync, { loading: isCartLoading }] = useMutation(
|
|
|
|
|
- CREATE_ADD_PRODUCT_IN_CART,
|
|
|
|
|
- {
|
|
|
|
|
- onCompleted: (res) => {
|
|
|
|
|
- console.log('useAddToCart onCompleted run ----- 0');
|
|
|
|
|
- const responseData = res?.createAddProductInCart?.addProductInCart;
|
|
|
|
|
-
|
|
|
|
|
- if (!responseData?.success) {
|
|
|
|
|
- showToast(responseData?.message || "Error adding to cart", "danger");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- if (responseData) {
|
|
|
|
|
- if (responseData.success) {
|
|
|
|
|
- /** 兜底代码 start*/
|
|
|
|
|
- // 游客加购,然后清空购物车,然后刷新页面,然后再加购,然后再刷新页面,购物车会失效,所以添加兜底代码
|
|
|
|
|
- const isGuest = getIsGuest();// true 是游客
|
|
|
|
|
- // 如果之前的cartToken有效,responseCartId和responseCartToken的值是一样的都是cart id; 否则两者不相等
|
|
|
|
|
- const responseCartId = responseData.id;
|
|
|
|
|
- const responseCartToken = responseData.cartToken;
|
|
|
|
|
- if(isGuest && responseCartId !== responseCartToken) {
|
|
|
|
|
- setCookie(GUEST_CART_TOKEN, responseCartToken,{encode: false});
|
|
|
|
|
- setCookie(GUEST_CART_ID, responseCartId);
|
|
|
|
|
- setCookie(IS_GUEST, String(isGuest));
|
|
|
|
|
|
|
+ const [isRemoveLoading, setIsRemoveLoading] = useState(false);
|
|
|
|
|
+
|
|
|
|
|
+ const appendProductToCart = async (param: AddToCartVariables) => {
|
|
|
|
|
+ const res = await addProductToCartAction(param);
|
|
|
|
|
+ const result: {
|
|
|
|
|
+ data: AddProductInCart | null;
|
|
|
|
|
+ error: boolean;
|
|
|
|
|
+ } = {
|
|
|
|
|
+ data: null,
|
|
|
|
|
+ error: true
|
|
|
|
|
+ };
|
|
|
|
|
+ if(res.success) {
|
|
|
|
|
+ const responseData = res.cartData?.createAddProductInCart?.addProductInCart;
|
|
|
|
|
+ if (responseData) {
|
|
|
|
|
+ if (responseData.success) {
|
|
|
|
|
+ const cartDetail = formatCartDetail(responseData);
|
|
|
|
|
+ dispatch(addItem(cartDetail));
|
|
|
|
|
+ showToast("Product added to cart successfully", "success");
|
|
|
|
|
+ result.data = responseData;
|
|
|
|
|
+ result.error = false;
|
|
|
}
|
|
}
|
|
|
- /** 兜底代码 end*/
|
|
|
|
|
-
|
|
|
|
|
- const cartDetail = formatCartDetail(responseData);
|
|
|
|
|
- dispatch(addItem(cartDetail));
|
|
|
|
|
- showToast("Product added to cart successfully", "success");
|
|
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- onError: (err) => {
|
|
|
|
|
- handleApolloBusinessError(err,(error) => {
|
|
|
|
|
- showToast(error.message, "danger");
|
|
|
|
|
- });
|
|
|
|
|
- },
|
|
|
|
|
- },
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- const onAddToCart = async ({
|
|
|
|
|
- productId,
|
|
|
|
|
- quantity,
|
|
|
|
|
- variantId
|
|
|
|
|
- }: {
|
|
|
|
|
- productId: string;
|
|
|
|
|
- quantity: number;
|
|
|
|
|
- variantId?: number;
|
|
|
|
|
- token?: string;
|
|
|
|
|
- cartId?: number | string;
|
|
|
|
|
- }) => {
|
|
|
|
|
-
|
|
|
|
|
- // Ensure token exists - create if needed
|
|
|
|
|
- let token = getGuestCartToken(); // 从cookie获取token
|
|
|
|
|
- const isGuest = getIsGuest();
|
|
|
|
|
-
|
|
|
|
|
- if (!token && isGuest) {
|
|
|
|
|
- // 没有token,则创建一个并写入cookie
|
|
|
|
|
- token = await createGuestToken();
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
- if (!token) {
|
|
|
|
|
- showToast("Failed to create cart session", "danger");
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showToast(res.msg, "danger");
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const param : { productId: number; quantity:number; variantId?: number; } = {
|
|
|
|
|
- productId: parseInt(productId),
|
|
|
|
|
- quantity,
|
|
|
|
|
- };
|
|
|
|
|
- if(variantId) {
|
|
|
|
|
- param.variantId = variantId;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const result = await mutateAsync({
|
|
|
|
|
- variables: param,
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- return {
|
|
|
|
|
- data: result.data,
|
|
|
|
|
- error: result.error,
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ return result;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 删除购物车中的产品
|
|
// 删除购物车中的产品
|
|
|
- const deleteProductFromCart = useCallback((cartItemId: number) => {
|
|
|
|
|
- return apolloClient.mutate({
|
|
|
|
|
- mutation: REMOVE_CART_ITEM,
|
|
|
|
|
- variables: {
|
|
|
|
|
- cartItemId: cartItemId
|
|
|
|
|
- },
|
|
|
|
|
- }).then((res) => {
|
|
|
|
|
- const resCatData = res.data?.createRemoveCartItem?.removeCartItem ?? null;
|
|
|
|
|
|
|
+ const deleteProductFromCart = useCallback(async (cartItemId: number) => {
|
|
|
|
|
+ setIsRemoveLoading(true);
|
|
|
|
|
+ const deleteRes = await deleteCartProductAction(cartItemId);
|
|
|
|
|
+ if(deleteRes.success) {
|
|
|
|
|
+ const resCatData = deleteRes.cartData?.createRemoveCartItem?.removeCartItem ?? null;
|
|
|
if(resCatData && resCatData.itemsQty) {
|
|
if(resCatData && resCatData.itemsQty) {
|
|
|
const cartDetail = formatCartDetail(resCatData);
|
|
const cartDetail = formatCartDetail(resCatData);
|
|
|
dispatch(addItem(cartDetail));
|
|
dispatch(addItem(cartDetail));
|
|
@@ -130,27 +61,25 @@ export const useAddProduct = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(!resCatData || !resCatData?.itemsQty) {
|
|
if(!resCatData || !resCatData?.itemsQty) {
|
|
|
- dispatch(clearCart());
|
|
|
|
|
- // @todo 可以优化为通过接口或者server action 删除cookie
|
|
|
|
|
- const isGuest = getIsGuest();
|
|
|
|
|
- if (isGuest) {
|
|
|
|
|
- deleteGuestCookie();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ dispatch(clearCart());
|
|
|
}
|
|
}
|
|
|
|
|
+ setIsRemoveLoading(false);
|
|
|
return {
|
|
return {
|
|
|
data: resCatData?.itemsQty ? formatCartDetail(resCatData) : null,
|
|
data: resCatData?.itemsQty ? formatCartDetail(resCatData) : null,
|
|
|
error: false,
|
|
error: false,
|
|
|
msg: ""
|
|
msg: ""
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setIsRemoveLoading(false);
|
|
|
|
|
+ return {
|
|
|
|
|
+ data: null,
|
|
|
|
|
+ error: true,
|
|
|
|
|
+ msg: deleteRes.msg,
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- }).catch((err) => {
|
|
|
|
|
- return {
|
|
|
|
|
- data: null,
|
|
|
|
|
- error: true,
|
|
|
|
|
- msg: err.message,
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- },[apolloClient]);
|
|
|
|
|
|
|
+ },[]);
|
|
|
|
|
|
|
|
// 修改购物车中产品的数量
|
|
// 修改购物车中产品的数量
|
|
|
const editProductQtyFromCart = useCallback((cartItemId: number,quantity:number) => {
|
|
const editProductQtyFromCart = useCallback((cartItemId: number,quantity:number) => {
|
|
@@ -189,45 +118,6 @@ export const useAddProduct = () => {
|
|
|
});
|
|
});
|
|
|
},[apolloClient]);
|
|
},[apolloClient]);
|
|
|
|
|
|
|
|
- //--------Remove Cart Product Quantity--------//
|
|
|
|
|
- const [removeFromCart, { loading: isRemoveLoading }] = useMutation(
|
|
|
|
|
- REMOVE_CART_ITEM,
|
|
|
|
|
- {
|
|
|
|
|
- onCompleted: async (response) => {
|
|
|
|
|
- const responseData = response?.createRemoveCartItem?.removeCartItem;
|
|
|
|
|
- if (isObject(responseData)) {
|
|
|
|
|
- const message = "Cart item removed successfully";
|
|
|
|
|
- const cartDetail = formatCartDetail(responseData);
|
|
|
|
|
- dispatch(addItem(cartDetail));
|
|
|
|
|
- showToast(message as string, "warning");
|
|
|
|
|
-
|
|
|
|
|
- if (!responseData?.itemsQty) {
|
|
|
|
|
- dispatch(clearCart());
|
|
|
|
|
-
|
|
|
|
|
- const isGuest = getIsGuest();
|
|
|
|
|
- if (isGuest) {
|
|
|
|
|
- deleteGuestCookie();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- showToast("Something went wrong", "warning");
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- onError: (error) => {
|
|
|
|
|
- handleApolloBusinessError(error,(err) => {
|
|
|
|
|
- showToast(err.message, "danger");
|
|
|
|
|
- });
|
|
|
|
|
- },
|
|
|
|
|
- },
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- const onAddToRemove = async (productId: string) => {
|
|
|
|
|
- await removeFromCart({
|
|
|
|
|
- variables: {
|
|
|
|
|
- cartItemId: parseInt(productId),
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
|
|
|
|
|
//---------Update Cart Product Quantity--------//
|
|
//---------Update Cart Product Quantity--------//
|
|
|
const [updateCartItem, { loading: isUpdateLoading }] = useMutation(
|
|
const [updateCartItem, { loading: isUpdateLoading }] = useMutation(
|
|
@@ -273,13 +163,11 @@ export const useAddProduct = () => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
- isCartLoading,
|
|
|
|
|
- onAddToCart,
|
|
|
|
|
isRemoveLoading,
|
|
isRemoveLoading,
|
|
|
- onAddToRemove,
|
|
|
|
|
onUpdateCart,
|
|
onUpdateCart,
|
|
|
isUpdateLoading,
|
|
isUpdateLoading,
|
|
|
deleteProductFromCart,
|
|
deleteProductFromCart,
|
|
|
- editProductQtyFromCart
|
|
|
|
|
|
|
+ editProductQtyFromCart,
|
|
|
|
|
+ appendProductToCart
|
|
|
};
|
|
};
|
|
|
};
|
|
};
|