import useTranslation from "next-translate/useTranslation"; import dynamic from "next/dynamic"; import Link from "next/link"; import router from "next/router"; import React, { useMemo, useState, useRef } from "react"; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; import Dropzone from "react-dropzone"; import "react-quill-new/dist/quill.snow.css"; import { Field, change } from "redux-form"; import { uploadSingleFile, deleteBlob, deleteRepBlob, getFilesFromBlobHashed, getFilesFromBlobproxy, } from "../../../actions"; const LoadingMessage = () =>
Loading the editor...
; // Dynamically import ReactQuill with a proper loading state const ReactQuill = dynamic( () => import("react-quill-new").then((mod) => mod.default), { ssr: false, loading: () => , // This is valid as long as it's a valid React component } ); import { useDispatch } from "react-redux"; // Import the useDispatch hook import { addDays, addMonths, addYears, parseISO, subDays, subMonths, subYears, } from "date-fns"; import { bytesToSize, getThumbnailIconByExtension, updateLinks, } from "../../utils"; import { useRouter } from "next/router"; export const RenderRadioList = ({ datafieldname, name, label, id, errorMsg, options, input: { onChange, value }, meta: { touched, error }, ...custom }) => { const required = (value) => (value ? undefined : "Required"); return ( <>
{touched && error && ( Error: {" "} {errorMsg} )}
{Object.keys(options).map((key, index) => (
))}
); }; export const RenderRadioListWithText = ({ datafieldname, name, label, id, errorMsg, options, input: { onChange, value }, meta: { touched, error }, ...custom }) => { const required = (value) => (value ? undefined : "Required"); const router = useRouter(); return ( <>
{touched && error && ( Error: {" "} {errorMsg} )}
{Object.keys(options).map((key, index) => (
{value === options[key] && (
)}
))}
); }; export const RenderCondtionalRadioList = ({ datafieldname, legend, name, label, id, errorMsg, options, input: { onChange, value }, meta: { touched, error }, ...custom }) => { const required = (value) => (value ? undefined : "Required"); let { t } = useTranslation(); return ( <>
{touched && error && ( Error: {" "} {errorMsg} )}
{custom.hint}
{Object.keys(options).map((key, index) => (
{value == "Yes" && options[key] == "Yes" && (
)}
))}
); }; export const RenderLPACondtionalRadioList = ({ datafieldname, legend, name, label, id, errorMsg, options, input: { onChange, value }, meta: { touched, error }, ...custom }) => { const required = (value) => (value ? undefined : "Required"); let { t } = useTranslation(); return ( <>
{touched && error && ( Error: {" "} {errorMsg} )} {typeof custom.hint != undefined && (
{custom.hint}
)}
{Object.keys(options).map((key, index) => (
{value == custom.optionSelect && options[key] == custom.optionSelect && (
)}
))}
); }; export const RenderPickList = ({ datafieldname, name, label, input, optionsArr, meta: { touched, error }, errorMsg, ...custom }) => { // console.log(custom.disabled); let { t } = useTranslation(); return ( <>
{touched && error && ( Error:{" "} {errorMsg} )}
); }; export const RenderTextfield = ({ id, rows, datafieldname, name, label, input, errorMsg, type, className, meta: { touched, error }, ...custom }) => { const required = (value) => (value ? undefined : "Required"); return ( <>
{touched && error && ( Error:{" "} {errorMsg} )}
); }; export const RenderDatePicker = ({ datafieldname, name, label, id, errorMsg, input: { onChange, value }, meta: { touched, error }, ...custom }) => { const router = useRouter(); var startDateArr = custom.dateStart != "0" ? custom.dateStart.split("") : custom.dateStart; var endDateArr = custom.dateEnd != "0" ? custom.dateEnd.split("") : custom.dateEnd; var minDate = startDateArr == 0 ? new Date() : startDateArr[0] == "-" ? startDateArr[2] == "y" ? subYears(new Date(), startDateArr[1]) : startDateArr[2] == "m" ? subMonths(new Date(), startDateArr[1]) : subDays(new Date(), startDateArr[1]) : startDateArr[2] == "y" ? addYears(new Date(), startDateArr[1]) : startDateArr[2] == "m" ? addMonths(new Date(), startDateArr[1]) : addDays(new Date(), startDateArr[1]); var maxDate = endDateArr == 0 ? new Date() : startDateArr[0] == "-" ? startDateArr[2] == "y" ? subYears(new Date(), startDateArr[1]) : startDateArr[2] == "m" ? subMonths(new Date(), startDateArr[1]) : subDays(new Date(), startDateArr[1]) : startDateArr[2] == "y" ? addYears(new Date(), startDateArr[1]) : startDateArr[2] == "m" ? addMonths(new Date(), startDateArr[1]) : addDays(new Date(), startDateArr[1]); return ( <>
{touched && error && ( Error: {" "} {errorMsg} )}
); }; export const RenderMultiline = ({ id, className, rows, datafieldname, name, label, input, meta: { touched, error }, ...custom }) => { const [editValue, setEditValue] = useState( input.value != null ? input.value : "" ); const changeEdit = (valStr) => { setEditValue(valStr); input.onChange(valStr); }; var modules = { toolbar: [ [{ "header": [1, 2, false] }], ["bold", "italic", "underline", "blockquote"], [{ "list": "ordered" }, { "list": "bullet" }], ["clean"], ], }; return ( <>
{"hint" in custom} {"hint" in custom && (
{custom.hint}
)}
); }; export const RenderRichMultiline = ({ id, className, rows, datafieldname, name, label, input, meta: { touched, error }, ...custom }) => { const [editValue, setEditValue] = useState( input.value != null ? input.value : "" ); const changeEdit = (valStr) => { valStr = updateLinks(valStr); setEditValue(valStr); input.onChange(valStr); }; var modules = { toolbar: [ [{ "header": [1, 2, false] }], ["bold", "italic", "underline", "blockquote"], [{ "list": "ordered" }, { "list": "bullet" }], ["clean"], ], }; return ( <> ); }; export function MultiLinefield(props) { const { name, label } = props; return (
Do not include personal or financial information, like your National Insurance number or credit card details.
); } 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) => { const files = field.input.value; const dispatch = useDispatch(); // Get dispatch using useDispatch hook 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.name} ({file.size / 1024}kb)
)); const getThumbnailIcon = (fileObj, fileType) => { switch (fileType) { case "text/html": return "/assets/images/documenttypes/html.png"; break; case "text/plain": return "/assets/images/documenttypes/txt.png"; break; case "application/msword": return "/assets/images/documenttypes/doc.png"; break; case "application/pdf": return "/assets/images/documenttypes/pdf.png"; break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": return "/assets/images/documenttypes/docx.png"; break; case "text/csv": return "/assets/images/documenttypes/csv.png"; break; case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": return "/assets/images/documenttypes/xlsx.png"; break; case "application/zip": return "/assets/images/documenttypes/zip.png"; break; case "image/jpeg": case "image/png": return URL.createObjectURL(fileObj); break; default: return "/assets/images/documenttypes/default.png"; break; } }; const filelistObj = field.fileList || {}; let blobList = filelistObj; //let blobList = field.props.currentView.fileList; function removeNullObjects(arr) { if (arr.length === 0) { return arr; } return arr.filter((obj) => obj !== null); } function removeObjectsWithUndefinedKey(arr, key) { if (arr.length === 0) { return arr; } return arr.filter((obj) => obj[key] !== undefined); } function removeEmptyObjects(arr) { if (arr.length === 0) { return arr; } return arr.filter( (obj) => obj && typeof obj === "object" && Object.keys(obj).length > 0 ); } //blobList = removeEmptyObjects(blobList); //blobList = removeObjectsWithUndefinedKey(blobList, "name"); //blobList = removeNullObjects(blobList); let buildAppealFilesArray = []; let filesUploadObj = field.input.value; for (let key in filesUploadObj) { typeof filesUploadObj[key].name != "undefined" && buildAppealFilesArray.push({ "name": filesUploadObj[key].name, "size": filesUploadObj[key].size, }); } //buildAppealFilesArray = buildAppealFilesArray.concat(blobList); function removeDuplicates(arr) { const seen = new Set(); return arr.filter((obj) => { const serializedObj = JSON.stringify(obj); if (seen.has(serializedObj)) { return false; // Skip this object (duplicate) } seen.add(serializedObj); // Add the serialized object to the "seen" set return true; // Keep this object }); } buildAppealFilesArray = removeDuplicates(buildAppealFilesArray); //blobList = buildAppealFilesArray; const deleteThisBlob = async ( containerName, blobName, deleteblobhash, getblobshash, casefolderID, filenamePrefix ) => { deleteRepBlob( containerName, blobName, deleteblobhash, casefolderID, filenamePrefix ) .then((data) => data) .then(() => { getFilesFromBlobHashed( containerName, getblobshash, casefolderID + "/" + filenamePrefix ).then((newfilelist) => field.setFilesForRepresentations(newfilelist.value[0]) ); }); }; const [rejectedFiles, setRejectedFiles] = useState([]); // Store rejected files const [completedUploadFiles, setCompletedUploadFiles] = useState(false); const [uploadCountMessage, setUploadCountMessage] = useState(""); const handleDropRejected = (fileRejections) => { const errors = fileRejections .map(({ file, errors }) => { return errors.map((error) => { if (error.code === "file-too-large") { return `${file.name} ${t( "myrepresentations:fileupload-file-error-filesize-label" )}`; } if (error.code === "file-invalid-type") { return `${file.name} ${t( "myrepresentations:fileupload-file-error-invalid-type-label" )}`; } return `${file.name} ${t( "myrepresentations: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 = () => { setRejectedFiles([]); // Clear any previously rejected file errorsss }; return ( <> { setCompletedUploadFiles(false); const renamedAcceptedFiles = filesToUpload.map( (file) => new File( [file], `${ field.filenamePrefix.hasOwnProperty( "representationForm" ) && field.filenamePrefix.representationForm.hasOwnProperty( "values" ) && field.filenamePrefix.representationForm.values.hasOwnProperty( "repfile_name" ) && field.filenamePrefix.representationForm .values.repfile_name }_-_Attachment_-_${file.name}`, { type: file.type, } ) ); field.input.onChange(renamedAcceptedFiles); setUploadCountMessage(renamedAcceptedFiles.length); uploadSingleFile( renamedAcceptedFiles, field.containerID, field.ticketnumber + "/" + field.filenamePrefix.representationForm.values .repfile_name ).then((data) => { console.log(data); let buildAppealFilesArray = []; let values = field; let filesUploadObj = renamedAcceptedFiles; for (let key in filesUploadObj) { typeof filesUploadObj[key].name != "undefined" && buildAppealFilesArray.push({ "name": filesUploadObj[key].name, "size": filesUploadObj[key].size, }); } //console.log(buildAppealFilesArray); function removeDuplicates(arr, key) { const seen = new Set(); return arr.filter((item) => { const value = item[key]; if (seen.has(value)) { return false; // Duplicate found } else { seen.add(value); // Add value to the set return true; // Keep the item } }); } buildAppealFilesArray = values.hasOwnProperty( "fileList" ) ? buildAppealFilesArray.concat(values.fileList) : buildAppealFilesArray; buildAppealFilesArray = removeDuplicates( buildAppealFilesArray, "name" ); // Object.assign(values, { // "fileList": buildAppealFilesArray, // }); getFilesFromBlobproxy( field.containerID, field.ticketnumber + "/" + (typeof field.filenamePrefix != "object" ? field.filenamePrefix : encodeURIComponent( field.filenamePrefix .representationForm.values .repfile_name )) ).then((data) => { data = data.value || {}; field.input.value = ""; field.setFilesForRepresentations(data[0]); setCompletedUploadFiles(true); dispatch( change("representationForm", field.name, null) ); // Set the field value to null }); }); }} onDropRejected={handleDropRejected} onDropAccepted={handleDropAccepted} > {({ getRootProps, getInputProps }) => ( <>
{" "}
{t( "myrepresentations:fileupload-drop-label" )} (Max 50 MB)
( {t( "myrepresentations:fileupload-file-list-label" )} )
{uploadCountMessage > 0 && completedUploadFiles == false && (
{t("home:uploading-files-label", { number: uploadCountMessage, })}
)} {completedUploadFiles > 0 && uploadCountMessage > 0 && (
{t( "home:completed-uploading-files-label", { number: uploadCountMessage, } )}
)}
)}
{rejectedFiles.length > 0 && (
    {rejectedFiles.map((error, index) => (
  • {error}
  • ))}
)} {field.meta.touched && field.meta.error && ( {field.meta.error} )} {!completedUploadFiles && filesUploadObj && Array.isArray(filesUploadObj) && filesUploadObj.map( (file, i) => typeof file.name != "undefined" && (
{file.name} {file.name} ({bytesToSize(file.size)} )
{completedUploadFiles ? (

Upload complete

) : (

{t( "home:uploading-files-progress-label" )}

)}
) )} {blobList.length > 0 && (

{t("myrepresentations:previously-added-files")}

)} {blobList.map((blob, i) => (
{ setUploadCountMessage(uploadCountMessage - 1); deleteThisBlob( field.containerID, blob.name, blob.hasheddeletepath, blob.hashgetblobs, field.ticketnumber, blob.path.split("/")[1] ); }} title={t("home:remove-this-file-label")} > − {blob.name} {blob.name} ( {bytesToSize(blob.contentLength || blob.size)})
))}{" "} ); }; export function FileUploadField(props) { return ( <>

{props.label}

); } // export const RepresentationGuidanceText = (appealType) => { // let { t } = useTranslation(); // console.log(appealType); // switch (appealType) { // case "846040004": //has/cas // return ( //

// {t("myrepresentations:questionnaire-publish-policy-label")}{" "} // // https://gov.wales/planning-and-environment-decisions-wales-publishing-policy-html // //

// ); // break; // default: // return ( //

// {t("myrepresentations:publish-policy-label")}{" "} // // https://gov.wales/planning-and-environment-decisions-wales-publishing-policy-html // //

// ); // break; // } // return guidanceString; // };