import { useEffect, useMemo, useCallback } from "react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { RouterProvider } from "@tanstack/react-router"; import { ToastContainer } from "react-toastify"; import { useUserProfileStore, useUserStore, } from "./context/zustand-store/userStore"; import { makeRouter } from "./routes/routes"; import { useDarkMode } from "./hooks/useDarkMode"; import { getUserPermissions } from "./utils/getUserAvalableItems"; import { ItemWithSubItems } from "./types/userPermissions"; import versionNumber from "./version.txt"; import "./index.css"; import "react-toastify/dist/ReactToastify.css"; import { checkIsMobile } from "./utils/checkIsMobile"; const queryClient = new QueryClient(); export default function App() { const auth = useUserStore((s) => s.auth); const { profile } = useUserProfileStore(); const [isDark] = useDarkMode(); const menuItems: ItemWithSubItems[] = useMemo( () => getUserPermissions(profile?.permissions ?? []), [profile?.permissions] ); const router = useMemo( () => makeRouter(auth ?? null, menuItems), [auth, menuItems] ); const hardRefresh = useCallback(() => { const url = new URL(window.location.href); url.searchParams.set("refresh", Date.now().toString()); window.location.href = url.toString(); }, []); const runWhenIdle = useCallback((fn: () => void) => { const ric = (window as any).requestIdleCallback; if (typeof ric === "function") { ric(fn); } else { setTimeout(fn, 300); } }, []); useEffect(() => { let aborted = false; const controller = new AbortController(); const checkVersion = () => { if (document.visibilityState !== "visible") return; fetch(`${versionNumber}?_=${Date.now()}`, { signal: controller.signal, cache: "no-store", }) .then((res) => res.text()) .then(async (txt) => { if (aborted) return; const latest = txt.trim(); const stored = localStorage.getItem("AppVersion"); if (latest && latest !== stored) { localStorage.setItem("AppVersion", latest); const clearAndReload = async () => { if ("caches" in window) { const names = await caches.keys(); for (const n of names) { await caches.delete(n).catch(() => undefined); } } setTimeout(hardRefresh, 200); }; runWhenIdle(clearAndReload); } }) .catch(() => {}); }; runWhenIdle(checkVersion); return () => { aborted = true; controller.abort(); }; }, [hardRefresh, runWhenIdle]); useEffect(() => { const url = new URL(window.location.href); if (url.searchParams.has("refresh")) { url.searchParams.delete("refresh"); window.history.replaceState( {}, document.title, url.pathname + url.search ); } }, []); return (
{checkIsMobile() &&
}
); }