import { ApolloProvider } from "@apollo/client"; import * as Sentry from "@sentry/react"; import { SplitFactoryProvider, useSplitClient } from "@splitsoftware/splitio-react"; import { ConfigProvider } from "antd"; import enLocale from "antd/es/locale/en_US"; import { useEffect, useMemo } from "react"; import { CookiesProvider } from "react-cookie"; import { useTranslation } from "react-i18next"; import { connect, useSelector } from "react-redux"; import { createStructuredSelector } from "reselect"; import GlobalLoadingBar from "../components/global-loading-bar/global-loading-bar.component"; import { setDarkMode } from "../redux/application/application.actions"; import { selectDarkMode } from "../redux/application/application.selectors"; import { selectCurrentUser } from "../redux/user/user.selectors.js"; import { signOutStart } from "../redux/user/user.actions"; import client from "../utils/GraphQLClient"; import App from "./App"; import getTheme from "./themeProvider"; // Base Split configuration const config = { core: { authorizationKey: import.meta.env.VITE_APP_SPLIT_API, key: "anon" } }; function SplitClientProvider({ children }) { const imexshopid = useSelector((state) => state.user.imexshopid); const splitClient = useSplitClient({ key: imexshopid || "anon" }); useEffect(() => { if (splitClient && imexshopid) { console.log(`Split client initialized with key: ${imexshopid}, isReady: ${splitClient.isReady}`); } }, [splitClient, imexshopid]); return children; } const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser }); const mapDispatchToProps = (dispatch) => ({ setDarkMode: (isDarkMode) => dispatch(setDarkMode(isDarkMode)), signOutStart: () => dispatch(signOutStart()) }); function AppContainer({ currentUser, setDarkMode, signOutStart }) { const { t } = useTranslation(); const isDarkMode = useSelector(selectDarkMode); const theme = useMemo(() => getTheme(isDarkMode), [isDarkMode]); // Global seamless logout listener with redirect to /signin useEffect(() => { const handleSeamlessLogout = (event) => { if (event.data?.type !== "seamlessLogoutRequest") return; const requestOrigin = event.origin; if (currentUser?.authorized !== true) { window.parent.postMessage( { type: "seamlessLogoutResponse", status: "already_logged_out" }, requestOrigin || "*" ); return; } signOutStart(); window.parent.postMessage({ type: "seamlessLogoutResponse", status: "logged_out" }, requestOrigin || "*"); }; window.addEventListener("message", handleSeamlessLogout); return () => { window.removeEventListener("message", handleSeamlessLogout); }; }, [signOutStart, currentUser]); // Update data-theme attribute useEffect(() => { document.documentElement.setAttribute("data-theme", isDarkMode ? "dark" : "light"); return () => document.documentElement.removeAttribute("data-theme"); }, [isDarkMode]); // Sync darkMode with localStorage useEffect(() => { if (currentUser?.uid) { const savedMode = localStorage.getItem(`dark-mode-${currentUser.uid}`); if (savedMode !== null) { setDarkMode(JSON.parse(savedMode)); } else { setDarkMode(false); } } else { setDarkMode(false); } }, [currentUser?.uid, setDarkMode]); // Persist darkMode useEffect(() => { if (currentUser?.uid) { localStorage.setItem(`dark-mode-${currentUser.uid}`, JSON.stringify(isDarkMode)); } }, [isDarkMode, currentUser?.uid]); return ( ); } export default Sentry.withProfiler(connect(mapStateToProps, mapDispatchToProps)(AppContainer));