import axios from "axios"; import _ from "lodash"; import useTranslation from "next-translate/useTranslation"; import { useRouter } from "next/router"; import React, { useEffect } from "react"; import "react-datepicker/dist/react-datepicker.css"; import { Field } from "redux-form"; import fieldLookup from "../../data/crmfieldlookuptranslations.json"; import pickListLookup from "../../data/picklistLookups.json"; import { setFileCount } from "../../store/appealType/action"; import "react-quill-new/dist/quill.snow.css"; import { useStore as store, useSelector } from "react-redux"; import { validateField } from "./validationUtils"; // Import the validation function import { getFieldTranslation } from "./helpers/translationHelpers"; import { RenderRichMultiline } from "./fields/renderRichMultiline"; import { RenderTextfield } from "./fields/renderTextfield"; import { RenderMultiline } from "./fields/renderMultiline"; import { RenderDatePicker } from "./fields/renderDatePicker"; import { RenderYesNo } from "./fields/renderYesNo"; import { RenderRadio } from "./fields/renderRadio"; import { RenderCheckBox } from "./fields/renderCheckBox"; import { RenderPickList } from "./fields/renderPickList"; import { RenderDecimalField } from "./fields/renderDecimalField"; import { RenderFileUpload } from "./fields/renderFileUpload"; export { RenderSubFields } from "./fields/renderSubFields"; export { FieldArrayForm } from "./fields/fieldArrayForm"; const getValidationMessages = (t) => ({ requiredMessage: t("newappeal:is-required-label"), emojiNotAllowedMessage: t("newappeal:emojis-not-allowed-label"), invalidPostcodeMessage: t("newappeal:invalid-postcode-label") }); const hasParentFieldValue = ({ parentField, form, formProps }) => parentField != false && !_.isEmpty(formProps[form]) && _.has(formProps[form].values, parentField); const isVisibleByEquality = ({ parentField, form, formProps, parentFieldShowOnValue }) => (hasParentFieldValue({ parentField, form, formProps }) && formProps[form].values[parentField]) == parentFieldShowOnValue; const isVisibleByInclusion = ({ parentField, form, formProps, parentFieldShowOnValue }) => hasParentFieldValue({ parentField, form, formProps }) && parentFieldShowOnValue.indexOf( formProps[form].values[parentField].toString() ) > -1; export function Textfield(props) { const { name, label, validation, ticketnumber, form, formProps, parentField, parentFieldShowOnValue, maxFieldLength, hint } = props; const required = (value) => { let errors; // Check for the required field if (!value) { errors = t("newappeal:is-required-label"); } else { // Check for emojis using a regular expression const emojiRegex = /[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{2300}-\u{23FF}\u{2B50}\u{1F004}-\u{1F0CF}\u{1F0A0}-\u{1F0A5}\u{1F170}-\u{1F251}]/gu; if (emojiRegex.test(value)) { errors = "Emojis are not allowed"; } } return errors; }; const postcode = (value) => value && !/^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$/i.test( value ) ? t("newappeal:invalid-postcode-label") : undefined; let { t } = useTranslation(); if (name == "pinswg_name") { return ( <>

{t("newappeal:new-appeal-introduction-paragraph")}

{t("newappeal:new-appeal-introduction-paragraph-two")}

{t( "newappeal:new-appeal-introduction-warning-paragraph" )}

); } else { var showIfHasParentShowValue = isVisibleByEquality({ parentField, form, formProps, parentFieldShowOnValue }); // console.log(parentField, showIfHasParentShowValue); // console.log(parentField, formProps, form); //console.log("validation props:", validation); const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } = getValidationMessages(t); return (
{parentField != false ? ( showIfHasParentShowValue && ( validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function label={props.label} maxFieldLength={props.maxFieldLength} /> ) ) : ( validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function label={props.label} errorMsg={t("newappeal:is-required-label")} maxFieldLength={props.maxFieldLength} /> )}
); } } export function MultiLinefield(props) { const { name, label, form, formProps, parentField, parentFieldShowOnValue, validation, maxFieldLength, hint } = props; const required = (value) => { let errors; // Check for the required field if (!value) { errors = t("newappeal:is-required-label"); } else { // Check for emojis using a regular expression const emojiRegex = /[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{2300}-\u{23FF}\u{2B50}\u{1F004}-\u{1F0CF}\u{1F0A0}-\u{1F0A5}\u{1F170}-\u{1F251}]/gu; if (emojiRegex.test(value)) { errors = t("newappeal:emojis-not-allowed-label"); } } return errors; }; var showIfHasParentShowValue = isVisibleByInclusion({ parentField, form, formProps, parentFieldShowOnValue }); (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; //console.log(showIfHasParentShowValue, formProps[form].values[parentField]); let { t } = useTranslation(); const translatedLabel = FieldsTranslations(props.label); const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } = getValidationMessages(t); return ( <> {parentField != false ? ( showIfHasParentShowValue && (
{props.hasOwnProperty("hint") && props.hint != false && t(props.hint)}{" "}
{t("newappeal:new-appeal-multiline-pid")}
validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function maxFieldLength={props.maxFieldLength} />
) ) : (
{props.hasOwnProperty("hint") && props.hint != false && t(props.hint)}{" "}
{t("newappeal:new-appeal-multiline-pid")}
validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function maxFieldLength={props.maxFieldLength} />
)} ); } export function RichMultiLinefield(props) { const { name, label, form, formProps, parentField, parentFieldShowOnValue, validation, maxFieldLength } = props; const required = (value) => value ? undefined : t("newappeal:is-required-label"); var showIfHasParentShowValue = isVisibleByInclusion({ parentField, form, formProps, parentFieldShowOnValue }); (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; //console.log(showIfHasParentShowValue, formProps[form].values[parentField]); let { t } = useTranslation(); const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } = getValidationMessages(t); return ( <> {parentField != false ? ( showIfHasParentShowValue && (
{props.hasOwnProperty("hint") && props.hint != false && t(props.hint)}{" "}
{t("newappeal:new-appeal-multiline-pid")}
validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function maxFieldLength={props.maxFieldLength} />
) ) : (
{props.hasOwnProperty("hint") && props.hint != false && t(props.hint)}{" "}
{t("newappeal:new-appeal-multiline-pid")}
validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function maxFieldLength={props.maxFieldLength} />
)} ); } export function DateFieldPicker(props) { const { name, label, parentField, form, formProps, parentFieldShowOnValue, validation } = props; let dateStart = props.dateStart; let dateEnd = props.dateEnd; let { t } = useTranslation(); const required = (value) => (value ? undefined : "Required"); var showIfHasParentShowValue = isVisibleByEquality({ parentField, form, formProps, parentFieldShowOnValue }); const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } = getValidationMessages(t); // a and b are javascript Date objects function dateDiffInDays(a, b) { const _MS_PER_DAY = 1000 * 60 * 60 * 24; // Discard the time and time-zone information. const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()); const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()); return Math.floor((utc2 - utc1) / _MS_PER_DAY); } dateStart = showIfHasParentShowValue && name == "pinswg_dateoflpadecision" ? "-" + (dateDiffInDays( new Date(formProps[form].values["pinswg_dateofapplication"]), new Date() ) - 1) + "d" : dateStart; return (
{parentField != false ? ( showIfHasParentShowValue && ( validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function errorMsg={t("newappeal:select-a-date-label")} dateStart={dateStart} dateEnd={dateEnd} hint={props.hint} /> ) ) : ( validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function errorMsg={t("newappeal:select-a-date-label")} dateStart={dateStart} dateEnd={dateEnd} hint={props.hint} /> )}
); } export function DateField(props) { const { name, label } = props; return (
); } export function YesNofield(props) { const router = useRouter(); let { t } = useTranslation(); const { name, label, inline, form, formProps, validation, parentFieldShowOnValue, parentField } = props; const yesNo = router.locale == "cy" ? ["Ydw", "Na"] : ["Yes", "No"]; const required = (value) => (value ? undefined : "Required"); var showIfHasParentShowValue = isVisibleByInclusion({ parentField, form, formProps, parentFieldShowOnValue }); (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; return ( <> {parentField != false ? ( showIfHasParentShowValue && ( ) ) : ( )} ); } export function Radiofield(props) { const { name, label, datafieldname, form, formProps, parentFieldShowOnValue, parentField, validation } = props; const router = useRouter(); const required = (value) => (value ? undefined : "Required"); // console.log(props.options); let { t } = useTranslation(); const fieldOptions = props.options .slice(1, props.options.length - 1) .split(","); //parentFieldShowOnValue var showIfHasParentShowValue = isVisibleByInclusion({ parentField, form, formProps, parentFieldShowOnValue }); (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } = getValidationMessages(t); return ( <> {parentField != false ? ( showIfHasParentShowValue && ( validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function requiredDocumentLabel={props.requiredDocumentLabel} requiredDocumentValue={props.requiredDocumentValue} setDocumentsList={props.setDocumentsList} documentList={props.documentList} /> ) ) : ( validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function requiredDocumentLabel={props.requiredDocumentLabel} requiredDocumentValue={props.requiredDocumentValue} setDocumentsList={props.setDocumentsList} documentList={props.documentList} /> )} ); } export function CheckBoxfield(props) { const router = useRouter(); console.log(props); const required = (value) => (value ? undefined : "Required"); const fieldOptions = router.locale == "cy" ? ["Ydw", "Na", "2323"] : ["Yes", "No", "23232"]; return ( ); } export function PickList(props) { const { name, label, datafieldname, hint } = props; let { t } = useTranslation(); const required = (value) => { return value || value == 0 ? undefined : t("newappeal:is-required-label"); }; return ( ); } export function NumericField(props) { const { name, label, validation, form, formProps, parentFieldShowOnValue, parentField, maxFieldLength } = props; let { t } = useTranslation(); const required = (value) => { return value || value == 0 ? undefined : t("newappeal:is-required-label"); }; const isNumber = (value) => { const regex = /^\d+$/; return regex.test(value) ? undefined : t("newappeal:invalid-number-label"); }; const maxLength = (max) => (value) => value && value.length > max ? `Must be ${max} characters or less` : undefined; //parentFieldShowOnValue var showIfHasParentShowValue = isVisibleByInclusion({ parentField, form, formProps, parentFieldShowOnValue }); (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; //console.log("parentField:", parentField, showIfHasParentShowValue); const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } = getValidationMessages(t); return ( <> {parentField != false ? ( showIfHasParentShowValue && (
validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function component={RenderTextfield} label={label} maxFieldLength={props.maxFieldLength} />
) ) : (
parseInt(value)} // maxFieldLength={props.maxFieldLength} name={props.name} id={props.name} type="text" className="govuk-input govuk-input--width-10" aria-describedby={name} //pattern="^\d*\.?\d+$" pattern="[0-9]*" validate={[ required, isNumber, maxLength(props.maxFieldLength) ]} component={RenderTextfield} label={props.label} maxFieldLength={props.maxFieldLength} />
)} ); } export function DecimalField(props) { const { name, label, validation, form, formProps, parentFieldShowOnValue, parentField, maxFieldLength } = props; let { t } = useTranslation(); const required = (value) => value ? undefined : t("newappeal:is-required-label"); const isNumber = (value) => { const regex = /^\d*\.?\d{0,1}$/; return regex.test(value) ? undefined : t("newappeal:invalid-number-label"); }; const maxLength = (max) => (value) => value && value.length > max ? `Must be ${max} characters or less` : undefined; //parentFieldShowOnValue var showIfHasParentShowValue = isVisibleByInclusion({ parentField, form, formProps, parentFieldShowOnValue }); (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; //console.log("parentField:", parentField, showIfHasParentShowValue); const normalizeDecimal = (value) => { return value ? parseFloat(value) : value; }; const validateDecimal = (value) => { if (!value) return t("newappeal:is-required-label"); // Regex to match whole numbers or decimal numbers (up to 7 characters including decimal) const regex = /^\d{1,6}(\.\d{1,2})?$/; // Up to 6 digits before the decimal, 2 after // Check if the value matches the regex pattern if (!regex.test(value)) { return t("newappeal:invalid-decimal-label"); } return undefined; }; const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } = getValidationMessages(t); return ( <> {parentField != false ? ( showIfHasParentShowValue && (
validateField( value, validation, requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage ) } // Use the external validate function component={RenderTextfield} label={props.label} maxFieldLength={props.maxFieldLength} />
) ) : (
)} ); } const RenderCaseID = {}; export function ReadOnlyfield(props) { const { name, label, value } = props; //console.log(props.value.refno); return ( <>
); } export const FieldsTranslations = (label) => { const router = useRouter(); const { locale } = router; const { appealtypes } = router.query; return getFieldTranslation({ label, locale, appealtypes, fieldLookup }); }; export function FileUploadField(props) { const uploadCount = typeof props.uploadCount === "number" ? props.uploadCount : 0; const setFileCount = typeof props.setFileCount === "function" ? props.setFileCount : () => {}; return ( <>

{FieldsTranslations(props.label)}{" "}

); }