Ready to implement family tree

This commit is contained in:
Pierre HUBERT 2023-08-21 12:45:37 +02:00
parent 6f54ae2ceb
commit c414defb19
4 changed files with 157 additions and 1 deletions

View File

@ -34,6 +34,8 @@ import {
FamilyEditCoupleRoute, FamilyEditCoupleRoute,
} from "./routes/family/FamilyCoupleRoute"; } from "./routes/family/FamilyCoupleRoute";
import { FamilyCouplesListRoute } from "./routes/family/FamilyCouplesListRoute"; import { FamilyCouplesListRoute } from "./routes/family/FamilyCouplesListRoute";
import { FamilyTreeRoute } from "./routes/family/FamilyTreeRoute";
import { FamilyMemberTreeRoute } from "./routes/family/FamilyMemberTreeRoute";
interface AuthContext { interface AuthContext {
signedIn: boolean; signedIn: boolean;
@ -87,6 +89,12 @@ export function App(): React.ReactElement {
element={<FamilyEditCoupleRoute />} element={<FamilyEditCoupleRoute />}
/> />
<Route path="tree" element={<FamilyTreeRoute />} />
<Route
path="tree/:memberId"
element={<FamilyMemberTreeRoute />}
/>
<Route path="settings" element={<FamilySettingsRoute />} /> <Route path="settings" element={<FamilySettingsRoute />} />
<Route path="users" element={<FamilyUsersListRoute />} /> <Route path="users" element={<FamilyUsersListRoute />} />
<Route path="*" element={<NotFoundRoute />} /> <Route path="*" element={<NotFoundRoute />} />

View File

@ -0,0 +1,108 @@
import { useParams } from "react-router-dom";
import { useFamily } from "../../widgets/BaseFamilyRoute";
import {
Alert,
FormControl,
FormControlLabel,
FormLabel,
IconButton,
Paper,
Radio,
RadioGroup,
Tab,
Tabs,
} from "@mui/material";
import { MemberItem } from "../../widgets/MemberItem";
import ClearIcon from "@mui/icons-material/Clear";
import { RouterLink } from "../../widgets/RouterLink";
import React from "react";
enum CurrTab {
BasicTree,
AdvancedTree,
}
enum TreeMode {
Ascending,
Descending,
}
export function FamilyMemberTreeRoute(): React.ReactElement {
const { memberId } = useParams();
const family = useFamily();
const [currTab, setCurrTab] = React.useState(CurrTab.BasicTree);
const [currMode, setCurrMode] = React.useState(TreeMode.Descending);
const member = family.members.get(Number(memberId));
if (!member) {
return (
<Alert severity="error">
L'arbre ne peut pas être constuit : le membre n'existe pas !
</Alert>
);
}
return (
<div
style={{
flex: "1",
display: "flex",
flexDirection: "column",
marginBottom: "10px",
}}
>
{/* parent bar */}
<div style={{ display: "flex" }}>
<MemberItem
dense
member={member}
secondary={
<RouterLink to={family.family.URL("tree")}>
<IconButton>
<ClearIcon />
</IconButton>
</RouterLink>
}
/>
<div style={{ flex: "10" }}></div>
<FormControl>
<FormLabel>Arbre</FormLabel>
<RadioGroup
row
value={currMode}
onChange={(_e, v) => setCurrMode(Number(v))}
>
<FormControlLabel
value={TreeMode.Descending}
control={<Radio />}
label="Descendant"
/>
<FormControlLabel
value={TreeMode.Ascending}
control={<Radio />}
label="Ascendant"
/>
</RadioGroup>
</FormControl>
<div style={{ flex: "2" }}></div>
<Tabs
value={currTab}
onChange={(_e, v) => setCurrTab(v)}
aria-label="basic tabs example"
>
<Tab tabIndex={CurrTab.BasicTree} label="Basique" />
<Tab tabIndex={CurrTab.AdvancedTree} label="Avancé" />
</Tabs>
</div>
{/* the tree itself */}
<Paper style={{ flex: "1" }}>todo</Paper>
</div>
);
}

View File

@ -0,0 +1,39 @@
import { useNavigate } from "react-router-dom";
import { MemberInput } from "../../widgets/forms/MemberInput";
import { useFamily } from "../../widgets/BaseFamilyRoute";
export function FamilyTreeRoute(): React.ReactElement {
const n = useNavigate();
const family = useFamily();
const onMemberSelected = (id: number | undefined) => {
if (id) n(family.family.URL(`tree/${id}`));
};
return (
<div
style={{
flex: "1",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}
>
<div style={{ maxWidth: "450px", textAlign: "center" }}>
<p>
Veuillez sélectionner la personne à partir de laquelle vous souhaitez
constuire l'arbre généalogique de votre famille :
</p>
<MemberInput
editable={true}
onValueChange={onMemberSelected}
label={"Membre"}
filter={() => true}
/>
</div>
</div>
);
}

View File

@ -12,12 +12,13 @@ import FemaleIcon from "@mui/icons-material/Female";
import MaleIcon from "@mui/icons-material/Male"; import MaleIcon from "@mui/icons-material/Male";
export function MemberItem(p: { export function MemberItem(p: {
dense?: boolean;
member?: Member; member?: Member;
onClick?: () => void; onClick?: () => void;
secondary?: React.ReactElement; secondary?: React.ReactElement;
}): React.ReactElement { }): React.ReactElement {
return ( return (
<ListItemButton onClick={p.onClick}> <ListItemButton onClick={p.onClick} dense={p.dense}>
<ListItemAvatar> <ListItemAvatar>
<MemberPhoto member={p.member!} /> <MemberPhoto member={p.member!} />
</ListItemAvatar> </ListItemAvatar>