w-funnel/src/hooks/session/useSession.ts
2025-10-30 02:38:00 +01:00

150 lines
4.2 KiB
TypeScript

import {
ICreateSessionResponse,
IUpdateSessionRequest,
} from "@/entities/session/types";
import {
createSession as createSessionApi,
updateSession as updateSessionApi,
} from "@/entities/session/actions";
import { getClientTimezone } from "@/shared/utils/locales";
import { parseQueryParams } from "@/shared/utils/url";
import { useCallback, useMemo, useState } from "react";
import { setSessionIdToCookie } from "@/entities/session/serverActions";
import { metricService } from "@/services/analytics/metricService";
// TODO
const locale = "en";
interface IUseSessionProps {
funnelId: string;
googleAnalyticsId?: string;
}
export const useSession = ({ funnelId, googleAnalyticsId }: IUseSessionProps) => {
const localStorageKey = `${funnelId}_sessionId`;
const sessionId =
typeof window === "undefined" ? "" : localStorage.getItem(localStorageKey);
const timezone = getClientTimezone();
const [isError, setIsError] = useState(false);
const setSessionId = useCallback(
async (sessionId: string) => {
localStorage.setItem(localStorageKey, sessionId);
localStorage.setItem("activeSessionId", sessionId);
await setSessionIdToCookie("activeSessionId", sessionId);
},
[localStorageKey]
);
const createSession =
useCallback(async (): Promise<ICreateSessionResponse> => {
if (typeof window === "undefined") {
return {
sessionId: "",
status: "error",
};
}
if (sessionId?.length) {
setSessionId(sessionId);
return {
sessionId,
status: "old",
};
}
try {
const utm = parseQueryParams();
const sessionParams = {
feature: "stripe",
locale,
timezone,
source: funnelId,
sign: false,
utm,
domain: window.location.hostname,
};
console.log("Creating session with parameters:", sessionParams);
const sessionFromServer = await createSessionApi(sessionParams);
console.log("Session creation response:", sessionFromServer);
if (
sessionFromServer?.sessionId?.length &&
sessionFromServer?.status === "success"
) {
await setSessionId(sessionFromServer.sessionId);
// ✅ Отправляем sessionId в userParams (параметры посетителя)
metricService.userParams({
sessionId: sessionFromServer.sessionId,
});
// ✅ Отправляем контекст визита в params (параметры визита)
metricService.sendVisitContext({
sessionId: sessionFromServer.sessionId,
funnelId,
gaId: googleAnalyticsId,
});
return sessionFromServer;
}
console.error(
"Session creation failed - invalid response:",
sessionFromServer
);
setIsError(true);
return {
status: "error",
sessionId: "",
};
} catch (error) {
console.error("Session creation failed with error:", error);
setIsError(true);
return {
status: "error",
sessionId: "",
};
}
}, [sessionId, timezone, setSessionId, funnelId, googleAnalyticsId]);
const updateSession = useCallback(
async (data: IUpdateSessionRequest["data"]) => {
try {
let _sessionId = sessionId;
if (!_sessionId) {
const session = await createSession();
_sessionId = session.sessionId;
}
const result = await updateSessionApi({
sessionId: _sessionId,
data: {
feature: "stripe",
...data,
},
});
return result;
} catch (error) {
console.log(error);
}
},
[sessionId, createSession]
);
const deleteSession = useCallback(async () => {
if (typeof window === "undefined") {
return;
}
localStorage.removeItem(localStorageKey);
}, [localStorageKey]);
return useMemo(
() => ({
session: sessionId,
isError,
createSession,
updateSession,
deleteSession,
}),
[sessionId, isError, createSession, deleteSession, updateSession]
);
};