| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- "use client";
- import { useEffect, useState, useRef } from "react";
- import { fetchHandler } from "../fetch-handler";
- import { GUEST_CART_ID, GUEST_CART_TOKEN, IS_GUEST } from "@/utils/constants";
- import { encodeJWT, decodeJWT } from "@/utils/jwt-cookie";
- import { setCookie, deleteCookie, getCookie } from "@/utils/cookie-tools";
- // ---------------------------
- // Main Hook
- // ---------------------------
- export const useGuestCartToken = () => {
- const [token, setToken] = useState<string | null>(null);
- const [cartId, setCartId] = useState<number | null>(null);
- const [isReady, setIsReady] = useState(false);
- const isResettingRef = useRef(false);
- const tokenCreatedRef = useRef(false);
- const tokenPromiseRef = useRef<Promise<string | null> | null>(null);
- const createGuestToken = async (): Promise<string | null> => {
- if (tokenPromiseRef.current) return tokenPromiseRef.current;
- tokenPromiseRef.current = (async () => {
- if (tokenCreatedRef.current) {
- // Return existing raw token from cookie
- const cookieVal = getCookie(GUEST_CART_TOKEN);
- if (cookieVal) {
- const isGuest = getCookie(IS_GUEST) !== "false";
- const decoded = decodeJWT<{ sessionToken: string }>(cookieVal, isGuest);
- return decoded?.sessionToken ?? null;
- }
- return null;
- }
- tokenCreatedRef.current = true;
- try {
- const res = await fetchHandler({
- url: "graphql",
- method: "POST",
- body: { operationName: "CreateCart" },
- contentType: true,
- });
- const cart = res?.data?.createCartToken?.cartToken;
- if (!cart) {
- tokenCreatedRef.current = false;
- return null;
- }
- const newToken = encodeJWT({
- sessionToken: cart.sessionToken,
- cartId: cart.id,
- isGuest: cart.isGuest,
- });
- const newCartId = Number(cart.id);
- setCookie(GUEST_CART_TOKEN, newToken,{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
- deleteCookie(GUEST_CART_TOKEN);
- deleteCookie(GUEST_CART_ID);
- await createGuestToken();
- isResettingRef.current = false;
- };
- useEffect(() => {
- const cookieToken = getCookie(GUEST_CART_TOKEN);
- if (cookieToken) {
- const isGuest = getCookie(IS_GUEST) !== "false";
- const decoded = decodeJWT<{
- sessionToken: string;
- cartId: number;
- isGuest: boolean;
- }>(cookieToken, isGuest);
- if (decoded) {
- setToken(decoded.sessionToken);
- setCartId(decoded.cartId);
- }
- }
- setIsReady(true);
- }, []);
- return {
- token,
- cartId,
- isReady,
- createGuestToken,
- resetGuestToken,
- deleteCookie,
- };
- };
|