Can download / delete member photo
This commit is contained in:
		@@ -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
 | 
					   * Delete a family member
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import EditIcon from "@mui/icons-material/Edit";
 | 
				
			|||||||
import SaveIcon from "@mui/icons-material/Save";
 | 
					import SaveIcon from "@mui/icons-material/Save";
 | 
				
			||||||
import { Button, Grid, Stack } from "@mui/material";
 | 
					import { Button, Grid, Stack } from "@mui/material";
 | 
				
			||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import FileDownloadIcon from "@mui/icons-material/FileDownload";
 | 
				
			||||||
import { useNavigate, useParams } from "react-router-dom";
 | 
					import { useNavigate, useParams } from "react-router-dom";
 | 
				
			||||||
import { Member, MemberApi } from "../../api/MemberApi";
 | 
					import { Member, MemberApi } from "../../api/MemberApi";
 | 
				
			||||||
import { ServerApi } from "../../api/ServerApi";
 | 
					import { ServerApi } from "../../api/ServerApi";
 | 
				
			||||||
@@ -21,6 +22,7 @@ import { PropEdit } from "../../widgets/forms/PropEdit";
 | 
				
			|||||||
import { SexSelection } from "../../widgets/forms/SexSelection";
 | 
					import { SexSelection } from "../../widgets/forms/SexSelection";
 | 
				
			||||||
import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton";
 | 
					import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton";
 | 
				
			||||||
import { MemberPhoto } from "../../widgets/MemberPhoto";
 | 
					import { MemberPhoto } from "../../widgets/MemberPhoto";
 | 
				
			||||||
 | 
					import { RouterLink } from "../../widgets/RouterLink";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Create a new member route
 | 
					 * Create a new member route
 | 
				
			||||||
@@ -238,6 +240,20 @@ export function MemberPage(p: {
 | 
				
			|||||||
    p.onForceReload?.();
 | 
					    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 (
 | 
					  return (
 | 
				
			||||||
    <div style={{ maxWidth: "2000px", margin: "auto" }}>
 | 
					    <div style={{ maxWidth: "2000px", margin: "auto" }}>
 | 
				
			||||||
      <ConfirmLeaveWithoutSaveDialog
 | 
					      <ConfirmLeaveWithoutSaveDialog
 | 
				
			||||||
@@ -410,11 +426,6 @@ export function MemberPage(p: {
 | 
				
			|||||||
          </PropertiesBox>
 | 
					          </PropertiesBox>
 | 
				
			||||||
        </Grid>
 | 
					        </Grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {/* Contact */}
 | 
					 | 
				
			||||||
        <Grid item sm={12} md={6}>
 | 
					 | 
				
			||||||
          <PropertiesBox title="Contact">TODO</PropertiesBox>
 | 
					 | 
				
			||||||
        </Grid>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        {/* Photo */}
 | 
					        {/* Photo */}
 | 
				
			||||||
        <Grid item sm={12} md={6}>
 | 
					        <Grid item sm={12} md={6}>
 | 
				
			||||||
          <PropertiesBox title="Photo">
 | 
					          <PropertiesBox title="Photo">
 | 
				
			||||||
@@ -429,19 +440,40 @@ export function MemberPage(p: {
 | 
				
			|||||||
              ) : (
 | 
					              ) : (
 | 
				
			||||||
                <>
 | 
					                <>
 | 
				
			||||||
                  <UploadPhotoButton
 | 
					                  <UploadPhotoButton
 | 
				
			||||||
                    label={
 | 
					                    label={member.hasPhoto ? "Remplacer" : "Ajouter"}
 | 
				
			||||||
                      member.hasPhoto
 | 
					 | 
				
			||||||
                        ? "Remplacer la photo"
 | 
					 | 
				
			||||||
                        : "Ajouter une photo"
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    onPhotoSelected={uploadNewPhoto}
 | 
					                    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>
 | 
					            </div>
 | 
				
			||||||
          </PropertiesBox>
 | 
					          </PropertiesBox>
 | 
				
			||||||
        </Grid>
 | 
					        </Grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {/* Contact */}
 | 
				
			||||||
 | 
					        <Grid item sm={12} md={6}>
 | 
				
			||||||
 | 
					          <PropertiesBox title="Contact">TODO</PropertiesBox>
 | 
				
			||||||
 | 
					        </Grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {/* Bio */}
 | 
					        {/* Bio */}
 | 
				
			||||||
        <Grid item sm={12} md={6}>
 | 
					        <Grid item sm={12} md={6}>
 | 
				
			||||||
          <PropertiesBox title="Biographie">TODO</PropertiesBox>
 | 
					          <PropertiesBox title="Biographie">TODO</PropertiesBox>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,10 +2,14 @@ import { PropsWithChildren } from "react";
 | 
				
			|||||||
import { Link } from "react-router-dom";
 | 
					import { Link } from "react-router-dom";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function RouterLink(
 | 
					export function RouterLink(
 | 
				
			||||||
  p: PropsWithChildren<{ to: string }>
 | 
					  p: PropsWithChildren<{ to: string; target?: React.HTMLAttributeAnchorTarget }>
 | 
				
			||||||
): React.ReactElement {
 | 
					): React.ReactElement {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Link to={p.to} style={{ color: "inherit", textDecoration: "inherit" }}>
 | 
					    <Link
 | 
				
			||||||
 | 
					      to={p.to}
 | 
				
			||||||
 | 
					      target={p.target}
 | 
				
			||||||
 | 
					      style={{ color: "inherit", textDecoration: "inherit" }}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      {p.children}
 | 
					      {p.children}
 | 
				
			||||||
    </Link>
 | 
					    </Link>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ import { ImageCropperDialog } from "../../dialogs/ImageCropperDialog";
 | 
				
			|||||||
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
 | 
					import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
 | 
				
			||||||
import { Area } from "react-easy-crop";
 | 
					import { Area } from "react-easy-crop";
 | 
				
			||||||
import getCroppedImg from "../../utils/crop_image";
 | 
					import getCroppedImg from "../../utils/crop_image";
 | 
				
			||||||
 | 
					import UploadIcon from "@mui/icons-material/Upload";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function UploadPhotoButton(p: {
 | 
					export function UploadPhotoButton(p: {
 | 
				
			||||||
  label: string;
 | 
					  label: string;
 | 
				
			||||||
@@ -82,7 +83,13 @@ export function UploadPhotoButton(p: {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      {/* Upload button */}
 | 
					      {/* Upload button */}
 | 
				
			||||||
      <Button onClick={uploadPhoto}>{p.label}</Button>
 | 
					      <Button
 | 
				
			||||||
 | 
					        onClick={uploadPhoto}
 | 
				
			||||||
 | 
					        variant="outlined"
 | 
				
			||||||
 | 
					        startIcon={<UploadIcon />}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        {p.label}
 | 
				
			||||||
 | 
					      </Button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      {/* Crop image dialog */}
 | 
					      {/* Crop image dialog */}
 | 
				
			||||||
      {imageURL && (
 | 
					      {imageURL && (
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user