From ed44d40e690342b540abe82e7a24b304c03005cc Mon Sep 17 00:00:00 2001 From: Linda Paiste Date: Sun, 4 Jun 2023 14:58:14 -0500 Subject: [PATCH] Create and use helper component `FinalFormField` --- client/common/FinalFormField.jsx | 51 ++++++++ client/common/FormField.jsx | 32 +++++ .../modules/User/components/AccountForm.jsx | 111 +++++------------ client/modules/User/components/LoginForm.jsx | 57 +++------ .../User/components/NewPasswordForm.jsx | 57 +++------ .../User/components/ResetPasswordForm.jsx | 32 ++--- client/modules/User/components/SignupForm.jsx | 113 ++++++------------ 7 files changed, 197 insertions(+), 256 deletions(-) create mode 100644 client/common/FinalFormField.jsx create mode 100644 client/common/FormField.jsx diff --git a/client/common/FinalFormField.jsx b/client/common/FinalFormField.jsx new file mode 100644 index 0000000000..74914cc292 --- /dev/null +++ b/client/common/FinalFormField.jsx @@ -0,0 +1,51 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Field } from 'react-final-form'; +import FormField from './FormField'; + +function FinalFormField({ + name, + validate, + validateFields, + initialValue, + ...rest +}) { + return ( + + {(field) => ( + + )} + + ); +} + +FinalFormField.propTypes = { + id: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + ariaLabel: PropTypes.string.isRequired, + type: PropTypes.string.isRequired, + autoComplete: PropTypes.string, + name: PropTypes.string.isRequired, + validate: PropTypes.func, + validateFields: PropTypes.arrayOf(PropTypes.string), + initialValue: PropTypes.string +}; + +FinalFormField.defaultProps = { + autoComplete: undefined, + validate: undefined, + validateFields: undefined, + initialValue: '' +}; + +export default FinalFormField; diff --git a/client/common/FormField.jsx b/client/common/FormField.jsx new file mode 100644 index 0000000000..c0f5d89767 --- /dev/null +++ b/client/common/FormField.jsx @@ -0,0 +1,32 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +function FormField({ id, label, ariaLabel, hasError, error, ...rest }) { + return ( +

+ + + {hasError && {error}} +

+ ); +} + +FormField.propTypes = { + id: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + ariaLabel: PropTypes.string.isRequired, + type: PropTypes.string.isRequired, + autoComplete: PropTypes.string, + hasError: PropTypes.bool, + error: PropTypes.string +}; + +FormField.defaultProps = { + autoComplete: null, + hasError: false, + error: null +}; + +export default FormField; diff --git a/client/modules/User/components/AccountForm.jsx b/client/modules/User/components/AccountForm.jsx index 02578a9ee3..81b7b638ff 100644 --- a/client/modules/User/components/AccountForm.jsx +++ b/client/modules/User/components/AccountForm.jsx @@ -1,8 +1,9 @@ import React from 'react'; -import { Form, Field } from 'react-final-form'; +import { Form } from 'react-final-form'; import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import Button from '../../../common/Button'; +import FinalFormField from '../../../common/FinalFormField'; import { validateSettings } from '../../../utils/reduxFormUtils'; import { updateSettings, initiateVerification } from '../actions'; import apiClient from '../../../utils/apiClient'; @@ -60,30 +61,17 @@ function AccountForm() { handleSubmit(event).then(restart); }} > - - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
+ /> {user.verified !== 'verified' && (

@@ -101,68 +89,33 @@ function AccountForm() { )}

)} - - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
- - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
- - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
+ /> + + diff --git a/client/modules/User/components/LoginForm.jsx b/client/modules/User/components/LoginForm.jsx index 0e45fd85c2..2eadf5a7db 100644 --- a/client/modules/User/components/LoginForm.jsx +++ b/client/modules/User/components/LoginForm.jsx @@ -1,8 +1,9 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { Form, Field } from 'react-final-form'; +import { Form } from 'react-final-form'; import { useDispatch } from 'react-redux'; import Button from '../../../common/Button'; +import FinalFormField from '../../../common/FinalFormField'; import { validateLogin } from '../../../utils/reduxFormUtils'; import { validateAndLoginUser } from '../actions'; @@ -28,44 +29,22 @@ function LoginForm() { modifiedSinceLastSubmit }) => (
- - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
- - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
+ + {submitError && !modifiedSinceLastSubmit && ( {submitError} )} diff --git a/client/modules/User/components/NewPasswordForm.jsx b/client/modules/User/components/NewPasswordForm.jsx index 26af961fc5..434b383ce1 100644 --- a/client/modules/User/components/NewPasswordForm.jsx +++ b/client/modules/User/components/NewPasswordForm.jsx @@ -1,8 +1,9 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { Form, Field } from 'react-final-form'; +import { Form } from 'react-final-form'; import { useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; +import FinalFormField from '../../../common/FinalFormField'; import { validateNewPassword } from '../../../utils/reduxFormUtils'; import { updatePassword } from '../actions'; import Button from '../../../common/Button'; @@ -24,44 +25,22 @@ function NewPasswordForm(props) { > {({ handleSubmit, submitting, invalid, pristine }) => ( - - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
- - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
+ + diff --git a/client/modules/User/components/ResetPasswordForm.jsx b/client/modules/User/components/ResetPasswordForm.jsx index f44e7649bd..d1a5b5c32e 100644 --- a/client/modules/User/components/ResetPasswordForm.jsx +++ b/client/modules/User/components/ResetPasswordForm.jsx @@ -1,12 +1,13 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { Form, Field } from 'react-final-form'; +import { Form } from 'react-final-form'; import { useDispatch, useSelector } from 'react-redux'; +import FinalFormField from '../../../common/FinalFormField'; import { validateResetPassword } from '../../../utils/reduxFormUtils'; import { initiateResetPassword } from '../actions'; import Button from '../../../common/Button'; -function ResetPasswordForm(props) { +function ResetPasswordForm() { const { t } = useTranslation(); const resetPasswordInitiate = useSelector( (state) => state.user.resetPasswordInitiate @@ -25,25 +26,14 @@ function ResetPasswordForm(props) { > {({ handleSubmit, submitting, pristine, invalid }) => ( - - {(field) => ( -

- - - {field.meta.touched && field.meta.error && ( - {field.meta.error} - )} -

- )} -
+