Can set member photo
This commit is contained in:
@ -2,7 +2,7 @@ import ClearIcon from "@mui/icons-material/Clear";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import SaveIcon from "@mui/icons-material/Save";
|
||||
import { Button, Checkbox, FormControlLabel, Grid, Stack } from "@mui/material";
|
||||
import { Button, Grid, Stack } from "@mui/material";
|
||||
import React from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Member, MemberApi } from "../../api/MemberApi";
|
||||
@ -14,11 +14,13 @@ import { AsyncWidget } from "../../widgets/AsyncWidget";
|
||||
import { useFamily } from "../../widgets/BaseFamilyRoute";
|
||||
import { ConfirmLeaveWithoutSaveDialog } from "../../widgets/ConfirmLeaveWithoutSaveDialog";
|
||||
import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
|
||||
import { PropEdit } from "../../widgets/forms/PropEdit";
|
||||
import { PropertiesBox } from "../../widgets/PropertiesBox";
|
||||
import { SexSelection } from "../../widgets/forms/SexSelection";
|
||||
import { DateInput } from "../../widgets/forms/DateInput";
|
||||
import { PropCheckbox } from "../../widgets/forms/PropCheckbox";
|
||||
import { PropEdit } from "../../widgets/forms/PropEdit";
|
||||
import { SexSelection } from "../../widgets/forms/SexSelection";
|
||||
import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton";
|
||||
import { MemberPhoto } from "../../widgets/MemberPhoto";
|
||||
|
||||
/**
|
||||
* Create a new member route
|
||||
@ -67,6 +69,8 @@ export function FamilyCreateMemberRoute(): React.ReactElement {
|
||||
* Get existing member route
|
||||
*/
|
||||
export function FamilyMemberRoute(): React.ReactElement {
|
||||
const count = React.useRef(1);
|
||||
|
||||
const n = useNavigate();
|
||||
const alert = useAlert();
|
||||
const confirm = useConfirm();
|
||||
@ -80,6 +84,13 @@ export function FamilyMemberRoute(): React.ReactElement {
|
||||
setMember(await MemberApi.GetSingle(family.familyId, Number(memberId)));
|
||||
};
|
||||
|
||||
const forceReload = async () => {
|
||||
count.current += 1;
|
||||
setMember(undefined);
|
||||
|
||||
await family.reloadMembersList();
|
||||
};
|
||||
|
||||
const deleteMember = async () => {
|
||||
try {
|
||||
if (
|
||||
@ -103,8 +114,9 @@ export function FamilyMemberRoute(): React.ReactElement {
|
||||
|
||||
return (
|
||||
<AsyncWidget
|
||||
loadKey={memberId}
|
||||
loadKey={`${memberId}-${count.current}`}
|
||||
load={load}
|
||||
ready={member !== undefined}
|
||||
errMsg="Echec du chargement des informations du membre"
|
||||
build={() => (
|
||||
<MemberPage
|
||||
@ -115,6 +127,7 @@ export function FamilyMemberRoute(): React.ReactElement {
|
||||
onRequestEdit={() =>
|
||||
n(family.family.URL(`member/${member!.id}/edit`))
|
||||
}
|
||||
onForceReload={forceReload}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
@ -188,15 +201,19 @@ export function MemberPage(p: {
|
||||
onSave?: (m: Member) => void;
|
||||
onRequestEdit?: () => void;
|
||||
onRequestDelete?: () => void;
|
||||
onForceReload?: () => void;
|
||||
}): React.ReactElement {
|
||||
const confirm = useConfirm();
|
||||
const snackbar = useSnackbar();
|
||||
|
||||
const [changed, setChanged] = React.useState(false);
|
||||
const [member, setMember] = React.useState(structuredClone(p.member));
|
||||
const [member, setMember] = React.useState(
|
||||
new Member(structuredClone(p.member))
|
||||
);
|
||||
|
||||
const updatedMember = () => {
|
||||
setChanged(true);
|
||||
setMember(structuredClone(member));
|
||||
setMember(new Member(structuredClone(member)));
|
||||
};
|
||||
|
||||
const save = () => {
|
||||
@ -215,6 +232,12 @@ export function MemberPage(p: {
|
||||
p.onCancel!();
|
||||
};
|
||||
|
||||
const uploadNewPhoto = async (b: Blob) => {
|
||||
await MemberApi.SetMemberPhoto(member, b);
|
||||
snackbar("La photo du membre a été mise à jour avec succès !");
|
||||
p.onForceReload?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ maxWidth: "2000px", margin: "auto" }}>
|
||||
<ConfirmLeaveWithoutSaveDialog
|
||||
@ -287,7 +310,9 @@ export function MemberPage(p: {
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Grid container spacing={2}>
|
||||
{/* General info */}
|
||||
<Grid item sm={12} md={6}>
|
||||
<PropertiesBox title="Informations générales">
|
||||
{/* Sex */}
|
||||
@ -384,20 +409,52 @@ export function MemberPage(p: {
|
||||
/>
|
||||
</PropertiesBox>
|
||||
</Grid>
|
||||
|
||||
{/* Contact */}
|
||||
<Grid item sm={12} md={6}>
|
||||
<PropertiesBox title="Contact"></PropertiesBox>
|
||||
<PropertiesBox title="Contact">TODO</PropertiesBox>
|
||||
</Grid>
|
||||
|
||||
{/* Photo */}
|
||||
<Grid item sm={12} md={6}>
|
||||
<PropertiesBox title="Photo"></PropertiesBox>
|
||||
<PropertiesBox title="Photo">
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<MemberPhoto member={member} width={150} />
|
||||
<br />
|
||||
{p.editing ? (
|
||||
<p>
|
||||
Veuillez enregistrer / annuler les modifications apportées à
|
||||
la fiche avant de changer la photo du membre.
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
<UploadPhotoButton
|
||||
label={
|
||||
member.hasPhoto
|
||||
? "Remplacer la photo"
|
||||
: "Ajouter une photo"
|
||||
}
|
||||
onPhotoSelected={uploadNewPhoto}
|
||||
/>
|
||||
</>
|
||||
)}{" "}
|
||||
</div>
|
||||
</PropertiesBox>
|
||||
</Grid>
|
||||
|
||||
{/* Bio */}
|
||||
<Grid item sm={12} md={6}>
|
||||
<PropertiesBox title="Biographie"></PropertiesBox>
|
||||
<PropertiesBox title="Biographie">TODO</PropertiesBox>
|
||||
</Grid>
|
||||
|
||||
{/* Spouse */}
|
||||
<Grid item sm={12} md={6}>
|
||||
<PropertiesBox title={member.sex === "F" ? "Époux" : "Épouse"}>
|
||||
TODO
|
||||
</PropertiesBox>
|
||||
</Grid>
|
||||
|
||||
{/* Children */}
|
||||
<Grid item sm={12} md={6}>
|
||||
<PropertiesBox title="Enfants">TODO</PropertiesBox>
|
||||
</Grid>
|
||||
|
Reference in New Issue
Block a user