GeneIT/geneit_app/src/widgets/BaseFamilyRoute.tsx

222 lines
6.0 KiB
TypeScript
Raw Normal View History

2023-07-08 12:45:36 +02:00
import {
mdiAccountMultiple,
mdiCog,
2023-07-08 16:31:47 +02:00
mdiContentCopy,
2023-07-08 12:45:36 +02:00
mdiCrowd,
mdiFamilyTree,
mdiHumanMaleFemale,
2023-07-08 16:02:18 +02:00
mdiLockCheck,
2023-07-08 12:45:36 +02:00
} from "@mdi/js";
import Icon from "@mdi/react";
import HomeIcon from "@mui/icons-material/Home";
import {
Box,
Divider,
2023-07-08 16:31:47 +02:00
IconButton,
2023-07-08 12:45:36 +02:00
List,
2023-07-08 16:31:47 +02:00
ListItem,
2023-07-08 12:45:36 +02:00
ListItemButton,
ListItemIcon,
ListItemText,
ListSubheader,
2023-07-08 16:02:18 +02:00
Tooltip,
2023-07-08 12:45:36 +02:00
} from "@mui/material";
2023-07-08 16:31:47 +02:00
import { mdiRefresh } from "@mdi/js";
2023-07-08 11:59:55 +02:00
import React from "react";
2023-07-08 12:45:36 +02:00
import { Outlet, useLocation, useParams } from "react-router-dom";
import { Family, FamilyApi } from "../api/FamilyApi";
2023-07-08 11:59:55 +02:00
import { AsyncWidget } from "./AsyncWidget";
2023-07-08 12:45:36 +02:00
import { RouterLink } from "./RouterLink";
2023-07-08 16:54:26 +02:00
import { useSnackbar } from "../context_providers/SnackbarProvider";
import { useConfirm } from "../context_providers/ConfirmDialogProvider";
import { useAlert } from "../context_providers/AlertDialogProvider";
2023-07-08 11:59:55 +02:00
interface FamilyContext {
family: Family;
reloadFamilyInfo: () => void;
}
const FamilyContextK = React.createContext<FamilyContext | null>(null);
export function BaseFamilyRoute(): React.ReactElement {
const { familyId } = useParams();
2023-07-08 16:02:18 +02:00
const snackbar = useSnackbar();
2023-07-08 16:31:47 +02:00
const alert = useAlert();
const confirm = useConfirm();
2023-07-08 11:59:55 +02:00
const [family, setFamily] = React.useState<null | Family>(null);
const loadKey = React.useRef(1);
const load = async () => {
setFamily(await FamilyApi.GetSingle(Number(familyId)));
};
const onReload = () => {
loadKey.current += 1;
setFamily(null);
};
2023-07-08 16:02:18 +02:00
const copyInvitationCode = async () => {
navigator.clipboard.writeText(family!.invitation_code);
snackbar("Le code d'invitation a été copié dans le presse papier !");
};
2023-07-08 16:31:47 +02:00
const changeInvitationCode = async () => {
try {
if (
2023-07-09 17:35:12 +02:00
!(await confirm(
2023-07-08 16:31:47 +02:00
"Voulez-vous vraiment générer un nouveau code d'invitation pour cette famille ? Cette action aura pour effet d'invalider l'ancien code !"
))
)
return;
await FamilyApi.RenewInvitationCode(family!.family_id);
snackbar("Le code d'invitation a été changé avec succès !");
onReload();
} catch (e) {
console.error(e);
2023-07-09 17:35:12 +02:00
alert("Echec du renouvellement du code d'invitation !");
2023-07-08 16:31:47 +02:00
}
};
2023-07-08 11:59:55 +02:00
return (
<AsyncWidget
ready={family != null}
2023-07-08 16:31:47 +02:00
loadKey={`${familyId}-${loadKey.current}`}
2023-07-08 11:59:55 +02:00
load={load}
errMsg="Échec du chargement des informations de la famille !"
build={() => (
<FamilyContextK.Provider
value={{
family: family!,
reloadFamilyInfo: onReload,
}}
>
2023-07-08 16:02:18 +02:00
<Box
sx={{
display: "flex",
flex: "2",
}}
>
<List
component="nav"
sx={{
2023-07-08 16:31:47 +02:00
minWidth: "280px",
2023-07-08 16:02:18 +02:00
backgroundColor: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[100]
: "background.paper",
}}
>
2023-07-08 12:45:36 +02:00
<FamilyLink icon={<HomeIcon />} label="Accueil" uri="" />
<FamilyLink
icon={<Icon path={mdiCrowd} size={1} />}
label="Membres"
uri="members"
/>
<FamilyLink
icon={<Icon path={mdiHumanMaleFemale} size={1} />}
label="Couples"
uri="couples"
/>
<FamilyLink
icon={<Icon path={mdiFamilyTree} size={1} />}
label="Arbre"
uri="tree"
/>
<Divider sx={{ my: 1 }} />
2023-07-08 16:02:18 +02:00
<ListSubheader component="div">Administration</ListSubheader>
2023-07-08 12:45:36 +02:00
<FamilyLink
icon={<Icon path={mdiAccountMultiple} size={1} />}
label="Utilisateurs"
uri="users"
/>
<FamilyLink
icon={<Icon path={mdiCog} size={1} />}
label="Paramètres"
uri="settings"
/>
2023-07-08 16:02:18 +02:00
{/* Invitation code */}
2023-07-08 16:31:47 +02:00
<ListItem
dense
secondaryAction={
<span>
<Tooltip title="Copier le code d'invitation dans le presse papier">
<IconButton onClick={copyInvitationCode}>
<Icon path={mdiContentCopy} size={0.75} />
</IconButton>
</Tooltip>
{family!.is_admin && (
<Tooltip title="Changer le code d'activation">
<IconButton onClick={changeInvitationCode}>
<Icon path={mdiRefresh} size={0.75} />
</IconButton>
</Tooltip>
)}
</span>
}
>
<ListItemIcon>
<Icon path={mdiLockCheck} size={1} />
</ListItemIcon>
<ListItemText
primary="Code d'invitation"
secondary={family?.invitation_code}
/>
</ListItem>
2023-07-08 12:45:36 +02:00
</List>
<Box
component="main"
sx={{
flexGrow: 1,
overflow: "auto",
padding: "20px",
2023-07-09 17:02:43 +02:00
display: "flex",
flexDirection: "column",
2023-07-08 12:45:36 +02:00
}}
>
<Outlet />
</Box>
</Box>
2023-07-08 11:59:55 +02:00
</FamilyContextK.Provider>
)}
/>
);
}
export function useFamily(): FamilyContext {
return React.useContext(FamilyContextK)!;
}
2023-07-08 12:45:36 +02:00
function FamilyLink(p: {
icon: React.ReactElement;
uri: string;
label: string;
}): React.ReactElement {
const family = useFamily();
const location = useLocation();
const link = family.family.URL(p.uri);
return (
<RouterLink to={link}>
<ListItemButton selected={link === location.pathname}>
<ListItemIcon>{p.icon}</ListItemIcon>
<ListItemText primary={p.label} />
</ListItemButton>
</RouterLink>
);
}