mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import React, { Suspense } from "react";
|
|
import { useAtom } from "jotai";
|
|
import { ErrorBoundary } from "react-error-boundary";
|
|
import { useLocation, Outlet } from "react-router-dom";
|
|
|
|
import { useMediaQuery, Stack, GlobalStyles } from "@mui/material";
|
|
|
|
import TopBar, { TOP_BAR_HEIGHT } from "./TopBar";
|
|
import NavDrawer from "./NavDrawer";
|
|
import ErrorFallback, {
|
|
IErrorFallbackProps,
|
|
} from "@src/components/ErrorFallback";
|
|
import Loading from "@src/components/Loading";
|
|
import GetStartedChecklist from "@src/components/GetStartedChecklist";
|
|
|
|
import {
|
|
globalScope,
|
|
projectIdAtom,
|
|
navOpenAtom,
|
|
} from "@src/atoms/globalScope";
|
|
import { ROUTE_TITLES } from "@src/constants/routes";
|
|
import { useDocumentTitle } from "@src/hooks/useDocumentTitle";
|
|
|
|
export default function Navigation({ children }: React.PropsWithChildren<{}>) {
|
|
const [projectId] = useAtom(projectIdAtom, globalScope);
|
|
|
|
const [open, setOpen] = useAtom(navOpenAtom, globalScope);
|
|
const isPermanent = useMediaQuery((theme: any) => theme.breakpoints.up("md"));
|
|
|
|
const { pathname } = useLocation();
|
|
const basePath = ("/" + pathname.split("/")[1]) as keyof typeof ROUTE_TITLES;
|
|
const routeTitle =
|
|
ROUTE_TITLES[pathname as keyof typeof ROUTE_TITLES] ||
|
|
ROUTE_TITLES[basePath] ||
|
|
"";
|
|
const title = typeof routeTitle === "string" ? routeTitle : routeTitle.title;
|
|
useDocumentTitle(projectId, title);
|
|
|
|
return (
|
|
<>
|
|
<TopBar
|
|
open={open}
|
|
setOpen={setOpen}
|
|
isPermanent={isPermanent}
|
|
routeTitle={routeTitle}
|
|
title={title}
|
|
/>
|
|
|
|
<Stack direction="row">
|
|
<NavDrawer
|
|
open={open}
|
|
isPermanent={isPermanent}
|
|
onClose={() => setOpen(false)}
|
|
/>
|
|
<GetStartedChecklist navOpen={open} navPermanent={isPermanent} />
|
|
|
|
<ErrorBoundary FallbackComponent={StyledErrorFallback}>
|
|
<Suspense
|
|
fallback={
|
|
<Loading fullScreen style={{ marginTop: -TOP_BAR_HEIGHT }} />
|
|
}
|
|
>
|
|
<div style={{ flexGrow: 1, maxWidth: "100%" }}>
|
|
<Outlet />
|
|
{children}
|
|
</div>
|
|
</Suspense>
|
|
</ErrorBoundary>
|
|
</Stack>
|
|
|
|
<GlobalStyles
|
|
styles={(theme) => ({
|
|
":root": {
|
|
"--nav-transition-timing-function": open
|
|
? theme.transitions.easing.easeOut
|
|
: theme.transitions.easing.sharp,
|
|
"--nav-transition-duration":
|
|
(open
|
|
? theme.transitions.duration.enteringScreen
|
|
: theme.transitions.duration.leavingScreen) + "ms",
|
|
},
|
|
})}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const StyledErrorFallback = (props: IErrorFallbackProps) => (
|
|
<ErrorFallback {...props} style={{ marginTop: -TOP_BAR_HEIGHT }} />
|
|
);
|