useGuestCartToken.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. "use client";
  2. import { useState, useRef } from "react";
  3. import { fetchHandler } from "../fetch-handler";
  4. import { GUEST_CART_ID, GUEST_CART_TOKEN, IS_GUEST } from "@/utils/constants";
  5. import {
  6. setCookie,
  7. getGuestCartToken,
  8. getGuestCartId,
  9. deleteGuestCookie
  10. } from "@/utils/cookie-tools";
  11. import { CREATE_CART_TOKEN } from "@/graphql";
  12. // ---------------------------
  13. // Main Hook
  14. // ---------------------------
  15. export const useGuestCartToken = () => {
  16. const [token, setToken] = useState(() => {
  17. const guestCartToken = getGuestCartToken();
  18. return guestCartToken;
  19. });
  20. const [cartId, setCartId] = useState(() => {
  21. const guestCartId = getGuestCartId();
  22. return guestCartId ? Number(guestCartId) : null;
  23. });
  24. // const [isReady, setIsReady] = useState(true);
  25. const isResettingRef = useRef(false);
  26. const tokenCreatedRef = useRef(false);
  27. const tokenPromiseRef = useRef<Promise<string | null> | null>(null);
  28. const createGuestToken = async (): Promise<string | null> => {
  29. if (tokenPromiseRef.current) return tokenPromiseRef.current;
  30. tokenPromiseRef.current = (async () => {
  31. if (tokenCreatedRef.current) {
  32. // Return existing raw token from cookie
  33. const cookieVal = getGuestCartToken();
  34. if (cookieVal) {
  35. return cookieVal;
  36. }
  37. return null;
  38. }
  39. tokenCreatedRef.current = true;
  40. try {
  41. const query = CREATE_CART_TOKEN;
  42. const queryString = typeof query === "string" ? query : (query.loc?.source?.body ?? "");
  43. const res = await fetchHandler({
  44. url: "graphql",
  45. method: "POST",
  46. body: { operationName: "CreateCart",query: queryString },
  47. contentType: true,
  48. });
  49. const cart = res?.data?.createCartToken?.cartToken;
  50. if (!cart) {
  51. tokenCreatedRef.current = false;
  52. return null;
  53. }
  54. const newCartId = Number(cart.id);
  55. setCookie(GUEST_CART_TOKEN, cart.sessionToken,{encode: false});
  56. setCookie(GUEST_CART_ID, String(newCartId));
  57. setCookie(IS_GUEST, String(cart?.isGuest));
  58. // State and return should be the RAW token
  59. setToken(cart.sessionToken);
  60. setCartId(newCartId);
  61. return cart.sessionToken;
  62. } catch (e) {
  63. console.error("Error creating guest token:", e);
  64. tokenCreatedRef.current = false;
  65. return null;
  66. } finally {
  67. tokenPromiseRef.current = null;
  68. }
  69. })();
  70. return tokenPromiseRef.current;
  71. };
  72. const resetGuestToken = async () => {
  73. if (isResettingRef.current) return;
  74. isResettingRef.current = true;
  75. tokenCreatedRef.current = false;
  76. // delete old
  77. deleteGuestCookie();
  78. await createGuestToken();
  79. isResettingRef.current = false;
  80. };
  81. return {
  82. token,
  83. cartId,
  84. // isReady,
  85. createGuestToken,
  86. resetGuestToken,
  87. };
  88. };