import type { SuspenseProps } from "react"; import { lazy, Suspense, useEffect, useLayoutEffect, useRef } from "react"; import { lazily } from "react-lazily"; import ContactFormModal from "@ui_kit/ContactForm"; import dayjs from "dayjs"; import "dayjs/locale/ru"; import SigninDialog from "./pages/auth/Signin"; import SignupDialog from "./pages/auth/Signup"; import { Navigate, Route, Routes, useLocation, useNavigate, } from "react-router-dom"; import "./index.css"; import Landing from "./pages/Landing/Landing"; import Main from "./pages/main"; import { clearAuthToken, createUserAccount, devlog, getMessageFromFetchError, UserAccount, useUserFetcher, } from "@frontend/kitui"; import { makeRequest } from "@api/makeRequest"; import type { OriginalUserAccount } from "@root/user"; import { clearUserData, setCustomerAccount, setUser, setUserAccount, useUserStore, } from "@root/user"; import { enqueueSnackbar } from "notistack"; import PrivateRoute from "@ui_kit/PrivateRoute"; import FloatingSupportChat from "@ui_kit/FloatingSupportChat"; import { Restore } from "./pages/auth/Restore"; import { isAxiosError } from "axios"; import RecoverPassword from "./pages/auth/RecoverPassword"; import { InfoPrivilege } from "./pages/InfoPrivilege"; import OutdatedLink from "./pages/auth/OutdatedLink"; import { useAfterpay } from "@utils/hooks/useAfterpay"; const MyQuizzesFull = lazy(() => import("./pages/createQuize/MyQuizzesFull")); const ViewPage = lazy(() => import("./pages/ViewPublicationPage")); const Analytics = lazy(() => import("./pages/Analytics/Analytics")); const EditPage = lazy(() => import("./pages/startPage/EditPage")); const { Tariffs } = lazily(() => import("./pages/Tariffs/Tariffs")); const { DesignPage } = lazily(() => import("./pages/DesignPage/DesignPage")); const { IntegrationsPage } = lazily( () => import("./pages/IntegrationsPage/IntegrationsPage"), ); const { QuizAnswersPage } = lazily( () => import("./pages/QuizAnswersPage/QuizAnswersPage"), ); const ChatImageNewWindow = lazy( () => import("@ui_kit/FloatingSupportChat/ChatImageNewWindow"), ); dayjs.locale("ru"); const routeslink = [ { path: "/edit", page: EditPage, header: true, sidebar: true, footer: true, }, { path: "/design", page: DesignPage, header: true, sidebar: true, footer: true, }, { path: "/integrations", page: IntegrationsPage, header: true, sidebar: true, footer: true, }, ] as const; const LazyLoading = ({ children, fallback }: SuspenseProps) => ( }>{children} ); export function useUserAccountFetcher({ onError, onNewUserAccount, url, userId, }: { url: string; userId: string | null; onNewUserAccount: (response: T) => void; onError?: (error: any) => void; }) { const onNewUserAccountRef = useRef(onNewUserAccount); const onErrorRef = useRef(onError); useLayoutEffect(() => { onNewUserAccountRef.current = onNewUserAccount; onErrorRef.current = onError; }, [onError, onNewUserAccount]); useEffect(() => { if (!userId) return; const controller = new AbortController(); makeRequest({ url, contentType: true, method: "GET", useToken: true, withCredentials: false, signal: controller.signal, }) .then((result) => { devlog("User account", result); onNewUserAccountRef.current(result); }) .catch((error) => { devlog("Error fetching user account", error); if (isAxiosError(error) && error.response?.status === 404) { createUserAccount(controller.signal, url.replace("get", "create")) .then((result) => { devlog("Created user account", result); onNewUserAccountRef.current(result as T); }) .catch((error) => { devlog("Error creating user account", error); onErrorRef.current?.(error); }); } else { onErrorRef.current?.(error); } }); return () => controller.abort(); }, [url, userId]); } export default function App() { const userId = useUserStore((state) => state.userId); const location = useLocation(); const navigate = useNavigate(); useUserFetcher({ url: process.env.REACT_APP_DOMAIN + `/user/${userId}`, userId, onNewUser: setUser, onError: (error) => { const errorMessage = getMessageFromFetchError(error); if (errorMessage) { enqueueSnackbar(errorMessage); clearUserData(); clearAuthToken(); } }, }); useUserAccountFetcher({ url: process.env.REACT_APP_DOMAIN + "/customer/account", userId, onNewUserAccount: setCustomerAccount, onError: (error) => { const errorMessage = getMessageFromFetchError(error); if (errorMessage) { enqueueSnackbar(errorMessage); clearUserData(); clearAuthToken(); navigate("/signin"); } }, }); useUserAccountFetcher({ url: process.env.REACT_APP_DOMAIN + "/squiz/account/get", userId, onNewUserAccount: setUserAccount, onError: (error) => { const errorMessage = getMessageFromFetchError(error); if (errorMessage) { enqueueSnackbar(errorMessage); clearUserData(); clearAuthToken(); navigate("/signin"); } }, }); if (location.state?.redirectTo) return ( ); useAfterpay(); return ( <> {location.state?.backgroundLocation && ( } /> } /> } /> } /> } /> )} } /> } /> } /> } /> } /> } /> } />} /> } />} /> } />} /> } />} /> } />} /> } />} /> } /> }> {routeslink.map((e, i) => ( } /> } /> ))} ); }