Files
SkyMoney/web/src/App.tsx

58 lines
1.8 KiB
TypeScript

import { Suspense, useEffect, useState } from "react";
import { Outlet, useLocation } from "react-router-dom";
import { useQueryClient } from "@tanstack/react-query";
import { SessionTimeoutWarning } from "./components/SessionTimeoutWarning";
import NavBar from "./components/NavBar";
import { useAuthSession } from "./hooks/useAuthSession";
import { http } from "./api/http";
import UpdateNoticeModal from "./components/UpdateNoticeModal";
export default function App() {
const location = useLocation();
const qc = useQueryClient();
const session = useAuthSession({ retry: false });
const [dismissedVersion, setDismissedVersion] = useState<number | null>(null);
const notice = session.data?.updateNotice;
const isPublicRoute =
location.pathname.startsWith("/login") ||
location.pathname.startsWith("/register") ||
location.pathname.startsWith("/verify") ||
location.pathname.startsWith("/beta");
const showUpdateModal = !isPublicRoute && !!notice && dismissedVersion !== notice.version;
useEffect(() => {
setDismissedVersion(null);
}, [session.data?.userId]);
const acknowledgeNotice = async () => {
if (!notice) return;
await http("/app/update-notice/ack", {
method: "POST",
body: { version: notice.version },
});
setDismissedVersion(notice.version);
await qc.invalidateQueries({ queryKey: ["auth", "session"] });
};
return (
<>
<SessionTimeoutWarning />
<NavBar />
<main className="container py-6 h-full">
<Suspense fallback={<div className="muted text-sm">Loading</div>}>
<Outlet />
</Suspense>
</main>
{showUpdateModal && notice ? (
<UpdateNoticeModal
title={notice.title}
body={notice.body}
onAcknowledge={acknowledgeNotice}
/>
) : null}
</>
);
}