"use client"; import { useState, useRef } from "react"; import { fetchHandler } from "../fetch-handler"; import { GUEST_CART_ID, GUEST_CART_TOKEN, IS_GUEST } from "@/utils/constants"; import { setCookie, getGuestCartToken, getGuestCartId, deleteGuestCookie } from "@/utils/cookie-tools"; import { CREATE_CART_TOKEN } from "@/graphql"; // --------------------------- // Main Hook // --------------------------- export const useGuestCartToken = () => { const [token, setToken] = useState(() => { const guestCartToken = getGuestCartToken(); return guestCartToken; }); const [cartId, setCartId] = useState(() => { const guestCartId = getGuestCartId(); return guestCartId ? Number(guestCartId) : null; }); // const [isReady, setIsReady] = useState(true); const isResettingRef = useRef(false); const tokenCreatedRef = useRef(false); const tokenPromiseRef = useRef | null>(null); const createGuestToken = async (): Promise => { if (tokenPromiseRef.current) return tokenPromiseRef.current; tokenPromiseRef.current = (async () => { if (tokenCreatedRef.current) { // Return existing raw token from cookie const cookieVal = getGuestCartToken(); if (cookieVal) { return cookieVal; } return null; } tokenCreatedRef.current = true; try { const query = CREATE_CART_TOKEN; const queryString = typeof query === "string" ? query : (query.loc?.source?.body ?? ""); const res = await fetchHandler({ url: "graphql", method: "POST", body: { operationName: "CreateCart",query: queryString }, contentType: true, }); const cart = res?.data?.createCartToken?.cartToken; if (!cart) { tokenCreatedRef.current = false; return null; } const newCartId = Number(cart.id); setCookie(GUEST_CART_TOKEN, cart.sessionToken,{encode: false}); setCookie(GUEST_CART_ID, String(newCartId)); setCookie(IS_GUEST, String(cart?.isGuest)); // State and return should be the RAW token setToken(cart.sessionToken); setCartId(newCartId); return cart.sessionToken; } catch (e) { console.error("Error creating guest token:", e); tokenCreatedRef.current = false; return null; } finally { tokenPromiseRef.current = null; } })(); return tokenPromiseRef.current; }; const resetGuestToken = async () => { if (isResettingRef.current) return; isResettingRef.current = true; tokenCreatedRef.current = false; // delete old deleteGuestCookie(); await createGuestToken(); isResettingRef.current = false; }; return { token, cartId, // isReady, createGuestToken, resetGuestToken, }; };