Can set member photo
This commit is contained in:
98
geneit_app/src/widgets/forms/UploadPhotoButton.tsx
Normal file
98
geneit_app/src/widgets/forms/UploadPhotoButton.tsx
Normal file
@ -0,0 +1,98 @@
|
||||
import { Button } from "@mui/material";
|
||||
import { filesize } from "filesize";
|
||||
import React from "react";
|
||||
import { ServerApi } from "../../api/ServerApi";
|
||||
import { ImageCropperDialog } from "../../dialogs/ImageCropperDialog";
|
||||
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
||||
import { Area } from "react-easy-crop";
|
||||
import getCroppedImg from "../../utils/crop_image";
|
||||
|
||||
export function UploadPhotoButton(p: {
|
||||
label: string;
|
||||
onPhotoSelected: (b: Blob) => Promise<void>;
|
||||
}): React.ReactElement {
|
||||
const [processing, setProcessing] = React.useState(false);
|
||||
const [imageBlob, setImageBlob] = React.useState<Blob>();
|
||||
const [imageURL, setImageURL] = React.useState<string>();
|
||||
const alert = useAlert();
|
||||
|
||||
const uploadPhoto = async () => {
|
||||
try {
|
||||
// Create file element
|
||||
const fileEl = document.createElement("input");
|
||||
fileEl.type = "file";
|
||||
fileEl.accept =
|
||||
ServerApi.Config.constraints.photo_allowed_types.join(",");
|
||||
fileEl.click();
|
||||
|
||||
// Wait for a file to be chosen
|
||||
await new Promise((res, _rej) =>
|
||||
fileEl.addEventListener("change", () => res(null))
|
||||
);
|
||||
|
||||
if ((fileEl.files?.length ?? 0) === 0) return null;
|
||||
const file = fileEl.files![0];
|
||||
|
||||
// Check file size
|
||||
if (file.size > ServerApi.Config.constraints.photo_max_size) {
|
||||
await alert(
|
||||
`Le fichier sélectionné est trop lourd ! (taille maximale acceptée : ${filesize(
|
||||
ServerApi.Config.constraints.photo_max_size
|
||||
)})`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const tempURL = URL.createObjectURL(fileEl.files![0]);
|
||||
|
||||
setImageBlob(file);
|
||||
setImageURL(tempURL);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert("Failed to upload custom account image!");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const cancelCrop = () => {
|
||||
setImageURL(undefined);
|
||||
};
|
||||
|
||||
const submitCrop = async (a: Area | undefined) => {
|
||||
setProcessing(true);
|
||||
try {
|
||||
let blob = imageBlob!;
|
||||
|
||||
if (a) {
|
||||
blob = await getCroppedImg(imageURL!, a!);
|
||||
}
|
||||
|
||||
await p.onPhotoSelected(blob);
|
||||
|
||||
setImageBlob(undefined);
|
||||
setImageURL(undefined);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert("Echec du traitement de la photo !");
|
||||
}
|
||||
|
||||
setProcessing(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Upload button */}
|
||||
<Button onClick={uploadPhoto}>{p.label}</Button>
|
||||
|
||||
{/* Crop image dialog */}
|
||||
{imageURL && (
|
||||
<ImageCropperDialog
|
||||
processing={processing}
|
||||
src={imageURL!}
|
||||
onCancel={cancelCrop}
|
||||
onSubmit={submitCrop}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user