Skip to content

Commit

Permalink
Merge pull request #890 from WildMeOrg/encounter_submission_process
Browse files Browse the repository at this point in the history
Encounter submission process
  • Loading branch information
TanyaStere42 authored Nov 13, 2024
2 parents a50f6ab + f970f5b commit 1d1071a
Show file tree
Hide file tree
Showing 22 changed files with 871 additions and 243 deletions.
5 changes: 2 additions & 3 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"lodash-es": "^4.17.21",
"mobx": "6.13.3",
"mobx-react-lite": "^4.0.7",
"moment": "^2.30.1",
"postcss-cli": "^11.0.0",
"rc-slider": "^10.6.2",
"react": "^18.2.0",
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/locale/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -309,5 +309,9 @@
"LOCATION_ID_REQUIRED_WARNING": "Die Standort-ID ist erforderlich, um Abgleichsgruppen zu erstellen.",
"MISSING_REQUIRED_FIELDS": "Es fehlen erforderliche Felder. Überprüfen Sie das Formular und versuchen Sie es erneut.",
"INVALID_LAT": "Der Breitengrad muss zwischen -90 und 90 liegen",
"INVALID_LONG": "Der Längengrad muss zwischen -180 und 180 liegen"
"INVALID_LONG": "Der Längengrad muss zwischen -180 und 180 liegen",
"BEERROR_REQUIRED" : "Konnte nicht übermittelt werden; erforderliches Feld fehlt: ",
"BEERROR_INVALID" : "Konnte nicht übermittelt werden; Feldformat war ungültig: ",
"BEERROR_UNKNOWN" : "Konnte aufgrund eines unbekannten Fehlers nicht abgeschickt werden.",
"ANON_UPLOAD_IMAGE_WARNING": "Bilder können erst hochgeladen werden, wenn das Captcha abgeschlossen ist."
}
6 changes: 5 additions & 1 deletion frontend/src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@
"LOCATION_ID_REQUIRED_WARNING": "Location ID is required to establish match sets.",
"MISSING_REQUIRED_FIELDS": "Missing required fields. Review the form and try again.",
"INVALID_LAT": "Latitude must be between -90 and 90",
"INVALID_LONG": "Longitude must be between -180 and 180"
"INVALID_LONG": "Longitude must be between -180 and 180",
"BEERROR_REQUIRED" : "Could not submit; missing required field: ",
"BEERROR_INVALID" : "Could not submit; field format was invalid: ",
"BEERROR_UNKNOWN" : "Could not submit due to unknown error.",
"ANON_UPLOAD_IMAGE_WARNING": "Images cannot be uploaded until captcha is complete."

}
6 changes: 5 additions & 1 deletion frontend/src/locale/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,9 @@
"LOCATION_ID_REQUIRED_WARNING": "Se requiere el ID de ubicación para establecer conjuntos de coincidencias.",
"MISSING_REQUIRED_FIELDS": "Faltan campos obligatorios. Revise el formulario e inténtelo de nuevo.",
"INVALID_LAT": "La latitud debe estar entre -90 y 90",
"INVALID_LONG": "La longitud debe estar entre -180 y 180"
"INVALID_LONG": "La longitud debe estar entre -180 y 180",
"BEERROR_REQUIRED" : "No se ha podido enviar; falta el campo obligatorio: ",
"BEERROR_INVALID" : "No se pudo enviar; el formato del campo no era válido: ",
"BEERROR_UNKNOWN" : "No se pudo enviar debido a un error desconocido.",
"ANON_UPLOAD_IMAGE_WARNING": "No se pueden subir imágenes hasta que se complete el captcha."
}
6 changes: 5 additions & 1 deletion frontend/src/locale/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,9 @@
"LOCATION_ID_REQUIRED_WARNING": "L'ID de l'emplacement est requis pour établir des ensembles de correspondances.",
"MISSING_REQUIRED_FIELDS": "Champs obligatoires manquants. Vérifiez le formulaire et réessayez.",
"INVALID_LAT": "La latitude doit être comprise entre -90 et 90",
"INVALID_LONG": "La longitude doit être comprise entre -180 et 180"
"INVALID_LONG": "La longitude doit être comprise entre -180 et 180",
"BEERROR_REQUIRED" : "Impossible de soumettre ; champ requis manquant : ",
"BEERROR_INVALID" : "Impossible de soumettre ; le format du champ n'est pas valide : ",
"BEERROR_UNKNOWN" : "Impossible de soumettre en raison d'une erreur inconnue.",
"ANON_UPLOAD_IMAGE_WARNING": "Les images ne peuvent pas être téléchargées tant que le captcha n'est pas complété."
}
6 changes: 5 additions & 1 deletion frontend/src/locale/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,9 @@
"LOCATION_ID_REQUIRED_WARNING": "L'ID della posizione è necessario per stabilire set di corrispondenze.",
"MISSING_REQUIRED_FIELDS": "Mancano i campi obbligatori. Rivedere il modulo e riprovare.",
"INVALID_LAT": "La latitudine deve essere compresa tra -90 e 90",
"INVALID_LONG": "La longitudine deve essere compresa tra -180 e 180"
"INVALID_LONG": "La longitudine deve essere compresa tra -180 e 180",
"BEERROR_REQUIRED" : "Impossibile inviare; manca un campo obbligatorio: ",
"BEERROR_INVALID" : "Impossibile inviare; il formato del campo non era valido: ",
"BEERROR_UNKNOWN" : "Impossibile inviare a causa di un errore sconosciuto.",
"ANON_UPLOAD_IMAGE_WARNING": "Non è possibile caricare immagini finché il captcha non è completato."
}
175 changes: 106 additions & 69 deletions frontend/src/pages/ReportsAndManagamentPages/ImageSection.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect, useRef, useContext } from "react";
import { ProgressBar, Image, Row, Col } from "react-bootstrap";
import { ProgressBar, Image as BootstrapImage, Row, Col } from "react-bootstrap";
import Flow from "@flowjs/flow.js";
import { FormattedMessage } from "react-intl";
import ThemeContext from "../../ThemeColorProvider";
Expand Down Expand Up @@ -43,10 +43,10 @@ export const FileUploader = observer(({ store }) => {
}, [previewData]);

useEffect(() => {
if (!flow && fileInputRef.current) {
if (!flow && fileInputRef.current && store.isHumanLocal) {
initializeFlow();
}
}, [flow, fileInputRef]);
}, [flow, fileInputRef, store.isHumanLocal]);

useEffect(() => {
const savedFiles = JSON.parse(localStorage.getItem("uploadedFiles"));
Expand Down Expand Up @@ -75,20 +75,19 @@ export const FileUploader = observer(({ store }) => {
setFlow(flowInstance);

flowInstance.on("fileAdded", (file) => {
if (!store.isHumanLocal) return;
const supportedTypes = [
"image/jpeg",
"image/jpg",
"image/png",
"image/bmp",
];
if (!supportedTypes.includes(file.file.type)) {
console.error("Unsupported file type:", file.file.type);
flowInstance.removeFile(file);
return false;
}

if (file.size > maxSize * 1024 * 1024) {
console.warn("File size exceeds limit:", file.name);
return false;
}

Expand All @@ -98,19 +97,53 @@ export const FileUploader = observer(({ store }) => {
file,
]);

const reader = new FileReader();
reader.onloadend = () => {
setPreviewData((prevPreviewData) => [
...prevPreviewData.filter((p) => p.fileName !== file.name),
{
src: reader.result,
fileName: file.name,
fileSize: file.size,
progress: 0,
},
]);
const createThumbnail = (file) => {
const reader = new FileReader();
reader.onload = () => {
const img = new Image();
img.src = reader.result;

img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");

const MAX_WIDTH = 150;
const MAX_HEIGHT = 150;
let width = img.width;
let height = img.height;

if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}

canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
const thumbnail = canvas.toDataURL("image/jpeg", 0.7);
setPreviewData((prevPreviewData) => [
...prevPreviewData.filter((p) => p.fileName !== file.name),
{
src: thumbnail,
fileName: file.name,
fileSize: file.size,
progress: 0,
},
]);
};
};
reader.readAsDataURL(file.file);
};

createThumbnail(file);

EXIF.getData(file.file, function () {
const exifData = EXIF.getAllTags(this);
const dateTime = exifData.DateTime;
Expand All @@ -123,13 +156,9 @@ export const FileUploader = observer(({ store }) => {
if (f.length == 3) datetime1 = f.join('-');
if ((f.length == 5) || (f.length == 6)) datetime1 = f.slice(0, 3).join('-') + ' ' + f.slice(3, 6).join(':');
store.setExifDateTime(datetime1);
// geo: latitude && longitude ? { latitude, longitude } : null,

} else {
console.warn("EXIF data not available for:", file.name);
}
// geo: latitude && longitude ? { latitude, longitude } : null,
}
});
reader.readAsDataURL(file.file);
});

flowInstance.on("fileProgress", (file) => {
Expand All @@ -155,7 +184,7 @@ export const FileUploader = observer(({ store }) => {
);
});

flowInstance.on("fileError", (file, message) => {
flowInstance.on("fileError", (file) => {
setUploading(false);
setPreviewData((prevPreviewData) =>
prevPreviewData.map((preview) =>
Expand All @@ -164,7 +193,6 @@ export const FileUploader = observer(({ store }) => {
: preview,
),
);
console.error("Upload error:", message);
});
setupDragAndDropListeners(flowInstance);
};
Expand Down Expand Up @@ -252,7 +280,6 @@ export const FileUploader = observer(({ store }) => {
: preview,
),
);
console.error(`File upload timed out: ${file.name}`);
}, 300000);

flow.on("fileSuccess", (uploadedFile) => {
Expand Down Expand Up @@ -282,6 +309,15 @@ export const FileUploader = observer(({ store }) => {
<FormattedMessage id="SUPPORTED_FILETYPES" />
{`${" "}${maxSize} MB`}
</p>
{!store.isHumanLocal && <Alert
variant="danger"
className="w-100 mt-1 mb-1 ms-2 me-4"
style={{
border: "none",
}}
>
<FormattedMessage id="ANON_UPLOAD_IMAGE_WARNING" />
</Alert>}
</Row>
<Row>
{store.imageSectionError && (
Expand All @@ -301,49 +337,50 @@ export const FileUploader = observer(({ store }) => {
href={`${process.env.PUBLIC_URL}/login?redirect=%2Freport`}
onClick={() => {
localStorage.setItem("species", store.speciesSection.value);
localStorage.setItem(
"followUpSection.submitter.name",
store.followUpSection.submitter.name,
);
localStorage.setItem(
"followUpSection.submitter.email",
store.followUpSection.submitter.email,
);
localStorage.setItem(
"followUpSection.photographer.name",
store.followUpSection.photographer.name,
);
localStorage.setItem(
"followUpSection.photographer.email",
store.followUpSection.photographer.email,
);
localStorage.setItem(
"followUpSection.additionalEmails",
store.followUpSection.additionalEmails,
);
localStorage.setItem(
"additionalCommentsSection",
store.additionalCommentsSection.value,
);
localStorage.setItem(
"uploadedFiles",
JSON.stringify(store.imagePreview),
);
// localStorage.setItem("dateTimeSection", store.dateTimeSection.value);
// localStorage.setItem("placeSection", store.placeSection.value);
localStorage.setItem(
"submissionId",
store.imageSectionSubmissionId,
);
localStorage.setItem(
"fileNames",
JSON.stringify(store.imageSectionFileNames),
);
localStorage.setItem(
"datetime",
store.dateTimeSection.value?.toISOString(),
);
localStorage.setItem("exifDateTime", store.exifDateTime);
localStorage.setItem(
"followUpSection.submitter.name",
store.followUpSection.submitter.name,
);
localStorage.setItem(
"followUpSection.submitter.email",
store.followUpSection.submitter.email,
);
localStorage.setItem(
"followUpSection.photographer.name",
store.followUpSection.photographer.name,
);
localStorage.setItem(
"followUpSection.photographer.email",
store.followUpSection.photographer.email,
);
localStorage.setItem(
"followUpSection.additionalEmails",
store.followUpSection.additionalEmails,
);
localStorage.setItem(
"additionalCommentsSection",
store.additionalCommentsSection.value,
);
localStorage.setItem(
"uploadedFiles",
JSON.stringify(store.imagePreview),
);
localStorage.setItem(
"submissionId",
store.imageSectionSubmissionId,
);
localStorage.setItem(
"fileNames",
JSON.stringify(store.imageSectionFileNames),
);
localStorage.setItem(
"datetime",
store.dateTimeSection.value?.toISOString(),
);
localStorage.setItem("exifDateTime", store.exifDateTime);
localStorage.setItem("locationID", store.placeSection.locationId);
localStorage.setItem("lat", store.lat);
localStorage.setItem("lon", store.lon);
}}
>
<FormattedMessage id="LOGIN_SIGN_IN" />
Expand Down Expand Up @@ -390,7 +427,7 @@ export const FileUploader = observer(({ store }) => {
);
}}
></i>
<Image
<BootstrapImage
id="thumb"
src={preview.src}
style={{ width: "100%", height: "120px", objectFit: "fill" }}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/pages/ReportsAndManagamentPages/LocationID.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export const LocationID = observer(
treeCheckStrictly
treeNodeFilterProp="title"
onChange={(selectedValues) => {
store.setLocationError(selectedValues ? false : true);
const singleSelection =
selectedValues.length > 0
? selectedValues[selectedValues.length - 1]
Expand Down Expand Up @@ -221,7 +222,7 @@ export const LocationID = observer(
color: theme.statusColors.red600,
}}
></i>
<FormattedMessage id="EMPTY_REQUIRED_WARNING" />
<FormattedMessage id="LOCATION_ID_REQUIRED_WARNING" />
</Alert>
)}
</Form.Group>
Expand Down
Loading

0 comments on commit 1d1071a

Please sign in to comment.