import { JSONPath as jsonpath } from "jsonpath-plus";
import React, { useMemo, useState } from "react";
import useTranslation from "next-translate/useTranslation";
import Link from "next/link";
import Dropzone from "react-dropzone";
import {
deleteBlob,
getFilesFromBlobHashed,
uploadSingleFile,
getFilesFromBlobproxy
} from "../../../actions/services/documentService";
import { bytesToSize, getThumbnailIconByExtension } from "../../utils";
import {
getDocumentTypePrefix,
getThumbnailIconByMimeType,
validateUploadFilename
} from "../helpers/fileUploadHelpers";
const baseStyle = {
display: "flex",
flexDirection: "column",
alignItems: "center",
padding: "20px",
borderWidth: 2,
borderRadius: 2,
borderColor: "#eeeeee",
borderStyle: "dashed",
backgroundColor: "#fafafa",
color: "#bdbdbd",
transition: "border .3s ease-in-out"
};
const activeStyle = {
borderColor: "#2196f3"
};
const acceptStyle = {
borderColor: "#00e676"
};
const rejectStyle = {
borderColor: "#ff1744"
};
export const RenderFileUpload = (field) => {
let files = field.input.value;
let { t } = useTranslation();
const style = useMemo(
() => ({
...baseStyle
// ...(isDragActive ? activeStyle : {}),
// ...(isDragAccept ? acceptStyle : {}),
// ...(isDragReject ? rejectStyle : {}),
}),
[]
// [isDragActive, isDragReject, isDragAccept]
);
const [filesList, setFilesList] = useState([]);
const thumbs = filesList.map((file) => (

-{" "}
{file.name} ({file.size / 1024}kb)
));
const filelistObj = field.fileList || {};
const blobList = jsonpath({
path: "$..[?(@ && @.documentType=='" + field.documentTypeCode + "')]",
json: filelistObj,
eval: true
});
//const blobList = filelistObj;
const deleteThisBlob = async (
containerName,
blobName,
deleteblobhash,
getblobshash,
casefolderID
) => {
//console.log(containerName, blobName, deleteblobhash);
deleteBlob(containerName, blobName, deleteblobhash, casefolderID)
.then((data) => data)
.then(() => {
getFilesFromBlobHashed(
containerName,
getblobshash,
casefolderID
).then((newfilelist) => field.setFilesForAppeal(newfilelist));
});
};
const removeFile = (file) => {
const newFilesArr = files.filter((user) => user.name != file.name);
files == newFilesArr;
field.input.onChange(newFilesArr);
};
function removeEmptyObjects(arr) {
return arr.filter((obj) => Object.keys(obj).length > 0);
}
const [errorMessage, setErrorMessage] = useState(null);
const [rejectedFiles, setRejectedFiles] = useState([]); // Store rejected files
const [completedUploadFiles, setCompletedUploadFiles] = useState(false);
const [uploadCountMessage, setUploadCountMessage] = useState("");
const [totalUploadFiles, setTotalUploadFiles] = useState(0);
const handleDropRejected = (fileRejections) => {
const errors = fileRejections
.map(({ file, errors }) => {
return errors.map((error) => {
if (error.code === "file-too-large") {
return `${file.name} ${t(
"newappeal:new-appeal-fileupload-file-error-filesize-label"
)}`;
}
if (error.code === "file-invalid-type") {
return `${file.name} ${t(
"newappeal:new-appeal-fileupload-file-error-invalid-type-label"
)}`;
}
if (error.code === "filename-invalid-chars") {
return (
error.message ||
`${file.name} ${t(
"newappeal:new-appeal-fileupload-file-error-invalid-filename-label"
)}`
);
}
return `${file.name} ${t(
"newappeal:new-appeal-fileupload-file-error-invalid-label"
)}`;
});
})
.flat(); // Flatten the errors array
setRejectedFiles(errors); // Store the error messages for rejected files
};
// Handle accepted files (clear error message when files are accepted)
const handleDropAccepted = () => {
setErrorMessage(null); // Clear any previous error messages when files are accepted
setRejectedFiles([]); // Clear any previously rejected file errorsss
};
return (
<>
validateUploadFilename(file, t)}
onDrop={(acceptedFiles, fileRejections, e) => {
// build + display rejected messages (ALWAYS, even if some accepted)
if (fileRejections?.length) {
handleDropRejected(fileRejections);
} else {
// only clear rejections when nothing was rejected on this drop
setRejectedFiles([]);
setErrorMessage(null);
}
// if nothing accepted, stop (prevents showing only "uploading" when all invalid)
if (!acceptedFiles || acceptedFiles.length === 0) {
setCompletedUploadFiles(true); // optional: depends on your UX
setUploadCountMessage(0);
setTotalUploadFiles(0);
return;
}
// continue with your existing upload logic for accepted files
setCompletedUploadFiles(false);
const renamedAcceptedFiles = acceptedFiles.map(
(file) =>
new File(
[file],
`${getDocumentTypePrefix(field.documentTypeCode)}_-_${
file.name
}`,
{ type: file.type }
)
);
field.input.onChange(renamedAcceptedFiles);
if (typeof field.setFileCount === "function") {
field.setFileCount(
(field.uploadCount || 0) +
renamedAcceptedFiles.length
);
}
setUploadCountMessage(0);
setTotalUploadFiles(renamedAcceptedFiles.length);
uploadSingleFile(
renamedAcceptedFiles,
field.containerID,
field.ticketnumber,
{
onChunkComplete: ({ cumulativeUploaded }) => {
setUploadCountMessage(cumulativeUploaded);
}
}
)
.then((data) => {
let buildAppealFilesArray = [];
let values = field.form.appealForm.values;
let filesUploadObj = renamedAcceptedFiles;
for (let key in filesUploadObj) {
typeof filesUploadObj[key].name !==
"undefined" &&
buildAppealFilesArray.push({
name: filesUploadObj[key].name,
size: filesUploadObj[key].size
});
}
function removeDuplicates(arr, key) {
const seen = new Set();
return arr.filter((item) => {
const value = item[key];
if (seen.has(value)) return false;
seen.add(value);
return true;
});
}
buildAppealFilesArray = values.hasOwnProperty(
"filesList"
)
? buildAppealFilesArray.concat(values.filesList)
: buildAppealFilesArray;
buildAppealFilesArray = removeDuplicates(
buildAppealFilesArray,
"name"
);
Object.assign(values, {
filesList: buildAppealFilesArray
});
// keep your existing server-side invalid handling
if (data.invalidFiles?.length > 0) {
setRejectedFiles((prev) => [
...prev,
...data.invalidFiles
]);
setUploadCountMessage(
renamedAcceptedFiles.length -
data.invalidFiles.length
);
}
return getFilesFromBlobproxy(
field.containerID,
field.ticketnumber
);
})
.then((data) => {
field.setFilesForAppeal(data);
setCompletedUploadFiles(true);
});
}}
>
{({ getRootProps, getInputProps }) => (
<>
>
)}
{rejectedFiles.length > 0 && (
{rejectedFiles.map((error, index) => (
- {error}
))}
)}
{totalUploadFiles > 0 && completedUploadFiles == false && (
{t("home:uploading-files-label", {
number:
totalUploadFiles > 0
? `${uploadCountMessage} of ${totalUploadFiles}`
: uploadCountMessage
})}
)}
{completedUploadFiles > 0 && uploadCountMessage >= 0 && (
{t("home:completed-uploading-files-label", {
number: uploadCountMessage
})}
)}
{field.meta.touched && field.meta.error && (
{field.meta.error}
)}
{files && Array.isArray(files) && (
<>
{/* {(files = removeEmptyObjects(files))} */}
{!completedUploadFiles &&
files.map(
(file, i) =>
typeof file.name != "undefined" && (
{" "}
{/*
removeFile(file)}
>
−
*/}
{file.name} (
{bytesToSize(file.size)})
{completedUploadFiles ? (
Upload complete
) : (
{t(
"home:uploading-files-progress-label"
)}{" "}
)}
)
)}
>
)}
{blobList.length > 0 && (
{t("newappeal:previously-added-files")}
)}
{blobList.map(
(blob, i) =>
blob.documentType == field.documentTypeCode && (
{
setUploadCountMessage(
uploadCountMessage - 1
);
deleteThisBlob(
field.containerID,
blob.name,
blob.hasheddeletepath,
blob.hashgetblobs,
field.ticketnumber
);
}}
title={t("home:remove-this-file-label")}
>
−
{blob.name} ({bytesToSize(blob.contentLength)})
)
)}{" "}
>
);
};