Can download / delete member photo

This commit is contained in:
Pierre HUBERT 2023-08-10 13:53:23 +02:00
parent 1cf79e621f
commit 39c7163290
4 changed files with 67 additions and 14 deletions

View File

@ -199,6 +199,16 @@ export class MemberApi {
});
}
/**
* Remove the photo of a member
*/
static async RemoveMemberPhoto(m: Member): Promise<void> {
await APIClient.exec({
uri: `/family/${m.family_id}/member/${m.id}/photo`,
method: "DELETE",
});
}
/**
* Delete a family member
*/

View File

@ -4,6 +4,7 @@ import EditIcon from "@mui/icons-material/Edit";
import SaveIcon from "@mui/icons-material/Save";
import { Button, Grid, Stack } from "@mui/material";
import React from "react";
import FileDownloadIcon from "@mui/icons-material/FileDownload";
import { useNavigate, useParams } from "react-router-dom";
import { Member, MemberApi } from "../../api/MemberApi";
import { ServerApi } from "../../api/ServerApi";
@ -21,6 +22,7 @@ import { PropEdit } from "../../widgets/forms/PropEdit";
import { SexSelection } from "../../widgets/forms/SexSelection";
import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton";
import { MemberPhoto } from "../../widgets/MemberPhoto";
import { RouterLink } from "../../widgets/RouterLink";
/**
* Create a new member route
@ -238,6 +240,20 @@ export function MemberPage(p: {
p.onForceReload?.();
};
const deletePhoto = async () => {
try {
if (!(await confirm("Voulez-vous supprimer cette photo ?"))) return;
await MemberApi.RemoveMemberPhoto(member);
snackbar("La photo du membre a été supprimée avec succès !");
p.onForceReload?.();
} catch (e) {
console.error(e);
alert("Échec de la suppresion de la photo !");
}
};
return (
<div style={{ maxWidth: "2000px", margin: "auto" }}>
<ConfirmLeaveWithoutSaveDialog
@ -410,11 +426,6 @@ export function MemberPage(p: {
</PropertiesBox>
</Grid>
{/* Contact */}
<Grid item sm={12} md={6}>
<PropertiesBox title="Contact">TODO</PropertiesBox>
</Grid>
{/* Photo */}
<Grid item sm={12} md={6}>
<PropertiesBox title="Photo">
@ -429,19 +440,40 @@ export function MemberPage(p: {
) : (
<>
<UploadPhotoButton
label={
member.hasPhoto
? "Remplacer la photo"
: "Ajouter une photo"
}
label={member.hasPhoto ? "Remplacer" : "Ajouter"}
onPhotoSelected={uploadNewPhoto}
/>
/>{" "}
{member.hasPhoto && (
<RouterLink to={member.photoURL} target="_blank">
<Button
variant="outlined"
startIcon={<FileDownloadIcon />}
>
Télécharger
</Button>
</RouterLink>
)}{" "}
{member.hasPhoto && (
<Button
variant="outlined"
startIcon={<DeleteIcon />}
color="error"
onClick={deletePhoto}
>
Supprimer
</Button>
)}
</>
)}{" "}
</div>
</PropertiesBox>
</Grid>
{/* Contact */}
<Grid item sm={12} md={6}>
<PropertiesBox title="Contact">TODO</PropertiesBox>
</Grid>
{/* Bio */}
<Grid item sm={12} md={6}>
<PropertiesBox title="Biographie">TODO</PropertiesBox>

View File

@ -2,10 +2,14 @@ import { PropsWithChildren } from "react";
import { Link } from "react-router-dom";
export function RouterLink(
p: PropsWithChildren<{ to: string }>
p: PropsWithChildren<{ to: string; target?: React.HTMLAttributeAnchorTarget }>
): React.ReactElement {
return (
<Link to={p.to} style={{ color: "inherit", textDecoration: "inherit" }}>
<Link
to={p.to}
target={p.target}
style={{ color: "inherit", textDecoration: "inherit" }}
>
{p.children}
</Link>
);

View File

@ -6,6 +6,7 @@ import { ImageCropperDialog } from "../../dialogs/ImageCropperDialog";
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
import { Area } from "react-easy-crop";
import getCroppedImg from "../../utils/crop_image";
import UploadIcon from "@mui/icons-material/Upload";
export function UploadPhotoButton(p: {
label: string;
@ -82,7 +83,13 @@ export function UploadPhotoButton(p: {
return (
<>
{/* Upload button */}
<Button onClick={uploadPhoto}>{p.label}</Button>
<Button
onClick={uploadPhoto}
variant="outlined"
startIcon={<UploadIcon />}
>
{p.label}
</Button>
{/* Crop image dialog */}
{imageURL && (