Refactor field array subfields renderer into dedicated component
This commit is contained in:
@@ -0,0 +1,146 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Field } from "redux-form";
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
import { RenderTextfield } from "./renderTextfield";
|
||||||
|
import { RenderDatePicker } from "./renderDatePicker";
|
||||||
|
|
||||||
|
export const RenderSubFields = ({
|
||||||
|
fields,
|
||||||
|
meta: { touched, error },
|
||||||
|
...custom
|
||||||
|
}) => {
|
||||||
|
let { t } = useTranslation();
|
||||||
|
|
||||||
|
let subTitle = fields.name.split("pinswg_")[1];
|
||||||
|
|
||||||
|
const checkValue = (value) => {
|
||||||
|
let errors;
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
errors = t("newappeal:is-required-label");
|
||||||
|
} else {
|
||||||
|
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 required = (value) =>
|
||||||
|
value ? undefined : t("newappeal:is-required-label");
|
||||||
|
|
||||||
|
const email = (value) => {
|
||||||
|
let errors;
|
||||||
|
|
||||||
|
const emailRegex =
|
||||||
|
/(?:[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/gi;
|
||||||
|
|
||||||
|
if (!emailRegex.test(value)) {
|
||||||
|
errors = t("newappeal:invalid-email-address-errormsg");
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
};
|
||||||
|
|
||||||
|
fields.length == 0 && fields.push({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className="subFieldList">
|
||||||
|
{fields.map((member, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<h4>
|
||||||
|
{subTitle == "owners" ? "Owner" : "Tenant"} #{index + 1}
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<div className="fieldArrayContainer">
|
||||||
|
<div className="govuk-grid-column-full">
|
||||||
|
<div
|
||||||
|
className="gouk-grid-row"
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
marginBottom: "20px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
id={`${member}.${fields.name}_firstname`}
|
||||||
|
name={`${member}.${fields.name}_firstname`}
|
||||||
|
type="text"
|
||||||
|
component={RenderTextfield}
|
||||||
|
validate={[checkValue]}
|
||||||
|
label={"First name"}
|
||||||
|
className="govuk-input govuk-input--width-12"
|
||||||
|
showErrorBottom={true}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
id={`${member}.${fields.name}_lastname`}
|
||||||
|
name={`${member}.${fields.name}_lastname`}
|
||||||
|
type="text"
|
||||||
|
component={RenderTextfield}
|
||||||
|
validate={[checkValue]}
|
||||||
|
label={"Last name"}
|
||||||
|
className="govuk-input govuk-input--width-12"
|
||||||
|
showErrorBottom={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="gouk-grid-row"
|
||||||
|
style={{ display: "flex" }}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
id={`${member}.${fields.name}_email`}
|
||||||
|
name={`${member}.${fields.name}_email`}
|
||||||
|
type="text"
|
||||||
|
component={RenderTextfield}
|
||||||
|
validate={[email]}
|
||||||
|
label={"Email"}
|
||||||
|
className="govuk-input govuk-input--width-12"
|
||||||
|
showErrorBottom={true}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
name={`${member}.dateserved`}
|
||||||
|
type="text"
|
||||||
|
component={RenderDatePicker}
|
||||||
|
label="Date served "
|
||||||
|
dateStart={"-6m"}
|
||||||
|
dateEnd={"0"}
|
||||||
|
validate={[required]}
|
||||||
|
className="govuk-input govuk-input--width-12"
|
||||||
|
showErrorBottom={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="gouk-grid-row"
|
||||||
|
style={{ display: "flex" }}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
title="Remove"
|
||||||
|
onClick={() => fields.remove(index)}
|
||||||
|
className="govuk-button fieldArrayDelete"
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<br />
|
||||||
|
{fields.length < custom.maxSubField && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="govuk-link fieldArrayLink"
|
||||||
|
onClick={() => fields.push({})}
|
||||||
|
>
|
||||||
|
{subTitle == "owners"
|
||||||
|
? t("newappeal:new-appeal-add-owner-label")
|
||||||
|
: t("newappeal:new-appeal-add-tenant-label")}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -41,6 +41,7 @@ import { RenderRadio } from "./fields/renderRadio";
|
|||||||
import { RenderCheckBox } from "./fields/renderCheckBox";
|
import { RenderCheckBox } from "./fields/renderCheckBox";
|
||||||
import { RenderPickList } from "./fields/renderPickList";
|
import { RenderPickList } from "./fields/renderPickList";
|
||||||
import { RenderDecimalField } from "./fields/renderDecimalField";
|
import { RenderDecimalField } from "./fields/renderDecimalField";
|
||||||
|
import { RenderSubFields } from "./fields/renderSubFields";
|
||||||
|
|
||||||
export function Textfield(props) {
|
export function Textfield(props) {
|
||||||
const {
|
const {
|
||||||
@@ -1584,143 +1585,6 @@ const renderField = ({ input, label, type, meta: { touched, error } }) => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const RenderSubFields = ({ fields, meta: { touched, error }, ...custom }) => {
|
|
||||||
let { t } = useTranslation();
|
|
||||||
|
|
||||||
let subTitle = fields.name.split("pinswg_")[1];
|
|
||||||
|
|
||||||
const checkValue = (value) => {
|
|
||||||
let errors;
|
|
||||||
|
|
||||||
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 required = (value) =>
|
|
||||||
value ? undefined : t("newappeal:is-required-label");
|
|
||||||
|
|
||||||
const email = (value) => {
|
|
||||||
let errors;
|
|
||||||
|
|
||||||
const emailRegex =
|
|
||||||
/(?:[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/gi;
|
|
||||||
|
|
||||||
if (!emailRegex.test(value)) {
|
|
||||||
errors = t("newappeal:invalid-email-address-errormsg");
|
|
||||||
}
|
|
||||||
return errors;
|
|
||||||
};
|
|
||||||
|
|
||||||
//fields.push({});
|
|
||||||
fields.length == 0 && fields.push({});
|
|
||||||
return (
|
|
||||||
<ul className="subFieldList">
|
|
||||||
{fields.map((member, index) => (
|
|
||||||
<div key={index}>
|
|
||||||
<h4>
|
|
||||||
{subTitle == "owners" ? "Owner" : "Tenant"} #{index + 1}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<div className="fieldArrayContainer">
|
|
||||||
<div className="govuk-grid-column-full">
|
|
||||||
<div
|
|
||||||
className="gouk-grid-row"
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
marginBottom: "20px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
id={`${member}.${fields.name}_firstname`}
|
|
||||||
name={`${member}.${fields.name}_firstname`}
|
|
||||||
type="text"
|
|
||||||
component={RenderTextfield}
|
|
||||||
validate={[checkValue]}
|
|
||||||
label={"First name"}
|
|
||||||
className="govuk-input govuk-input--width-12"
|
|
||||||
showErrorBottom={true}
|
|
||||||
/>
|
|
||||||
<Field
|
|
||||||
id={`${member}.${fields.name}_lastname`}
|
|
||||||
name={`${member}.${fields.name}_lastname`}
|
|
||||||
type="text"
|
|
||||||
component={RenderTextfield}
|
|
||||||
validate={[checkValue]}
|
|
||||||
label={"Last name"}
|
|
||||||
className="govuk-input govuk-input--width-12"
|
|
||||||
showErrorBottom={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="gouk-grid-row"
|
|
||||||
style={{ display: "flex" }}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
id={`${member}.${fields.name}_email`}
|
|
||||||
name={`${member}.${fields.name}_email`}
|
|
||||||
type="text"
|
|
||||||
component={RenderTextfield}
|
|
||||||
validate={[email]}
|
|
||||||
label={"Email"}
|
|
||||||
className="govuk-input govuk-input--width-12"
|
|
||||||
showErrorBottom={true}
|
|
||||||
/>
|
|
||||||
<Field
|
|
||||||
name={`${member}.dateserved`}
|
|
||||||
type="text"
|
|
||||||
component={RenderDatePicker}
|
|
||||||
label="Date served "
|
|
||||||
dateStart={"-6m"}
|
|
||||||
dateEnd={"0"}
|
|
||||||
validate={[required]}
|
|
||||||
className="govuk-input govuk-input--width-12"
|
|
||||||
showErrorBottom={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="gouk-grid-row"
|
|
||||||
style={{ display: "flex" }}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
title="Remove"
|
|
||||||
onClick={() => fields.remove(index)}
|
|
||||||
className="govuk-button fieldArrayDelete"
|
|
||||||
>
|
|
||||||
X
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<br />
|
|
||||||
{fields.length < custom.maxSubField && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="govuk-link fieldArrayLink"
|
|
||||||
onClick={() => fields.push({})}
|
|
||||||
>
|
|
||||||
{subTitle == "owners"
|
|
||||||
? t("newappeal:new-appeal-add-owner-label")
|
|
||||||
: t("newappeal:new-appeal-add-tenant-label")}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const FieldArrayForm = (props) => {
|
export const FieldArrayForm = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
|
|||||||
Reference in New Issue
Block a user