diff --git a/src/components/Organisms/MarketingPreferencesDS/MarketingPreferencesDSForm.js b/src/components/Organisms/MarketingPreferencesDS/MarketingPreferencesDSForm.js index 99834eaab..f3f9c1ebc 100644 --- a/src/components/Organisms/MarketingPreferencesDS/MarketingPreferencesDSForm.js +++ b/src/components/Organisms/MarketingPreferencesDS/MarketingPreferencesDSForm.js @@ -1,4 +1,5 @@ -import React from 'react'; +/* eslint-disable no-console */ +import React, { useState } from 'react'; import { useForm, FormProvider } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import Text from '../../Atoms/Text/Text'; @@ -23,7 +24,8 @@ const { mpValidationSchema, mpValidationOptions } = mpValidation; // Or customise and override the config to suit the destination app's requirements: const initalValueOverrides = { - mp_email: 'user@website.com' // Potentially provided earlier in the journey + mp_email: 'user@website.com', // Potentially provided earlier in the journey + mp_permissionEmail: 'true' }; const validationOverrides = { mp_permissionEmail: { hideInput: true }, // As we're passing a value above, hide the user input @@ -41,9 +43,12 @@ const { } = mpValidationCustom; const MarketingPreferencesDSForm = () => { + const [emailInteractedWith, setEmailInteractedWith] = useState(false); + function customSubmitHandler(formData) { - // eslint-disable-next-line no-console + // Obviously, in a *real* context, we'd do something useful with this data: console.log('Successful submission', formData); + console.log('emailInteractedWith:', emailInteractedWith); } // For our default instance: @@ -71,6 +76,8 @@ const MarketingPreferencesDSForm = () => { mpValidationOptions={mpValidationOptions} id="default" formContext={formMethods} + // Directly pass in our useState 'set' function as the callback: + emailInteractedCallback={setEmailInteractedWith} /> @@ -85,6 +92,8 @@ const MarketingPreferencesDSForm = () => { mpValidationOptions={mpValidationOptionsCustom} id="custom" formContext={formMethodsCustom} + // Directly pass in our useState 'set' function as the callback: + emailInteractedCallback={setEmailInteractedWith} /> diff --git a/src/components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS.js b/src/components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS.js index 33e8a34e2..b62aeae3e 100644 --- a/src/components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS.js +++ b/src/components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { useWatch } from 'react-hook-form'; import _ from 'lodash'; @@ -20,6 +20,7 @@ const MarketingPreferencesDS = ({ mpValidationOptions, id = null, formContext = null, + emailInteractedCallback, ...rest }) => { const { formState: { errors }, control } = formContext; @@ -30,6 +31,14 @@ const MarketingPreferencesDS = ({ const phoneChoice = useWatch({ control, name: 'mp_permissionPhone', defaultValue: null }); const smsChoice = useWatch({ control, name: 'mp_permissionSMS', defaultValue: null }); + useEffect(() => { + // Don't run on initial mount, only when actually updated: + if (emailChoice !== null) { + // Fire callback to update flag in parent component: + emailInteractedCallback(true); + } + }, [emailChoice, emailInteractedCallback]); + const { // eslint-disable-next-line camelcase mp_permissionEmail, mp_permissionSMS, mp_permissionPhone, mp_permissionPost @@ -37,11 +46,8 @@ const MarketingPreferencesDS = ({ // If the field is not required for each No/Yes choice, remove it from the DOM entirely const disableEmailInput = (mp_permissionEmail.yes === false && emailChoice.includes('yes')); - const disableSMSInput = (mp_permissionSMS.yes === false && smsChoice.includes('yes')); - const disablePhoneInput = (mp_permissionPhone.yes === false && phoneChoice.includes('yes')); - const disablePostInput = (mp_permissionPost.yes === false && postChoice.includes('yes')); // Required to track multiple errors to determine whether to show/hide the fieldset @@ -273,7 +279,9 @@ MarketingPreferencesDS.propTypes = { in the parent to set-up the validation, but also required here for additional functionality */ mpValidationOptions: PropTypes.objectOf(PropTypes.shape).isRequired, id: PropTypes.string, - formContext: PropTypes.shape() + formContext: PropTypes.shape(), + // For soft opt-in, as react-hook-form's 'isDirty' doesn't work with checkboxes, only Fields 😮‍💨 + emailInteractedCallback: PropTypes.func }; MaybeDisabled.propTypes = { diff --git a/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js b/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js index dc9ec76bd..555a29550 100644 --- a/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js +++ b/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js @@ -1,6 +1,8 @@ import * as yup from 'yup'; import { merge } from 'lodash'; +const phoneRegex = /^(((((\+44)|(0044))\s?\d{4}|\(?0\d{4}\)?)\s?\d{3}\s?\d{3})|((((\+44)|(0044))\s?\d{3}|\(?0\d{3}\)?)\s?\d{3}\s?\d{4})|((((\+44)|(0044))\s?\d{2}|\(?0\d{2}\)?)\s?\d{4}\s?\d{4}))(\s?\\#(\d{4}|\d{3}))?$/; + const setInitialValues = overrideValues => { const defaultValues = { mp_email: '', @@ -61,8 +63,6 @@ const buildValidationSchema = overrideOptions => { // Override with any custom options supplied const mpValidationOptions = merge(defaultOptions, overrideOptions); - const phoneRegex = /^(((((\+44)|(0044))\s?\d{4}|\(?0\d{4}\)?)\s?\d{3}\s?\d{3})|((((\+44)|(0044))\s?\d{3}|\(?0\d{3}\)?)\s?\d{3}\s?\d{4})|((((\+44)|(0044))\s?\d{2}|\(?0\d{2}\)?)\s?\d{4}\s?\d{4}))(\s?\\#(\d{4}|\d{3}))?$/; - const mpValidationFields = { mp_email: yup.string() .when('mp_permissionEmail', {