From 204ee8b020b18d54be677c4e120b261a8c1fcc4f Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Fri, 12 Apr 2024 13:15:32 +0200 Subject: [PATCH 1/6] feat: added bcc email validation with otp code --- src/actions/index.js | 21 ++++ src/components/FormView.jsx | 94 +++++++++++++----- src/components/View.jsx | 28 ++++-- src/components/Widget/Button.jsx | 13 +++ src/components/Widget/FileWidget.jsx | 7 +- src/components/Widget/OTPWidget.css | 28 ++++++ src/components/Widget/OTPWidget.jsx | 142 +++++++++++++++++++++++++++ src/components/Widget/index.js | 3 + src/index.js | 11 ++- src/reducers/index.js | 80 +++++++++++++++ 10 files changed, 388 insertions(+), 39 deletions(-) create mode 100644 src/components/Widget/Button.jsx create mode 100644 src/components/Widget/OTPWidget.css create mode 100644 src/components/Widget/OTPWidget.jsx diff --git a/src/actions/index.js b/src/actions/index.js index 2bb5a6c..2929a4a 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -85,3 +85,24 @@ export function clearFormData({ path, block_id, expired = false }) { }, }; } + +/** + * sendOTP action + * @module actions/sendOTP + */ +export const SEND_OTP = 'SEND_OTP'; + +export function sendOTP(path, block_id, email) { + return { + type: SUBMIT_FORM_ACTION, + subrequest: block_id + '_' + email, + request: { + op: 'post', + path: path + '/@validate-email-address', + data: { + email, + uid: block_id, + }, + }, + }; +} diff --git a/src/components/FormView.jsx b/src/components/FormView.jsx index faf5242..f216e29 100644 --- a/src/components/FormView.jsx +++ b/src/components/FormView.jsx @@ -1,15 +1,13 @@ import React from 'react'; import { useIntl, defineMessages } from 'react-intl'; -import { - Segment, - Message, - Grid, - Form, - Progress, - Button, -} from 'semantic-ui-react'; +import { Segment, Message, Grid, Form, Progress } from 'semantic-ui-react'; import { getFieldName } from 'volto-form-block/components/utils'; import Field from 'volto-form-block/components/Field'; +import { + OTPWidget, + OTP_FIELDNAME_EXTENDER, + Button, +} from 'volto-form-block/components/Widget'; import config from '@plone/volto/registry'; /* Style */ @@ -54,6 +52,8 @@ const FormView = ({ captcha, id, getErrorMessage, + path, + block_id, }) => { const intl = useIntl(); const FieldSchema = config.blocks.blocksConfig.form.fieldSchema; @@ -84,6 +84,25 @@ const FormView = ({ onSubmit(e); }; + const getFieldsToSendWithValue = (subblock) => { + var fields_to_send = []; + var fieldSchemaProperties = FieldSchema(subblock)?.properties; + for (var key in fieldSchemaProperties) { + if (fieldSchemaProperties[key].send_to_backend) { + fields_to_send.push(key); + } + } + + var fields_to_send_with_value = Object.assign( + {}, + ...fields_to_send.map((field) => { + return { + [field]: subblock[field], + }; + }), + ); + return fields_to_send_with_value; + }; return (
@@ -155,22 +174,8 @@ const FormView = ({ {data.subblocks?.map((subblock, index) => { let name = getFieldName(subblock.label, subblock.id); - var fields_to_send = []; - var fieldSchemaProperties = FieldSchema(subblock)?.properties; - for (var key in fieldSchemaProperties) { - if (fieldSchemaProperties[key].send_to_backend) { - fields_to_send.push(key); - } - } - - var fields_to_send_with_value = Object.assign( - {}, - ...fields_to_send.map((field) => { - return { - [field]: subblock[field], - }; - }), - ); + const fields_to_send_with_value = + getFieldsToSendWithValue(subblock); return ( @@ -199,6 +204,46 @@ const FormView = ({ ); })} + + {/*OTP*/} + {data.subblocks + .filter((subblock) => subblock.use_as_bcc) + .map((subblock, index) => { + const fieldName = getFieldName(subblock.label, subblock.id); + const name = fieldName + OTP_FIELDNAME_EXTENDER; + const fieldValue = formData[name]?.value; + const fields_to_send_with_value = + getFieldsToSendWithValue(subblock); + + return ( + + + + onChangeFormData( + subblock.id, + fieldName, + fieldValue, + { + ...fields_to_send_with_value, + otp: value, + }, + ) + } + value={formData[name]?.otp} + valid={isValidField(name)} + errorMessage={getErrorMessage(name)} + formHasErrors={formErrors?.length > 0} + path={path} + block_id={block_id} + /> + + + ); + })} + {captcha.render()} {formErrors.length > 0 && ( @@ -208,7 +253,6 @@ const FormView = ({

{intl.formatMessage(messages.form_errors)}

)} - {formState.error && ( diff --git a/src/components/View.jsx b/src/components/View.jsx index 033076d..e0f7458 100644 --- a/src/components/View.jsx +++ b/src/components/View.jsx @@ -10,6 +10,7 @@ import config from '@plone/volto/registry'; import { Captcha } from 'volto-form-block/components/Widget'; import { isValidEmail } from 'volto-form-block/helpers/validators'; import ValidateConfigForm from 'volto-form-block/components/ValidateConfigForm'; +import { OTP_FIELDNAME_EXTENDER } from 'volto-form-block/components/Widget'; const messages = defineMessages({ formSubmitted: { @@ -28,6 +29,10 @@ const messages = defineMessages({ id: 'formblock_invalidEmailMessage', defaultMessage: 'The email is incorrect', }, + insertOtp: { + id: 'formblock_insertOtp_error', + defaultMessage: 'Please, insert the OTP code recived via email.', + }, }); const initialState = { @@ -132,6 +137,7 @@ const View = ({ data, id, path }) => { data.subblocks.forEach((subblock, index) => { const name = getFieldName(subblock.label, subblock.id); const fieldType = subblock.field_type; + const isBCC = subblock.use_as_bcc; const additionalField = config.blocks.blocksConfig.form.additionalFields?.filter( (f) => f.id === fieldType && f.isValid !== undefined, @@ -172,14 +178,20 @@ const View = ({ data, id, path }) => { message: intl.formatMessage(messages.requiredFieldMessage), }); } else if ( - fieldType === 'from' && - formData[name]?.value && - !isValidEmail(formData[name].value) + (fieldType === 'from' || fieldType === 'email') && + formData[name]?.value ) { - v.push({ - field: name, - message: intl.formatMessage(messages.invalidEmailMessage), - }); + if (!isValidEmail(formData[name].value)) { + v.push({ + field: name, + message: intl.formatMessage(messages.invalidEmailMessage), + }); + } else if (isBCC && !formData[name].otp) { + v.push({ + field: name + OTP_FIELDNAME_EXTENDER, + message: intl.formatMessage(messages.insertOtp), + }); + } } }); @@ -324,6 +336,8 @@ const View = ({ data, id, path }) => { resetFormState={resetFormState} resetFormOnError={resetFormOnError} getErrorMessage={getErrorMessage} + path={path} + block_id={id} /> ); diff --git a/src/components/Widget/Button.jsx b/src/components/Widget/Button.jsx new file mode 100644 index 0000000..94ceeef --- /dev/null +++ b/src/components/Widget/Button.jsx @@ -0,0 +1,13 @@ +/** + * Button component. + * This is a wrapper for Buttons, to eventually customize Button component if you don't like to use semantic-ui, for example. + * @module components/Widget/OTPWidget + */ + +import { Button as SemanticButton } from 'semantic-ui-react'; + +const Button = (props) => { + return ; +}; + +export default Button; diff --git a/src/components/Widget/FileWidget.jsx b/src/components/Widget/FileWidget.jsx index 6cb80d2..a0d1b8e 100644 --- a/src/components/Widget/FileWidget.jsx +++ b/src/components/Widget/FileWidget.jsx @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Button, Image, Dimmer } from 'semantic-ui-react'; +import { Image, Dimmer } from 'semantic-ui-react'; import { readAsDataURL } from 'promise-file-reader'; import { injectIntl } from 'react-intl'; import deleteSVG from '@plone/volto/icons/delete.svg'; @@ -14,6 +14,7 @@ import { Icon, FormFieldWrapper } from '@plone/volto/components'; import loadable from '@loadable/component'; import { flattenToAppURL } from '@plone/volto/helpers'; import { defineMessages, useIntl } from 'react-intl'; +import { Button } from 'volto-form-block/components/Widget'; const imageMimetypes = [ 'image/png', @@ -85,8 +86,8 @@ const FileWidget = (props) => { const imgsrc = value?.download ? `${flattenToAppURL(value?.download)}?id=${Date.now()}` : null || value?.data - ? `data:${value['content-type']};${value.encoding},${value.data}` - : null; + ? `data:${value['content-type']};${value.encoding},${value.data}` + : null; /** * Drop handler diff --git a/src/components/Widget/OTPWidget.css b/src/components/Widget/OTPWidget.css new file mode 100644 index 0000000..52398da --- /dev/null +++ b/src/components/Widget/OTPWidget.css @@ -0,0 +1,28 @@ +.otp-widget .otp-widget-field-wrapper { + display: flex; + gap: 1rem; + align-items: start; +} +.otp-widget .otp-widget-field-wrapper .field { + flex-grow: 1; +} + +.otp-widget .otp-send-error { + color: #d9364f; + padding: 1rem; + margin: 1rem; + border: 1px solid #d9364f; + width: 100%; + text-align: center; +} + +@media (max-width: 1024px) { + .otp-widget .otp-widget-field-wrapper { + flex-direction: column; + } + .otp-widget .otp-widget-field-wrapper .field, + .otp-widget .otp-widget-field-wrapper .button-wrapper, + .otp-widget .otp-widget-field-wrapper .button-wrapper button { + width: 100%; + } +} diff --git a/src/components/Widget/OTPWidget.jsx b/src/components/Widget/OTPWidget.jsx new file mode 100644 index 0000000..2b72170 --- /dev/null +++ b/src/components/Widget/OTPWidget.jsx @@ -0,0 +1,142 @@ +/** + * OTPWidget component. + * @module components/Widget/OTPWidget + */ + +import PropTypes from 'prop-types'; +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { useIntl, defineMessages } from 'react-intl'; +import { isValidEmail } from 'volto-form-block/helpers/validators'; +import Field from 'volto-form-block/components/Field'; +import { Button } from 'volto-form-block/components/Widget'; +import { sendOTP } from 'volto-form-block/actions'; + +import 'volto-form-block/components/Widget/OTPWidget.css'; +export const OTP_FIELDNAME_EXTENDER = '_otp'; + +const messages = defineMessages({ + send_otp_to: { + id: 'form_send_otp_to', + defaultMessage: 'Send OTP code to {email}', + }, + insert_otp: { + id: 'form_insert_otp', + defaultMessage: 'Insert here the OTP code received at {email}', + }, +}); + +const OTPWidget = (props) => { + const { + id, + title, + fieldValue, + onChange, + value, + valid, + disabled, + isOnEdit, + formHasErrors, + errorMessage, + path, + block_id, + } = props; + const intl = useIntl(); + const dispatch = useDispatch(); + const _id = id + OTP_FIELDNAME_EXTENDER; + const sendOTPResponse = useSelector( + (state) => state.sendOTP?.subrequests?.[block_id + '_' + fieldValue], + ); + + const displayWidget = isValidEmail(fieldValue); + + const sendOTPCode = () => { + dispatch(sendOTP(path, block_id, fieldValue)); + }; + + return displayWidget ? ( +
+
+
+ +
+ +
+ + {sendOTPResponse?.error && ( +
+ {JSON.stringify(sendOTPResponse.error)} +
+ )} +
+ ) : ( + <> + ); +}; + +/** + * Property types + * @property {Object} propTypes Property types. + * @static + */ +OTPWidget.propTypes = { + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + description: PropTypes.string, + required: PropTypes.bool, + error: PropTypes.arrayOf(PropTypes.string), + value: PropTypes.string, + onChange: PropTypes.func.isRequired, + onBlur: PropTypes.func, + onClick: PropTypes.func, + minLength: PropTypes.number, + maxLength: PropTypes.number, + placeholder: PropTypes.string, +}; + +/** + * Default properties. + * @property {Object} defaultProps Default properties. + * @static + */ +OTPWidget.defaultProps = { + description: null, + required: false, + error: [], + value: null, + onChange: () => {}, + onBlur: () => {}, + onClick: () => {}, + minLength: null, + maxLength: null, +}; + +export default OTPWidget; diff --git a/src/components/Widget/index.js b/src/components/Widget/index.js index 1b2cb56..a5c031b 100644 --- a/src/components/Widget/index.js +++ b/src/components/Widget/index.js @@ -13,3 +13,6 @@ export { default as RadioWidget } from 'volto-form-block/components/Widget/Radio export { default as SelectWidget } from 'volto-form-block/components/Widget/SelectWidget'; export { default as TextareaWidget } from 'volto-form-block/components/Widget/TextareaWidget'; export { default as TextWidget } from 'volto-form-block/components/Widget/TextWidget'; +export { default as OTPWidget } from 'volto-form-block/components/Widget/OTPWidget'; +export { OTP_FIELDNAME_EXTENDER } from 'volto-form-block/components/Widget/OTPWidget'; +export { default as Button } from 'volto-form-block/components/Widget/Button'; diff --git a/src/index.js b/src/index.js index 07fe390..8b4439d 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,7 @@ import { getFormData, exportCsvFormData, clearFormData, + sendOTP, } from 'volto-form-block/reducers'; import FormSchema from 'volto-form-block/formSchema'; import FieldSchema from 'volto-form-block/fieldSchema'; @@ -34,6 +35,7 @@ export { submitForm, getFormData, exportCsvFormData, + sendOTP, } from 'volto-form-block/actions'; export { isValidEmail }; @@ -83,13 +85,14 @@ const applyConfig = (config) => { formData: getFormData, exportCsvFormData, clearFormData, + sendOTP, }; - config.settings.loadables['HCaptcha'] = loadable(() => - import('@hcaptcha/react-hcaptcha'), + config.settings.loadables['HCaptcha'] = loadable( + () => import('@hcaptcha/react-hcaptcha'), ); - config.settings.loadables['GoogleReCaptcha'] = loadable.lib(() => - import('react-google-recaptcha-v3'), + config.settings.loadables['GoogleReCaptcha'] = loadable.lib( + () => import('react-google-recaptcha-v3'), ); return config; diff --git a/src/reducers/index.js b/src/reducers/index.js index 2df6cca..aef4ecc 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -7,6 +7,7 @@ import { EXPORT_CSV_FORMDATA, GET_FORM_DATA, CLEAR_FORM_DATA, + SEND_OTP, } from 'volto-form-block/actions'; function download(filename, text) { @@ -223,3 +224,82 @@ export const clearFormData = (state = initialState, action = {}) => { return state; } }; + +/** + * sendOTP reducer. + * @function sendOTP + * @param {Object} state Current state. + * @param {Object} action Action to be handled. + * @returns {Object} New state. + */ +export const sendOTP = (state = initialState, action = {}) => { + switch (action.type) { + case `${SEND_OTP}_PENDING`: + return action.subrequest + ? { + ...state, + subrequests: { + ...state.subrequests, + [action.subrequest]: { + ...(state.subrequests[action.subrequest] || { + items: [], + total: 0, + batching: {}, + }), + error: null, + loaded: false, + loading: true, + }, + }, + } + : { + ...state, + error: null, + loading: true, + loaded: false, + }; + case `${SEND_OTP}_SUCCESS`: + return action.subrequest + ? { + ...state, + subrequests: { + ...state.subrequests, + [action.subrequest]: { + ...(state.subrequests[action.subrequest] || {}), + error: null, + loaded: true, + loading: false, + }, + }, + } + : { + ...state, + error: null, + loaded: true, + loading: false, + }; + case `${SEND_OTP}_FAIL`: + return action.subrequest + ? { + ...state, + subrequests: { + ...state.subrequests, + [action.subrequest]: { + ...(state.subrequests[action.subrequest] || {}), + error: action.error, + loading: false, + loaded: false, + }, + }, + } + : { + ...state, + error: action.error, + loading: false, + loaded: false, + }; + + default: + return state; + } +}; From 0e82b9c02024938567cbc4ece421d5102a4dadcf Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Tue, 16 Apr 2024 11:25:41 +0200 Subject: [PATCH 2/6] fix: locales and otp widget --- locales/de/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/en/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/es/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/eu/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/fr/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/it/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/ja/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/nl/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/pt/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/pt_BR/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/ro/LC_MESSAGES/volto.po | 19 +++++++++++++++++-- locales/volto.pot | 21 ++++++++++++++++++--- src/components/FormView.jsx | 7 ++++--- 13 files changed, 209 insertions(+), 28 deletions(-) diff --git a/locales/de/LC_MESSAGES/volto.po b/locales/de/LC_MESSAGES/volto.po index 650f70e..e855db6 100644 --- a/locales/de/LC_MESSAGES/volto.po +++ b/locales/de/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Daten exportieren" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,6 +424,11 @@ msgstr "Textfeld" msgid "form_formDataCount" msgstr "{formDataCount} Element(e) gespeichert" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "Setzt diese Adresse als Antwortadresse in versendeten Mails" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/en/LC_MESSAGES/volto.po b/locales/en/LC_MESSAGES/volto.po index 3a10917..e8aa25e 100644 --- a/locales/en/LC_MESSAGES/volto.po +++ b/locales/en/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Export in CSV" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,6 +424,11 @@ msgstr "Textarea" msgid "form_formDataCount" msgstr "{formDataCount} item(s) stored" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "Message of sending confirmed" msgid "form_send_message_helptext" msgstr "You can add the value of a filled field in the form by inserting its ID between curly brackets preceded by $, example: ${field_id}; you can add html elements such as links , new line
, bold and italic formatting." +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "If selected, this will be the address the receiver can use to reply." msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/es/LC_MESSAGES/volto.po b/locales/es/LC_MESSAGES/volto.po index 9564076..b929c55 100644 --- a/locales/es/LC_MESSAGES/volto.po +++ b/locales/es/LC_MESSAGES/volto.po @@ -307,12 +307,12 @@ msgstr "Exportar datos" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -433,6 +433,11 @@ msgstr "Campo de texto" msgid "form_formDataCount" msgstr "{formDataCount} elemento(s) guardados" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -478,6 +483,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -523,6 +533,11 @@ msgstr "Si está seleccionado el valor de este campo se utilizará como cabecera msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/eu/LC_MESSAGES/volto.po b/locales/eu/LC_MESSAGES/volto.po index 8297a6a..ba44f4d 100644 --- a/locales/eu/LC_MESSAGES/volto.po +++ b/locales/eu/LC_MESSAGES/volto.po @@ -300,12 +300,12 @@ msgstr "Esportatu datuak" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -426,6 +426,11 @@ msgstr "Testua" msgid "form_formDataCount" msgstr "Gordetako elementu kopurua: {formDataCount}" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -471,6 +476,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -516,6 +526,11 @@ msgstr "Aukeratuz gero jasotako posta elektronikoari 'Erantzun' eginez gero erem msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/fr/LC_MESSAGES/volto.po b/locales/fr/LC_MESSAGES/volto.po index 75ac30f..b239291 100644 --- a/locales/fr/LC_MESSAGES/volto.po +++ b/locales/fr/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Exporter au format CSV" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,6 +424,11 @@ msgstr "Zone de texte" msgid "form_formDataCount" msgstr "{formDataCount} article(s) stocké(s)" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/it/LC_MESSAGES/volto.po b/locales/it/LC_MESSAGES/volto.po index 6d24e06..e376e48 100644 --- a/locales/it/LC_MESSAGES/volto.po +++ b/locales/it/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Esporta in CSV" msgid "form_edit_fill_required_configuration_fields" msgstr "Inserire i campi obbligatori per la configurazione del form nella sidebar di destra. Il form non verrà mostrato sul sito finché i campi obbligatori non saranno configurati." -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "L'e-mail inserita nel campo 'Mittente di default' deve essere un indirizzo e-mail valido" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "Le e-mail inserite nel campo 'Destinatari' devono essere indirizzi e-mail validi." @@ -424,6 +424,11 @@ msgstr "Area di testo" msgid "form_formDataCount" msgstr "{formDataCount} elementi salvati" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "Inserisci qui il codice OTP ricevuto all'indirizzo {email}" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "Messaggio di conferma invio" msgid "form_send_message_helptext" msgstr "Si può aggiungere il valore di un campo compilato nella form inserendo il suo identificativo tra parentesi graffe preceduto da $, esempio: ${identificativo}; inoltre si possono aggiungere elementi html come link,
, nuova linea
, formattazioni in bold e italic ." +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "Invia il codice OTP a {email}" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "Se selezionato, questo sarà l'indirizzo a cui il destinatario potrà ri msgid "formblock_defaultInvalidFieldMessage" msgstr "Il valore inserito non è valido" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "Inserire il codice OTP ricevuto via email." + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/ja/LC_MESSAGES/volto.po b/locales/ja/LC_MESSAGES/volto.po index 5676c5d..681ae24 100644 --- a/locales/ja/LC_MESSAGES/volto.po +++ b/locales/ja/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,6 +424,11 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/nl/LC_MESSAGES/volto.po b/locales/nl/LC_MESSAGES/volto.po index 5676c5d..681ae24 100644 --- a/locales/nl/LC_MESSAGES/volto.po +++ b/locales/nl/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,6 +424,11 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/pt/LC_MESSAGES/volto.po b/locales/pt/LC_MESSAGES/volto.po index 5676c5d..681ae24 100644 --- a/locales/pt/LC_MESSAGES/volto.po +++ b/locales/pt/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,6 +424,11 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/pt_BR/LC_MESSAGES/volto.po b/locales/pt_BR/LC_MESSAGES/volto.po index 632b5d7..838a623 100644 --- a/locales/pt_BR/LC_MESSAGES/volto.po +++ b/locales/pt_BR/LC_MESSAGES/volto.po @@ -304,12 +304,12 @@ msgstr "Exportar dados" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -430,6 +430,11 @@ msgstr "Área de texto" msgid "form_formDataCount" msgstr "{formDataCount} item(ns) armazenados" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -475,6 +480,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -520,6 +530,11 @@ msgstr "Usar este campo como valor do cabeçalho de 'responder para'" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/ro/LC_MESSAGES/volto.po b/locales/ro/LC_MESSAGES/volto.po index 5676c5d..681ae24 100644 --- a/locales/ro/LC_MESSAGES/volto.po +++ b/locales/ro/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,6 +424,11 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -469,6 +474,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -514,6 +524,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/volto.pot b/locales/volto.pot index 153ecfc..d404c32 100644 --- a/locales/volto.pot +++ b/locales/volto.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2024-03-18T09:07:32.597Z\n" +"POT-Creation-Date: 2024-04-16T09:11:47.457Z\n" "Last-Translator: Plone i18n \n" "Language-Team: Plone i18n \n" "MIME-Version: 1.0\n" @@ -300,12 +300,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -426,6 +426,11 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" @@ -471,6 +476,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -516,6 +526,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/src/components/FormView.jsx b/src/components/FormView.jsx index f216e29..483d01e 100644 --- a/src/components/FormView.jsx +++ b/src/components/FormView.jsx @@ -211,7 +211,8 @@ const FormView = ({ .map((subblock, index) => { const fieldName = getFieldName(subblock.label, subblock.id); const name = fieldName + OTP_FIELDNAME_EXTENDER; - const fieldValue = formData[name]?.value; + const fieldValue = formData[fieldName]?.value; + const value = formData[fieldName]?.otp; const fields_to_send_with_value = getFieldsToSendWithValue(subblock); @@ -221,7 +222,7 @@ const FormView = ({ + onChange={(field, value) => onChangeFormData( subblock.id, fieldName, @@ -232,7 +233,7 @@ const FormView = ({ }, ) } - value={formData[name]?.otp} + value={value} valid={isValidField(name)} errorMessage={getErrorMessage(name)} formHasErrors={formErrors?.length > 0} From 71fddcc0097682765cd1b890eb40d9b04cc1489a Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Tue, 16 Apr 2024 12:31:11 +0200 Subject: [PATCH 3/6] fix: form response --- locales/de/LC_MESSAGES/volto.po | 5 +++++ locales/en/LC_MESSAGES/volto.po | 5 +++++ locales/es/LC_MESSAGES/volto.po | 5 +++++ locales/eu/LC_MESSAGES/volto.po | 5 +++++ locales/fr/LC_MESSAGES/volto.po | 5 +++++ locales/it/LC_MESSAGES/volto.po | 5 +++++ locales/ja/LC_MESSAGES/volto.po | 5 +++++ locales/nl/LC_MESSAGES/volto.po | 5 +++++ locales/pt/LC_MESSAGES/volto.po | 5 +++++ locales/pt_BR/LC_MESSAGES/volto.po | 5 +++++ locales/ro/LC_MESSAGES/volto.po | 5 +++++ locales/volto.pot | 7 ++++++- src/actions/index.js | 2 +- src/components/Widget/OTPWidget.css | 24 +++++++++++++++++------- src/components/Widget/OTPWidget.jsx | 13 ++++++++++++- src/reducers/index.js | 1 + 16 files changed, 92 insertions(+), 10 deletions(-) diff --git a/locales/de/LC_MESSAGES/volto.po b/locales/de/LC_MESSAGES/volto.po index e855db6..e8c3fbb 100644 --- a/locales/de/LC_MESSAGES/volto.po +++ b/locales/de/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/en/LC_MESSAGES/volto.po b/locales/en/LC_MESSAGES/volto.po index e8aa25e..626eaba 100644 --- a/locales/en/LC_MESSAGES/volto.po +++ b/locales/en/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/es/LC_MESSAGES/volto.po b/locales/es/LC_MESSAGES/volto.po index b929c55..18b32e5 100644 --- a/locales/es/LC_MESSAGES/volto.po +++ b/locales/es/LC_MESSAGES/volto.po @@ -443,6 +443,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/eu/LC_MESSAGES/volto.po b/locales/eu/LC_MESSAGES/volto.po index ba44f4d..83fea09 100644 --- a/locales/eu/LC_MESSAGES/volto.po +++ b/locales/eu/LC_MESSAGES/volto.po @@ -436,6 +436,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/fr/LC_MESSAGES/volto.po b/locales/fr/LC_MESSAGES/volto.po index b239291..2450348 100644 --- a/locales/fr/LC_MESSAGES/volto.po +++ b/locales/fr/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/it/LC_MESSAGES/volto.po b/locales/it/LC_MESSAGES/volto.po index e376e48..1b26497 100644 --- a/locales/it/LC_MESSAGES/volto.po +++ b/locales/it/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "Inserisci qui il codice OTP ricevuto all'indirizzo {email}" msgid "form_manage_data" msgstr "Gestione dei dati" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "Il codice OTP è stato inviato a {email}. Verifica la tua email e inserisci nel campo sopra il codice OTP ricevuto." + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/ja/LC_MESSAGES/volto.po b/locales/ja/LC_MESSAGES/volto.po index 681ae24..0382415 100644 --- a/locales/ja/LC_MESSAGES/volto.po +++ b/locales/ja/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/nl/LC_MESSAGES/volto.po b/locales/nl/LC_MESSAGES/volto.po index 681ae24..0382415 100644 --- a/locales/nl/LC_MESSAGES/volto.po +++ b/locales/nl/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/pt/LC_MESSAGES/volto.po b/locales/pt/LC_MESSAGES/volto.po index 681ae24..0382415 100644 --- a/locales/pt/LC_MESSAGES/volto.po +++ b/locales/pt/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/pt_BR/LC_MESSAGES/volto.po b/locales/pt_BR/LC_MESSAGES/volto.po index 838a623..ef846d8 100644 --- a/locales/pt_BR/LC_MESSAGES/volto.po +++ b/locales/pt_BR/LC_MESSAGES/volto.po @@ -440,6 +440,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/ro/LC_MESSAGES/volto.po b/locales/ro/LC_MESSAGES/volto.po index 681ae24..0382415 100644 --- a/locales/ro/LC_MESSAGES/volto.po +++ b/locales/ro/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/locales/volto.pot b/locales/volto.pot index d404c32..1d350ca 100644 --- a/locales/volto.pot +++ b/locales/volto.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2024-04-16T09:11:47.457Z\n" +"POT-Creation-Date: 2024-04-16T10:30:04.164Z\n" "Last-Translator: Plone i18n \n" "Language-Team: Plone i18n \n" "MIME-Version: 1.0\n" @@ -436,6 +436,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" diff --git a/src/actions/index.js b/src/actions/index.js index 2929a4a..08d5921 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -94,7 +94,7 @@ export const SEND_OTP = 'SEND_OTP'; export function sendOTP(path, block_id, email) { return { - type: SUBMIT_FORM_ACTION, + type: SEND_OTP, subrequest: block_id + '_' + email, request: { op: 'post', diff --git a/src/components/Widget/OTPWidget.css b/src/components/Widget/OTPWidget.css index 52398da..e49ce40 100644 --- a/src/components/Widget/OTPWidget.css +++ b/src/components/Widget/OTPWidget.css @@ -7,15 +7,25 @@ flex-grow: 1; } -.otp-widget .otp-send-error { - color: #d9364f; - padding: 1rem; - margin: 1rem; - border: 1px solid #d9364f; - width: 100%; - text-align: center; +.otp-widget .otp-alert { + position: relative; + padding: 0.5rem 1rem; + margin-bottom: 1rem; + border: 1px solid #5d7083; + border-left: 8px solid #5d7083; + background-color: #fff; + border-radius: 0; + margin-top: -3rem; + margin-bottom: 3rem; } +.otp-widget .otp-alert.otp-error { + border-left: 8px solid #cc334d; +} + +.otp-widget .otp-alert.otp-success { + border-left: 8px solid #008055; +} @media (max-width: 1024px) { .otp-widget .otp-widget-field-wrapper { flex-direction: column; diff --git a/src/components/Widget/OTPWidget.jsx b/src/components/Widget/OTPWidget.jsx index 2b72170..1abb6f9 100644 --- a/src/components/Widget/OTPWidget.jsx +++ b/src/components/Widget/OTPWidget.jsx @@ -24,6 +24,11 @@ const messages = defineMessages({ id: 'form_insert_otp', defaultMessage: 'Insert here the OTP code received at {email}', }, + otp_sent: { + id: 'form_otp_send', + defaultMessage: + 'OTP code was sent to {email}. Check your email and insert the received OTP code into the field above.', + }, }); const OTPWidget = (props) => { @@ -91,8 +96,14 @@ const OTPWidget = (props) => { />
+ {sendOTPResponse?.loaded && !sendOTPResponse?.loading && ( +
+ {intl.formatMessage(messages.otp_sent, { email: fieldValue })} +
+ )} + {sendOTPResponse?.error && ( -
+
{JSON.stringify(sendOTPResponse.error)}
)} diff --git a/src/reducers/index.js b/src/reducers/index.js index aef4ecc..0dd3aed 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -95,6 +95,7 @@ export const submitForm = (state = initialState, action = {}) => { ...state.subrequests, [action.subrequest]: { ...(state.subrequests[action.subrequest] || {}), + error: action.error, loading: false, loaded: false, }, From fe9f53123a2878ff31c8fa90431b2ee73d90f82d Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Wed, 17 Apr 2024 10:57:08 +0200 Subject: [PATCH 4/6] feat: disable otp send button for 5 minutes --- locales/de/LC_MESSAGES/volto.po | 9 ++++-- locales/en/LC_MESSAGES/volto.po | 9 ++++-- locales/es/LC_MESSAGES/volto.po | 9 ++++-- locales/eu/LC_MESSAGES/volto.po | 9 ++++-- locales/fr/LC_MESSAGES/volto.po | 9 ++++-- locales/it/LC_MESSAGES/volto.po | 9 ++++-- locales/ja/LC_MESSAGES/volto.po | 9 ++++-- locales/nl/LC_MESSAGES/volto.po | 9 ++++-- locales/pt/LC_MESSAGES/volto.po | 9 ++++-- locales/pt_BR/LC_MESSAGES/volto.po | 9 ++++-- locales/ro/LC_MESSAGES/volto.po | 9 ++++-- locales/volto.pot | 11 +++++-- src/components/Widget/OTPWidget.css | 11 +++++++ src/components/Widget/OTPWidget.jsx | 49 ++++++++++++++++++++++++++++- 14 files changed, 144 insertions(+), 26 deletions(-) diff --git a/locales/de/LC_MESSAGES/volto.po b/locales/de/LC_MESSAGES/volto.po index e8c3fbb..0ce947e 100644 --- a/locales/de/LC_MESSAGES/volto.po +++ b/locales/de/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Löschen" @@ -494,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "Beschriftung der Schaltfläche Senden" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Gesendet!" diff --git a/locales/en/LC_MESSAGES/volto.po b/locales/en/LC_MESSAGES/volto.po index 626eaba..c8ea6ce 100644 --- a/locales/en/LC_MESSAGES/volto.po +++ b/locales/en/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Clear" @@ -494,7 +499,7 @@ msgstr "Show cancel button" msgid "form_submit_label" msgstr "Submit button label" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Sent!" diff --git a/locales/es/LC_MESSAGES/volto.po b/locales/es/LC_MESSAGES/volto.po index 18b32e5..bc8363f 100644 --- a/locales/es/LC_MESSAGES/volto.po +++ b/locales/es/LC_MESSAGES/volto.po @@ -443,6 +443,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -458,7 +463,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Borrar" @@ -503,7 +508,7 @@ msgstr "" msgid "form_submit_label" msgstr "Etiqueta del botón de envío" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Enviado" diff --git a/locales/eu/LC_MESSAGES/volto.po b/locales/eu/LC_MESSAGES/volto.po index 83fea09..a81c3bc 100644 --- a/locales/eu/LC_MESSAGES/volto.po +++ b/locales/eu/LC_MESSAGES/volto.po @@ -436,6 +436,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -451,7 +456,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Garbitu" @@ -496,7 +501,7 @@ msgstr "" msgid "form_submit_label" msgstr "Bidalketa botoiaren etiketa" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Bidalita!" diff --git a/locales/fr/LC_MESSAGES/volto.po b/locales/fr/LC_MESSAGES/volto.po index 2450348..6476b07 100644 --- a/locales/fr/LC_MESSAGES/volto.po +++ b/locales/fr/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Dégager" @@ -494,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "Soumettre l'étiquette du bouton" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Expédié!" diff --git a/locales/it/LC_MESSAGES/volto.po b/locales/it/LC_MESSAGES/volto.po index 1b26497..dbbe474 100644 --- a/locales/it/LC_MESSAGES/volto.po +++ b/locales/it/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "Inserisci qui il codice OTP ricevuto all'indirizzo {email}" msgid "form_manage_data" msgstr "Gestione dei dati" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "Puoi inviare un nuovo codice OTP fra" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "Giorni validità" msgid "form_remove_data_after_days_helptext" msgstr "Numero di giorni dopo i quali, i dati dovrebbero essere cancellati" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Indietro" @@ -494,7 +499,7 @@ msgstr "Mostra il bottone annulla" msgid "form_submit_label" msgstr "Testo sul bottone di invio" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Inviato!" diff --git a/locales/ja/LC_MESSAGES/volto.po b/locales/ja/LC_MESSAGES/volto.po index 0382415..d269365 100644 --- a/locales/ja/LC_MESSAGES/volto.po +++ b/locales/ja/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -494,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" diff --git a/locales/nl/LC_MESSAGES/volto.po b/locales/nl/LC_MESSAGES/volto.po index 0382415..d269365 100644 --- a/locales/nl/LC_MESSAGES/volto.po +++ b/locales/nl/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -494,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" diff --git a/locales/pt/LC_MESSAGES/volto.po b/locales/pt/LC_MESSAGES/volto.po index 0382415..d269365 100644 --- a/locales/pt/LC_MESSAGES/volto.po +++ b/locales/pt/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -494,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" diff --git a/locales/pt_BR/LC_MESSAGES/volto.po b/locales/pt_BR/LC_MESSAGES/volto.po index ef846d8..525f73c 100644 --- a/locales/pt_BR/LC_MESSAGES/volto.po +++ b/locales/pt_BR/LC_MESSAGES/volto.po @@ -440,6 +440,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -455,7 +460,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Limpar" @@ -500,7 +505,7 @@ msgstr "" msgid "form_submit_label" msgstr "Texto do botão de enviar" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Enviado!" diff --git a/locales/ro/LC_MESSAGES/volto.po b/locales/ro/LC_MESSAGES/volto.po index 0382415..d269365 100644 --- a/locales/ro/LC_MESSAGES/volto.po +++ b/locales/ro/LC_MESSAGES/volto.po @@ -434,6 +434,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -449,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -494,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" diff --git a/locales/volto.pot b/locales/volto.pot index 1d350ca..334e100 100644 --- a/locales/volto.pot +++ b/locales/volto.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2024-04-16T10:30:04.164Z\n" +"POT-Creation-Date: 2024-04-17T08:56:51.659Z\n" "Last-Translator: Plone i18n \n" "Language-Team: Plone i18n \n" "MIME-Version: 1.0\n" @@ -436,6 +436,11 @@ msgstr "" msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + #: components/Widget/OTPWidget # defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. msgid "form_otp_send" @@ -451,7 +456,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -496,7 +501,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" diff --git a/src/components/Widget/OTPWidget.css b/src/components/Widget/OTPWidget.css index e49ce40..8c4978f 100644 --- a/src/components/Widget/OTPWidget.css +++ b/src/components/Widget/OTPWidget.css @@ -26,6 +26,17 @@ .otp-widget .otp-alert.otp-success { border-left: 8px solid #008055; } + +.otp-widget .otp-widget-field-wrapper .button-wrapper { + display: flex; + flex-direction: column; +} + +.otp-widget .otp-widget-field-wrapper .button-wrapper .otp-button-message { + font-size: 0.8rem; + color: #555555; + text-align: center; +} @media (max-width: 1024px) { .otp-widget .otp-widget-field-wrapper { flex-direction: column; diff --git a/src/components/Widget/OTPWidget.jsx b/src/components/Widget/OTPWidget.jsx index 1abb6f9..f979419 100644 --- a/src/components/Widget/OTPWidget.jsx +++ b/src/components/Widget/OTPWidget.jsx @@ -4,7 +4,7 @@ */ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useIntl, defineMessages } from 'react-intl'; import { isValidEmail } from 'volto-form-block/helpers/validators'; @@ -29,9 +29,25 @@ const messages = defineMessages({ defaultMessage: 'OTP code was sent to {email}. Check your email and insert the received OTP code into the field above.', }, + otp_countdown: { + id: 'form_otp_countdown', + defaultMessage: 'You can send a new OTP code in', + }, }); +const getCountDownValues = (countDown) => { + // calculate time left + const days = Math.floor(countDown / (1000 * 60 * 60 * 24)); + const hours = Math.floor( + (countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), + ); + const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((countDown % (1000 * 60)) / 1000); + + return [days, hours, minutes, seconds]; +}; const OTPWidget = (props) => { + const OTP_EXIPIRE_MINUTES = 5; const { id, title, @@ -52,6 +68,8 @@ const OTPWidget = (props) => { const sendOTPResponse = useSelector( (state) => state.sendOTP?.subrequests?.[block_id + '_' + fieldValue], ); + const [countDownEnd, setCountDownEnd] = useState(null); + const [countDown, setCountDown] = useState(null); const displayWidget = isValidEmail(fieldValue); @@ -59,6 +77,23 @@ const OTPWidget = (props) => { dispatch(sendOTP(path, block_id, fieldValue)); }; + useEffect(() => { + if (sendOTPResponse?.loaded) { + const end = new Date().getTime() + OTP_EXIPIRE_MINUTES * 60000; + setCountDownEnd(end); + setCountDown(end - new Date().getTime()); + + const interval = setInterval(() => { + setCountDown(countDownEnd - new Date().getTime()); + }, 1000); + + return () => clearInterval(interval); + } else { + setCountDown(null); + setCountDownEnd(null); + } + }, [sendOTPResponse, countDownEnd]); + return displayWidget ? (
@@ -73,10 +108,22 @@ const OTPWidget = (props) => { sendOTPCode(); }} className="send-otp-code" + disabled={countDown > 0} > {intl.formatMessage(messages.send_otp_to, { email: fieldValue })} + {countDown > 0 && ( +
+ {intl.formatMessage(messages.otp_countdown)}{' '} + {getCountDownValues(countDown) + .filter((v, index) => v > 0 || index === 2) + .map((v) => (v < 10 ? '0' + v : v)) + .join(':')} + . +
+ )}
+ Date: Wed, 17 Apr 2024 15:16:48 +0200 Subject: [PATCH 5/6] fix: display seconds --- src/components/Widget/OTPWidget.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Widget/OTPWidget.jsx b/src/components/Widget/OTPWidget.jsx index f979419..defa629 100644 --- a/src/components/Widget/OTPWidget.jsx +++ b/src/components/Widget/OTPWidget.jsx @@ -116,7 +116,7 @@ const OTPWidget = (props) => {
{intl.formatMessage(messages.otp_countdown)}{' '} {getCountDownValues(countDown) - .filter((v, index) => v > 0 || index === 2) + .filter((v, index) => v > 0 || index === 2 || index === 3) .map((v) => (v < 10 ? '0' + v : v)) .join(':')} . From 800c84f24748270948022875efa489c15cec1790 Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Thu, 18 Apr 2024 09:37:32 +0200 Subject: [PATCH 6/6] chore: updated README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index cc7a895..fc23c93 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,10 @@ With HCaptcha integration, you also have an additional option in the sidebar in In some test scenarios it's found that the "Passing Threshold" of HCaptcha must be configured as "Auto" to get the best results. In some test cases if one sets the Threshold to "Moderate" HCaptcha starts to fail. +### OTP email validation + +To prevent sending spam emails to users via the email address configured as sender, the 'email' fields type flagged as BCC will require the user to enter an OTP code received at the address entered in the field when user fills out the form. + ## Export With backend support, you can store data submitted from the form.