Can download / delete member photo
This commit is contained in:
parent
1cf79e621f
commit
39c7163290
@ -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
|
||||
*/
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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 && (
|
||||
|
Loading…
Reference in New Issue
Block a user