Files
pedwfrontend/pages/contactus.js
T

545 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import useTranslation from "next-translate/useTranslation";
import Head from "next/head";
import { useRouter } from "next/router";
import Breadcrumbs from "../components/breadcrumbs";
import CookieBanner from "../components/cookieBanner";
import Footer from "../components/footer";
import Header from "../components/header";
import ServiceBanner from "../components/servicebanner";
import Link from "next/link";
import {
Field,
change,
formValueSelector,
reduxForm,
touch,
SubmissionError,
} from "redux-form";
import { connect, submitError } from "react-redux";
import { createCRMTask, sendEmail } from "../actions";
import { useState } from "react";
const RenderPickList = ({
datafieldname,
picklistData,
id,
name,
label,
input,
errorMsg,
meta: { touched, error },
}) => {
let { t } = useTranslation();
const required = (value) => {
return value || value == 0
? undefined
: t("newappeal:is-required-label");
};
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-!-margin-bottom-1 govuk-form-group--error"
: "govuk-form-group govuk-!-margin-bottom-1"
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{label}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{error}
</span>
)}
<select
{...input}
className="govuk-select govuk-input--width-20"
id={id}
name={id}
>
<option value="" disabled defaultValue>
{t("newappeal:select-default")}
</option>
<option value="plq">Planning legislation query</option>
<option value="ipq">Infrastructure procedure query</option>
<option value="pcpq">
Planning casework procedure query
</option>
<option value="pi">Portal Issues</option>
<option value="appadvice">Appeal submission advice</option>
<option value="repadvice">
Representation submission advice
</option>
<option value="ceq">Casework Events Query</option>
<option value="other">Any Other Enquiries</option>
<option value="postdec">Post Decision</option>
<option value="comp">Complaints/Complements</option>
</select>
</div>
</>
);
};
const RenderMultiline = ({
id,
className,
rows,
cols,
datafieldname,
name,
label,
input,
errorMsg,
meta: { touched, error },
...custom
}) => {
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{label}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{errorMsg || error}
</span>
)}
<textarea
id={id}
name={id}
rows={rows}
cols={cols}
className={className}
{...input}
maxLength={
custom.hasOwnProperty("maxFieldLength")
? custom.maxFieldLength
? custom.maxFieldLength
: 800
: 800
}
></textarea>
</div>
</>
);
};
const RenderTextfield = ({
id,
className,
rows,
datafieldname,
name,
label,
input,
errorMsg,
meta: { touched, error },
...custom
}) => {
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{label}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{errorMsg || error}
</span>
)}
<input
{...input}
type={"email"}
className={className}
name={id || name}
id={id || name}
maxLength={
custom.hasOwnProperty("maxFieldLength")
? custom.maxFieldLength
? custom.maxFieldLength
: 100
: 200
}
pattern={
custom.hasOwnProperty("pattern")
? custom.pattern
: undefined
}
/>
</div>
</>
);
};
const contactPurpose = (contactValue) => {
let contactPurposeBody;
switch (contactValue) {
case "plq":
contactPurposeBody = (
<p className="govuk-body">
Questions about Planning legislation or policy
</p>
);
break;
case "ipq":
contactPurposeBody = (
<p className="govuk-body">
Questions or comments about applications for major
infrastructure projects
</p>
);
break;
case "pcpq":
contactPurposeBody = (
<p className="govuk-body">
Questions or comments about planning and environmental
appeals
</p>
);
break;
case "pi":
contactPurposeBody = (
<p className="govuk-body">
Query about using the Casework Portal
</p>
);
break;
case "appadvice":
contactPurposeBody = (
<p className="govuk-body">Advice How to submit an appeal</p>
);
break;
case "repadvice":
contactPurposeBody = (
<p className="govuk-body">
Advice How to comment on an appeal or application
</p>
);
break;
case "ceq":
contactPurposeBody = (
<p className="govuk-body">
Queries about forthcoming Hearing or Inquiry event
</p>
);
break;
case "other":
contactPurposeBody = (
<p className="govuk-body">Other enquiry for PEDW</p>
);
break;
case "postdec":
contactPurposeBody = (
<p className="govuk-body">
Issues or questions about a case after the decision is
issued
</p>
);
break;
case "comp":
contactPurposeBody = (
<p className="govuk-body">General Complaints of Compliments</p>
);
break;
default:
// code block
}
return contactPurposeBody;
};
let t;
let ContactUs = (props) => {
const { footerLinks, pages } = props;
let { t } = useTranslation();
const [formSubmitted, setFormSubmitted] = useState(false);
const router = useRouter();
const { locale } = router;
const required = (value) =>
value ? undefined : t("newappeal:is-required-label");
const emailRegex =
/^(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}|(?:\[(?: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-zA-Z0-9-]*[a-zA-Z0-9]:.+)])$/;
const email = (value) =>
value && !emailRegex.test(value)
? t("account:invalid-email-address-errormsg")
: undefined;
const onSubmit = async (formValues) => {
// Only called if validation passes
sendContactEmail(formValues);
createCRMTask(formValues);
formValues.typeOfContact == "plq" &&
sendPETEmail(formValues, props.petEmail);
console.log("Form submitted:", formValues);
};
const sendContactEmail = async (formValues) => {
Object.assign(formValues, {
"contactSubject": contactPurpose(formValues.typeOfContact).props
.children,
});
const reference = "PEDW-CONTACT-US";
const templateId = "69228c5f-8500-40ff-a6c5-95a9434c3ec8";
const templateIdCY = "b8f1f76d-4ab9-4a2f-b294-e3623c6095a3";
try {
const res = await sendEmail(
router.locale !== "en" ? templateIdCY : templateId,
formValues.contactEmail,
formValues,
reference
);
console.log("Email sent successfully.");
setFormSubmitted(true);
} catch (error) {
console.error("Email sending failed:", error);
alert("Something went wrong. Please try again later.");
// Required: inform redux-form this is a submit error
throw new SubmissionError({
_error: "Failed to send email. Please try again later.",
});
}
};
const sendPETEmail = async (formValues, petEmail) => {
const reference = "PEDW-CONTACT-US-PET";
const templateId = "56bbdcf9-d63d-48e9-a794-3e253dd7498b";
const templateIdCY = "00b794d3-29aa-434d-b696-0ef0b0337d79";
console.log(petEmail);
try {
const res = await sendEmail(
templateId,
petEmail,
formValues,
reference
);
console.log("Email sent successfully.");
setFormSubmitted(true);
} catch (error) {
console.error("Email sending failed:", error);
alert("Something went wrong. Please try again later.");
// Required: inform redux-form this is a submit error
throw new SubmissionError({
_error: "Failed to send email. Please try again later.",
});
}
};
return (
<div>
<Head>
<title>{t("common:service-name")}</title>
</Head>
<div id="page_wrapper">
<CookieBanner />
<Header />
<div className="govuk-width-container">
<Breadcrumbs />
<ServiceBanner props={props} />
<main
className="govuk-main-wrapper govuk-!-padding-top-9 govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<h2 className="govuk-heading-l govuk-!-margin-bottom-7">
Contact us{" "}
</h2>
<div className="wgForm">
{formSubmitted ? (
<div className="govuk-panel govuk-panel--confirmation">
<h1 className="govuk-panel__title">
Thank you for your enquiry
</h1>
<div className="govuk-panel__body">
Well get back to you as soon as
we can.
</div>
</div>
) : (
<>
<p className="govuk-body">
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Nulla congue leo ac quam
pulvinar, id vulputate libero
volutpat. Maecenas ut odio id
nisl laoreet dictum. Nam
faucibus, leo vitae egestas
lacinia, enim tortor bibendum
lorem, ut tincidunt lacus sapien
quis lorem. Aenean interdum
dolor augue, ac cursus lectus
suscipit vitae.{" "}
</p>
<form
onSubmit={props.handleSubmit(
onSubmit
)}
>
<Field
name={"contactEmail"}
id={"contactEmail"}
label="Your email address"
component={RenderTextfield}
validate={[required, email]}
className="govuk-input govuk-input--width-20"
type="email"
/>
<Field
name="typeOfContact"
id="typeOfContact"
component={RenderPickList}
label="What do you want to contact us about?"
validate={[required]}
/>
<div className="govuk-form-group">
{props.typeOfContactValue && (
<div>
{contactPurpose(
props.typeOfContactValue
)}
</div>
)}
</div>
<Field
name="contactbody"
id="contactbody"
component={RenderMultiline}
label="What do you want to ask?"
rows={10}
cols={80}
validate={[required]}
/>
<button
type="submit"
className="govuk-button"
>
Send your question
</button>
<button
type="button"
className="govuk-button govuk-button--secondary govuk-!-margin-left-5"
onClick={props.reset}
>
Clear form
</button>
</form>
</>
)}
</div>
</div>
</div>
</main>
</div>
<Footer footerLinks={footerLinks} ticketnumber={props} />
</div>
</div>
);
};
const selector = formValueSelector("contactUsForm"); // <-- same as form name
// ContactUs = connect((state) => {
// const typeOfContactValue = selector(state, "typeOfContact");
// return {
// typeOfContactValue,
// initialValues: {
// contactEmail:
// state.accountDetails.accountDetails?.emailaddress1 || "",
// },
// };
// })(ContactUs);
const mapDispatchToProps = (dispatch) => ({});
const mapStateToProps = (state) => {
const typeOfContactValue = selector(state, "typeOfContact");
const email = state.accountDetails.accountDetails?.emailaddress1;
return {
typeOfContactValue,
initialValues: email ? { contactEmail: email } : {},
petEmail: process.env.NEXT_PUBLIC_PETEMAIL,
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(
reduxForm({
form: "contactUsForm",
enableReinitialize: true,
destroyOnUnmount: false,
touchOnBlur: true,
touchOnChange: true,
onSubmitFail: (errors, dispatch, subnittError, props) => {
if (errors) {
// Touch all fields with errors so validation messages appear
const errorFields = Object.keys(errors);
dispatch(touch("contactUsForm", ...errorFields));
// Scroll to first error
const firstErrorField = errorFields[0];
const errorElement = document.querySelector(
`[name="${firstErrorField}"]`
);
if (
errorElement &&
typeof errorElement.scrollIntoView === "function"
) {
errorElement.scrollIntoView({
behavior: "smooth",
block: "center",
});
errorElement.focus({ preventScroll: true });
} else {
console.warn(
"Could not find element for error field:",
firstErrorField
);
}
}
console.log("Redux Form onSubmitFail:", submitError);
},
})(ContactUs)
);