GeneIT/geneit_app/src/widgets/BaseAuthenticatedPage.tsx

152 lines
4.5 KiB
TypeScript

import { mdiFamilyTree } from "@mdi/js";
import Icon from "@mdi/react";
import SettingsIcon from "@mui/icons-material/Settings";
import { Box, Button } from "@mui/material";
import AppBar from "@mui/material/AppBar";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import Toolbar from "@mui/material/Toolbar";
import Typography from "@mui/material/Typography";
import * as React from "react";
import { Link, Outlet, useNavigate } from "react-router-dom";
import { useAuth } from "../App";
import { AuthApi } from "../api/AuthApi";
import { User, UserApi } from "../api/UserApi";
import { AsyncWidget } from "./AsyncWidget";
import { RouterLink } from "./RouterLink";
import { DarkThemeButton } from "./DarkThemeButton";
interface UserContext {
user: User;
reloadUserInfo: () => void;
}
const UserContextK = React.createContext<UserContext | null>(null);
export function BaseAuthenticatedPage(): React.ReactElement {
const [user, setUser] = React.useState<null | User>(null);
const auth = useAuth();
const navigate = useNavigate();
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const load = async () => {
setUser(await UserApi.GetUserInfo());
};
const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
const handleCloseMenu = () => {
setAnchorEl(null);
};
const signOut = () => {
handleCloseMenu();
AuthApi.SignOut();
navigate("/");
auth.setSignedIn(false);
};
return (
<AsyncWidget
loadKey="1"
load={load}
errMsg="Echec du chargement des informations utilisateur !"
errAdditionalElement={() => (
<>
<Button onClick={signOut}>Déconnexion</Button>
</>
)}
build={() => (
<UserContextK.Provider
value={{
user: user!,
reloadUserInfo: load,
}}
>
<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],
}}
>
<AppBar position="sticky">
<Toolbar>
<Icon
path={mdiFamilyTree}
size={1}
style={{ marginRight: "1rem" }}
/>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
<RouterLink to="/">GeneIT</RouterLink>
</Typography>
<div>
<DarkThemeButton />
<Button size="large" color="inherit">
{user!.name}
</Button>
<Button
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleMenu}
color="inherit"
>
<SettingsIcon />
</Button>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={Boolean(anchorEl)}
onClose={handleCloseMenu}
>
<Link
to="/profile"
style={{ color: "inherit", textDecoration: "none" }}
>
<MenuItem onClick={handleCloseMenu}>Profil</MenuItem>
</Link>
<MenuItem onClick={signOut}>Déconnexion</MenuItem>
</Menu>
</div>
</Toolbar>
</AppBar>
<Outlet />
</Box>
</UserContextK.Provider>
)}
/>
);
}
export function useUser(): UserContext {
return React.useContext(UserContextK)!;
}