Files
MoneyMgr/moneymgr_web/src/widgets/BaseAuthenticatedPage.tsx

105 lines
3.2 KiB
TypeScript

import { Box, Button } from "@mui/material";
import * as React from "react";
import { Outlet, useNavigate } from "react-router-dom";
import { AuthApi, AuthInfo } from "../api/AuthApi";
import { useAuth } from "../App";
import { AccountsListProvider } from "../hooks/AccountsListProvider";
import { ChooseAccountDialogProvider } from "../hooks/context_providers/ChooseAccountDialogProvider";
import { UnmatchedInboxEntriesCountProvider } from "../hooks/UnmatchedInboxEntriesCountProvider";
import { AsyncWidget } from "./AsyncWidget";
import { MoneyNavList } from "./MoneyNavList";
import { MoneyWebAppBar } from "./MoneyWebAppBar";
interface AuthInfoContext {
info: AuthInfo;
reloadAuthInfo: () => void;
}
const AuthInfoContextK = React.createContext<AuthInfoContext | null>(null);
export function BaseAuthenticatedPage(): React.ReactElement {
const [authInfo, setAuthInfo] = React.useState<null | AuthInfo>(null);
const auth = useAuth();
const navigate = useNavigate();
const signOut = () => {
AuthApi.SignOut();
navigate("/");
auth.setSignedIn(false);
};
const load = async () => {
setAuthInfo(await AuthApi.GetAuthInfo());
};
return (
<AsyncWidget
loadKey="1"
load={load}
errMsg="Failed to load user information!"
errAdditionalElement={() => (
<>
<Button onClick={signOut}>Sign out</Button>
</>
)}
build={() => (
<AuthInfoContextK
value={{
info: authInfo!,
reloadAuthInfo: load,
}}
>
<UnmatchedInboxEntriesCountProvider>
<AccountsListProvider>
<ChooseAccountDialogProvider>
<Box
component="div"
sx={{
minHeight: "100vh",
display: "flex",
flexDirection: "column",
backgroundColor: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[100]
: theme.palette.grey[900],
color: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[900]
: theme.palette.grey[100],
}}
>
<MoneyWebAppBar onSignOut={signOut} />
<Box
sx={{
display: "flex",
flex: "2",
}}
>
<MoneyNavList />
<div
style={{
flexGrow: 1,
flexShrink: 0,
flexBasis: 0,
minWidth: 0,
display: "flex",
}}
>
<Outlet />
</div>
</Box>
</Box>
</ChooseAccountDialogProvider>
</AccountsListProvider>
</UnmatchedInboxEntriesCountProvider>
</AuthInfoContextK>
)}
/>
);
}
export function useAuthInfo(): AuthInfoContext {
return React.use(AuthInfoContextK)!;
}