GeneIT/geneit_app/src/routes/FamiliesListRoute.tsx

260 lines
6.9 KiB
TypeScript
Raw Normal View History

2023-07-04 17:05:36 +00:00
import AddIcon from "@mui/icons-material/Add";
import ConfirmationNumberIcon from "@mui/icons-material/ConfirmationNumber";
2023-07-07 16:41:00 +00:00
import {
Button,
Card,
CardActionArea,
CardActions,
CardContent,
IconButton,
Tooltip,
Typography,
} from "@mui/material";
2023-06-27 15:13:12 +00:00
import React from "react";
2023-07-04 17:05:36 +00:00
import { Family, FamilyApi } from "../api/FamilyApi";
2023-06-27 15:13:12 +00:00
import { CreateFamilyDialog } from "../dialogs/CreateFamilyDialog";
2023-06-27 16:52:49 +00:00
import { JoinFamilyDialog } from "../dialogs/JoinFamilyDialog";
2023-07-08 14:54:26 +00:00
import { useAlert } from "../context_providers/AlertDialogProvider";
2023-07-04 17:05:36 +00:00
import { AsyncWidget } from "../widgets/AsyncWidget";
2023-07-08 14:54:26 +00:00
import { useConfirm } from "../context_providers/ConfirmDialogProvider";
2023-07-07 16:57:43 +00:00
import { RouterLink } from "../widgets/RouterLink";
import { TimeWidget } from "../widgets/TimeWidget";
2023-06-27 15:13:12 +00:00
export function FamiliesListRoute(): React.ReactElement {
const loadKey = React.useRef(1);
const [families, setFamilies] = React.useState<Family[] | null>(null);
const [createFamily, setCreateFamily] = React.useState(false);
2023-06-27 16:52:49 +00:00
const [joinFamily, setJoinFamily] = React.useState(false);
2023-06-27 15:13:12 +00:00
const load = async () => {
2023-07-04 17:05:36 +00:00
setFamilies(await FamilyApi.GetList());
2023-06-27 15:13:12 +00:00
};
const reload = () => {
loadKey.current += 1;
2023-07-07 16:41:00 +00:00
setFamilies(null);
2023-06-27 15:13:12 +00:00
};
const onRequestCreateFamily = async () => {
setCreateFamily(true);
};
2023-06-27 16:52:49 +00:00
const onRequestJoinFamily = async () => {
setJoinFamily(true);
};
2023-06-27 15:13:12 +00:00
return (
<AsyncWidget
2023-06-27 17:03:39 +00:00
ready={families !== null}
loadKey={`families-list-${loadKey.current}`}
2023-06-27 15:13:12 +00:00
load={load}
errMsg="Echec du chargement de la liste des familles"
build={() => (
<>
{families!!.length === 0 ? (
2023-06-27 16:52:49 +00:00
<NoFamilyWidget
onRequestCreateFamily={onRequestCreateFamily}
onRequestJoinFamily={onRequestJoinFamily}
/>
2023-06-27 15:13:12 +00:00
) : (
2023-07-07 16:41:00 +00:00
<HasFamiliesWidget
2023-07-04 17:05:36 +00:00
onRequestCreateFamily={onRequestCreateFamily}
onRequestJoinFamily={onRequestJoinFamily}
2023-07-07 16:41:00 +00:00
onRequestRefresh={reload}
2023-07-04 17:05:36 +00:00
families={families!}
/>
2023-06-27 15:13:12 +00:00
)}
{/** Create family dialog anchor */}
<CreateFamilyDialog
open={createFamily}
onClose={() => setCreateFamily(false)}
onCreated={() => {
setCreateFamily(false);
reload();
}}
/>
2023-06-27 16:52:49 +00:00
{/** Join family dialog anchor */}
<JoinFamilyDialog
open={joinFamily}
onClose={() => setJoinFamily(false)}
onJoined={() => {
setJoinFamily(false);
reload();
}}
/>
2023-06-27 15:13:12 +00:00
</>
)}
/>
);
}
function NoFamilyWidget(p: {
onRequestCreateFamily: () => void;
2023-06-27 16:52:49 +00:00
onRequestJoinFamily: () => void;
2023-06-27 15:13:12 +00:00
}): React.ReactElement {
return (
<div style={{ flex: 1, display: "flex", alignItems: "center" }}>
2023-07-04 16:47:37 +00:00
<Typography variant="h3" style={{ flex: 3, textAlign: "center" }}>
2023-06-27 15:13:12 +00:00
Vous n'appartenez à aucune famille !
</Typography>
<div
style={{
2023-07-04 16:47:37 +00:00
flex: 2,
2023-06-27 15:13:12 +00:00
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<NoFamilyButton
label="Créer une famille"
onClick={p.onRequestCreateFamily}
/>
2023-06-27 16:52:49 +00:00
<NoFamilyButton
label="Rejoindre une famille"
onClick={p.onRequestJoinFamily}
/>
2023-06-27 15:13:12 +00:00
</div>
</div>
);
}
function NoFamilyButton(p: {
label: string;
onClick: () => void;
}): React.ReactElement {
return (
<Button
variant="outlined"
size="large"
style={{ width: "300px", marginBottom: "10px" }}
onClick={p.onClick}
>
{p.label}
</Button>
);
}
2023-07-07 16:41:00 +00:00
function HasFamiliesWidget(p: {
2023-06-27 15:13:12 +00:00
families: Family[];
2023-07-04 17:05:36 +00:00
onRequestCreateFamily: () => void;
onRequestJoinFamily: () => void;
2023-07-07 16:41:00 +00:00
onRequestRefresh: () => void;
2023-06-27 15:13:12 +00:00
}): React.ReactElement {
2023-07-04 17:05:36 +00:00
return (
<div style={{ width: "100%", maxWidth: "800px", margin: "20px auto" }}>
2023-07-07 16:41:00 +00:00
<div
style={{
display: "flex",
justifyContent: "space-between",
marginBottom: "10px",
}}
>
2023-07-04 17:05:36 +00:00
<Typography variant="h4">Mes familles</Typography>
<div>
<IconButton aria-label="create" onClick={p.onRequestCreateFamily}>
<Tooltip title="Créer une nouvelle famille">
<AddIcon />
</Tooltip>
</IconButton>
<IconButton aria-label="create" onClick={p.onRequestJoinFamily}>
<Tooltip title="Rejoindre une famille">
<ConfirmationNumberIcon />
</Tooltip>
</IconButton>
</div>
</div>
2023-07-07 16:41:00 +00:00
{/* Display user memberships */}
{p.families.map((f) => (
<FamilyCard key={f.family_id} f={f} onFamilyLeft={p.onRequestRefresh} />
))}
2023-07-04 17:05:36 +00:00
</div>
);
2023-06-27 15:13:12 +00:00
}
2023-07-07 16:41:00 +00:00
function FamilyCard(p: {
f: Family;
onFamilyLeft: () => void;
}): React.ReactElement {
const confirm = useConfirm();
const alert = useAlert();
const leaveFamily = async () => {
try {
if (
2023-07-07 16:57:43 +00:00
!p.f.CanLeave ||
2023-07-07 16:41:00 +00:00
!(await confirm.confirm(
"Voulez-vous vraiment quitter la famille " + p.f.name + " ?"
))
)
return;
await FamilyApi.LeaveFamily(p.f.family_id);
p.onFamilyLeft();
alert.alert(
`La famille ${p.f.name} a été retirée de votre liste de familles !`
);
} catch (e) {
console.error(e);
alert.alert("Echec du retrait de la famille !");
}
};
return (
<Card style={{ margin: "5px" }}>
<CardActionArea>
2023-07-07 16:57:43 +00:00
<RouterLink to={p.f.BaseURL}>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{p.f.name}
</Typography>
<Typography variant="body2" color="text.secondary">
2023-07-08 14:31:47 +00:00
<span style={{ fontStyle: "italic" }}>
{p.f.is_admin ? "Administrateur" : "Membre"}
</span>
<br />
2023-07-07 16:57:43 +00:00
{p.f.count_members === 1
? "1 membre"
2023-07-08 14:31:47 +00:00
: p.f.count_members + " membres"}
2023-07-07 16:57:43 +00:00
<br />
{p.f.count_admins === 1
? "1 administrateur"
: p.f.count_admins + " administrateurs"}
<br />
Famille créée il y a <TimeWidget time={p.f.time_create} />
</Typography>
</CardContent>{" "}
</RouterLink>
2023-07-07 16:41:00 +00:00
</CardActionArea>
<CardActions>
<Tooltip
title={
2023-07-07 16:57:43 +00:00
p.f.CanLeave
2023-07-07 16:41:00 +00:00
? "Quitter la famille"
: "Vous ne pouvez pas quitter cette famille, pour la retirer de cette liste vous devez la supprimer."
}
>
<span style={{ marginLeft: "auto" }}>
<Button
size="small"
color="primary"
2023-07-07 16:57:43 +00:00
disabled={!p.f.CanLeave}
2023-07-07 16:41:00 +00:00
onClick={leaveFamily}
>
Quitter
</Button>
</span>
</Tooltip>
</CardActions>
</Card>
);
}