useAddToCart.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. "use client";
  2. import { useCustomToast } from "./useToast";
  3. import { useAppDispatch } from "@/store/hooks";
  4. import { addItem, clearCart } from "@/store/slices/cart-slice";
  5. import { isObject } from "@utils/type-guards";
  6. import { getCartToken } from "@utils/getCartToken";
  7. import { getCookie } from "@utils/cookie-tools";
  8. import { useGuestCartToken } from "./useGuestCartToken";
  9. import { IS_GUEST } from "@/utils/constants";
  10. import { useMutation } from "@apollo/client/react";
  11. import {
  12. CREATE_ADD_PRODUCT_IN_CART,
  13. REMOVE_CART_ITEM,
  14. UPDATE_CART_ITEM,
  15. } from "@/graphql";
  16. import { AddToCartData, RemoveCartItemData, UpdateCartItemData } from "@/types/cart/type";
  17. export const useAddProduct = () => {
  18. const dispatch = useAppDispatch();
  19. const { createGuestToken, resetGuestToken } = useGuestCartToken();
  20. const { showToast } = useCustomToast();
  21. const [mutateAsync, { loading: isCartLoading }] = useMutation<AddToCartData>(
  22. CREATE_ADD_PRODUCT_IN_CART,
  23. {
  24. onCompleted: (res) => {
  25. console.log('useAddToCart onCompleted run ----- 0');
  26. const responseData = res?.createAddProductInCart?.addProductInCart;
  27. if (!responseData?.success) {
  28. showToast(responseData?.message || "Error adding to cart", "danger");
  29. return;
  30. }
  31. if (responseData) {
  32. if (responseData.success) {
  33. let cartDetail = {
  34. id: responseData.id,
  35. itemsQty: responseData.itemsQty,
  36. taxAmount: responseData.taxAmount,
  37. shippingAmount: responseData.shippingAmount,
  38. grandTotal: responseData.grandTotal,
  39. items: responseData.items,
  40. paymentMethod: responseData.paymentMethod || '',
  41. paymentMethodTitle: responseData.paymentMethodTitle || '',
  42. selectedShippingRate: responseData.selectedShippingRate || '',
  43. selectedShippingRateTitle: responseData.selectedShippingRateTitle || '',
  44. };
  45. dispatch(addItem(cartDetail));
  46. showToast("Product added to cart successfully", "success");
  47. }
  48. }
  49. },
  50. onError: (err) => {
  51. showToast(err?.message ?? "Error", "danger");
  52. },
  53. },
  54. );
  55. const onAddToCart = async ({
  56. productId,
  57. quantity,
  58. variantId
  59. }: {
  60. productId: string;
  61. quantity: number;
  62. variantId?: number;
  63. token?: string;
  64. cartId?: number | string;
  65. }) => {
  66. // Ensure token exists - create if needed
  67. let token = getCartToken(); // 从cookie获取token
  68. if (!token) {
  69. token = await createGuestToken();
  70. if (!token) {
  71. showToast("Failed to create cart session", "danger");
  72. return;
  73. }
  74. }
  75. let param : { productId: number; quantity:number; variantId?: number; } = {
  76. productId: parseInt(productId),
  77. quantity,
  78. };
  79. if(variantId) {
  80. param.variantId = variantId;
  81. }
  82. let result = await mutateAsync({
  83. variables: param,
  84. });
  85. return {
  86. data: result.data,
  87. error: result.error,
  88. };
  89. };
  90. //--------Remove Cart Product Quantity--------//
  91. const [removeFromCart, { loading: isRemoveLoading }] = useMutation<RemoveCartItemData>(
  92. REMOVE_CART_ITEM,
  93. {
  94. onCompleted: async (response) => {
  95. const responseData = response?.createRemoveCartItem?.removeCartItem;
  96. if (isObject(responseData)) {
  97. const message = "Cart item removed successfully";
  98. dispatch(addItem(responseData as any));
  99. showToast(message as string, "warning");
  100. if (!responseData?.itemsQty) {
  101. dispatch(clearCart());
  102. const isGuest = getCookie(IS_GUEST);
  103. if (isGuest === "true") {
  104. resetGuestToken();
  105. }
  106. }
  107. } else {
  108. showToast("Something went wrong", "warning");
  109. }
  110. },
  111. onError: (error) => {
  112. showToast(error?.message as string, "danger");
  113. },
  114. },
  115. );
  116. const onAddToRemove = async (productId: string) => {
  117. await removeFromCart({
  118. variables: {
  119. cartItemId: parseInt(productId),
  120. },
  121. });
  122. };
  123. //---------Update Cart Product Quantity--------//
  124. const [updateCartItem, { loading: isUpdateLoading }] = useMutation<UpdateCartItemData>(
  125. UPDATE_CART_ITEM,
  126. {
  127. onCompleted: (response) => {
  128. const responseData = response?.createUpdateCartItem?.updateCartItem;
  129. if (isObject(responseData)) {
  130. let cartDetail = {
  131. id: responseData.id,
  132. itemsQty: responseData.itemsQty,
  133. taxAmount: responseData.taxAmount,
  134. shippingAmount: responseData.shippingAmount,
  135. grandTotal: responseData.grandTotal,
  136. items: responseData.items,
  137. paymentMethod: responseData.paymentMethod || '',
  138. paymentMethodTitle: responseData.paymentMethodTitle || '',
  139. selectedShippingRate: responseData.selectedShippingRate || '',
  140. selectedShippingRateTitle: responseData.selectedShippingRateTitle || '',
  141. };
  142. dispatch(addItem(cartDetail));
  143. } else {
  144. showToast("Something went wrong!", "warning");
  145. }
  146. },
  147. onError: (error) => {
  148. showToast(error?.message as string, "danger");
  149. },
  150. },
  151. );
  152. const onUpdateCart = async ({
  153. cartItemId,
  154. quantity,
  155. }: {
  156. cartItemId: number;
  157. quantity: number;
  158. }) => {
  159. if (quantity < 1) {
  160. showToast("Quantity must be at least 1", "warning");
  161. return;
  162. }
  163. await updateCartItem({
  164. variables: {
  165. cartItemId: cartItemId,
  166. quantity,
  167. },
  168. });
  169. };
  170. return {
  171. isCartLoading,
  172. onAddToCart,
  173. isRemoveLoading,
  174. onAddToRemove,
  175. onUpdateCart,
  176. isUpdateLoading,
  177. };
  178. };