260 lines
6.9 KiB
TypeScript
260 lines
6.9 KiB
TypeScript
import AddIcon from "@mui/icons-material/Add";
|
|
import ConfirmationNumberIcon from "@mui/icons-material/ConfirmationNumber";
|
|
import {
|
|
Button,
|
|
Card,
|
|
CardActionArea,
|
|
CardActions,
|
|
CardContent,
|
|
IconButton,
|
|
Tooltip,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import React from "react";
|
|
import { Family, FamilyApi } from "../api/FamilyApi";
|
|
import { CreateFamilyDialog } from "../dialogs/CreateFamilyDialog";
|
|
import { JoinFamilyDialog } from "../dialogs/JoinFamilyDialog";
|
|
import { useAlert } from "../context_providers/AlertDialogProvider";
|
|
import { AsyncWidget } from "../widgets/AsyncWidget";
|
|
import { useConfirm } from "../context_providers/ConfirmDialogProvider";
|
|
import { RouterLink } from "../widgets/RouterLink";
|
|
import { TimeWidget } from "../widgets/TimeWidget";
|
|
|
|
export function FamiliesListRoute(): React.ReactElement {
|
|
const loadKey = React.useRef(1);
|
|
|
|
const [families, setFamilies] = React.useState<Family[] | null>(null);
|
|
|
|
const [createFamily, setCreateFamily] = React.useState(false);
|
|
const [joinFamily, setJoinFamily] = React.useState(false);
|
|
|
|
const load = async () => {
|
|
setFamilies(await FamilyApi.GetList());
|
|
};
|
|
|
|
const reload = () => {
|
|
loadKey.current += 1;
|
|
setFamilies(null);
|
|
};
|
|
|
|
const onRequestCreateFamily = async () => {
|
|
setCreateFamily(true);
|
|
};
|
|
|
|
const onRequestJoinFamily = async () => {
|
|
setJoinFamily(true);
|
|
};
|
|
|
|
return (
|
|
<AsyncWidget
|
|
ready={families !== null}
|
|
loadKey={`families-list-${loadKey.current}`}
|
|
load={load}
|
|
errMsg="Echec du chargement de la liste des familles"
|
|
build={() => (
|
|
<>
|
|
{families!!.length === 0 ? (
|
|
<NoFamilyWidget
|
|
onRequestCreateFamily={onRequestCreateFamily}
|
|
onRequestJoinFamily={onRequestJoinFamily}
|
|
/>
|
|
) : (
|
|
<HasFamiliesWidget
|
|
onRequestCreateFamily={onRequestCreateFamily}
|
|
onRequestJoinFamily={onRequestJoinFamily}
|
|
onRequestRefresh={reload}
|
|
families={families!}
|
|
/>
|
|
)}
|
|
|
|
{/** Create family dialog anchor */}
|
|
<CreateFamilyDialog
|
|
open={createFamily}
|
|
onClose={() => setCreateFamily(false)}
|
|
onCreated={() => {
|
|
setCreateFamily(false);
|
|
reload();
|
|
}}
|
|
/>
|
|
|
|
{/** Join family dialog anchor */}
|
|
<JoinFamilyDialog
|
|
open={joinFamily}
|
|
onClose={() => setJoinFamily(false)}
|
|
onJoined={() => {
|
|
setJoinFamily(false);
|
|
reload();
|
|
}}
|
|
/>
|
|
</>
|
|
)}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function NoFamilyWidget(p: {
|
|
onRequestCreateFamily: () => void;
|
|
onRequestJoinFamily: () => void;
|
|
}): React.ReactElement {
|
|
return (
|
|
<div style={{ flex: 1, display: "flex", alignItems: "center" }}>
|
|
<Typography variant="h3" style={{ flex: 3, textAlign: "center" }}>
|
|
Vous n'appartenez à aucune famille !
|
|
</Typography>
|
|
|
|
<div
|
|
style={{
|
|
flex: 2,
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<NoFamilyButton
|
|
label="Créer une famille"
|
|
onClick={p.onRequestCreateFamily}
|
|
/>
|
|
|
|
<NoFamilyButton
|
|
label="Rejoindre une famille"
|
|
onClick={p.onRequestJoinFamily}
|
|
/>
|
|
</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>
|
|
);
|
|
}
|
|
|
|
function HasFamiliesWidget(p: {
|
|
families: Family[];
|
|
onRequestCreateFamily: () => void;
|
|
onRequestJoinFamily: () => void;
|
|
onRequestRefresh: () => void;
|
|
}): React.ReactElement {
|
|
return (
|
|
<div style={{ width: "100%", maxWidth: "800px", margin: "20px auto" }}>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
marginBottom: "10px",
|
|
}}
|
|
>
|
|
<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>
|
|
|
|
{/* Display user memberships */}
|
|
{p.families.map((f) => (
|
|
<FamilyCard key={f.family_id} f={f} onFamilyLeft={p.onRequestRefresh} />
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function FamilyCard(p: {
|
|
f: Family;
|
|
onFamilyLeft: () => void;
|
|
}): React.ReactElement {
|
|
const confirm = useConfirm();
|
|
const alert = useAlert();
|
|
|
|
const leaveFamily = async () => {
|
|
try {
|
|
if (
|
|
!p.f.CanLeave ||
|
|
!(await confirm(
|
|
"Voulez-vous vraiment quitter la famille " + p.f.name + " ?"
|
|
))
|
|
)
|
|
return;
|
|
|
|
await FamilyApi.LeaveFamily(p.f.family_id);
|
|
|
|
p.onFamilyLeft();
|
|
|
|
alert(
|
|
`La famille ${p.f.name} a été retirée de votre liste de familles !`
|
|
);
|
|
} catch (e) {
|
|
console.error(e);
|
|
alert("Echec du retrait de la famille !");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Card style={{ margin: "5px" }}>
|
|
<CardActionArea>
|
|
<RouterLink to={p.f.BaseURL}>
|
|
<CardContent>
|
|
<Typography gutterBottom variant="h5" component="div">
|
|
{p.f.name}
|
|
</Typography>
|
|
<Typography variant="body2" color="text.secondary">
|
|
<span style={{ fontStyle: "italic" }}>
|
|
{p.f.is_admin ? "Administrateur" : "Membre"}
|
|
</span>
|
|
<br />
|
|
{p.f.count_members === 1
|
|
? "1 membre"
|
|
: p.f.count_members + " membres"}
|
|
<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>
|
|
</CardActionArea>
|
|
<CardActions>
|
|
<Tooltip
|
|
title={
|
|
p.f.CanLeave
|
|
? "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"
|
|
disabled={!p.f.CanLeave}
|
|
onClick={leaveFamily}
|
|
>
|
|
Quitter
|
|
</Button>
|
|
</span>
|
|
</Tooltip>
|
|
</CardActions>
|
|
</Card>
|
|
);
|
|
}
|