UNPKG

@plone/volto

Version:
227 lines (210 loc) 6.73 kB
/** * PasswordReset component. * @module components/theme/PasswordReset/PasswordReset */ import { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { Link, useHistory, useParams } from 'react-router-dom'; import Helmet from '@plone/volto/helpers/Helmet/Helmet'; import { Container } from 'semantic-ui-react'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { Form } from '@plone/volto/components/manage/Form'; import { setInitialPassword } from '@plone/volto/actions/users/users'; import config from '@plone/volto/registry'; const messages = defineMessages({ title: { id: 'Set your password', defaultMessage: 'Set your password', }, description: { id: 'Please fill out the form below to set your password.', defaultMessage: 'Please fill out the form below to set your password.', }, default: { id: 'Default', defaultMessage: 'Default', }, usernameTitle: { id: 'My username is', defaultMessage: 'My user name is', }, emailTitle: { id: 'My email is', defaultMessage: 'My email is', }, usernameDescription: { id: 'Enter your username for verification.', defaultMessage: 'Enter your username for verification.', }, emailDescription: { id: 'Enter your email for verification.', defaultMessage: 'Enter your email for verification.', }, passwordTitle: { id: 'New password', defaultMessage: 'New password', }, passwordDescription: { id: 'Enter your new password. Minimum 8 characters.', defaultMessage: 'Enter your new password. Minimum 8 characters.', }, passwordRepeatTitle: { id: 'Confirm password', defaultMessage: 'Confirm password', }, passwordsDoNotMatch: { id: 'Passwords do not match.', defaultMessage: 'Passwords do not match.', }, mailDoNotMatch: { id: 'E-mail addresses do not match.', defaultMessage: 'E-mail addresses do not match.', }, passwordRepeatDescription: { id: 'Re-enter the password. Make sure the passwords are identical.', defaultMessage: 'Re-enter the password. Make sure the passwords are identical.', }, setMyPassword: { id: 'Set my password', defaultMessage: 'Set my password', }, successRedirectToLoginTitle: { id: 'Account activation completed', defaultMessage: 'Account activation completed', }, successRedirectToLoginBody: { id: 'Your password has been set successfully. You may now {link} with your new password.', defaultMessage: 'Your password has been set successfully. You may now {link} with your new password.', }, passwordReset: { id: 'Password reset', defaultMessage: 'Password reset', }, }); /** * @function PasswordReset * @returns {JSX.Element} */ function PasswordReset() { const dispatch = useDispatch(); const history = useHistory(); const { token } = useParams(); const loading = useSelector((state) => state.users.initial.loading); const loaded = useSelector((state) => state.users.initial.loaded); const error = useSelector((state) => state.users.initial.error); const [localError, setLocalError] = useState(null); const [isSuccessful, setIsSuccessful] = useState(false); const intl = useIntl(); const identifierField = config.settings.useEmailAsLogin ? 'email' : 'username'; const identifierTitle = identifierField === 'email' ? intl.formatMessage(messages.emailTitle) : intl.formatMessage(messages.usernameTitle); const identifierDescription = identifierField === 'email' ? intl.formatMessage(messages.emailDescription) : intl.formatMessage(messages.usernameDescription); useEffect(() => { if (!loading && loaded) { setIsSuccessful(true); } }, [loading, loaded]); /** * Submit handler * @method onSubmit * @param {object} data Form data. * @returns {undefined} */ const onSubmit = (data) => { if (data.password === data.passwordRepeat) { dispatch(setInitialPassword(data[identifierField], token, data.password)); setLocalError(null); } else { setLocalError({ message: intl.formatMessage(messages.passwordsDoNotMatch), }); } }; /** * Cancel handler * @method onCancel * @returns {undefined} */ const onCancel = () => { history.goBack(); }; if (isSuccessful) { return ( <Container> <h1 className="documentFirstHeading"> <FormattedMessage {...messages.successRedirectToLoginTitle} /> </h1> <p className="description"> <FormattedMessage {...messages.successRedirectToLoginBody} values={{ link: ( <Link to="/login">{intl.formatMessage({ id: 'Log In' })}</Link> ), }} /> </p> </Container> ); } if (token) { const errmsg = error ? error.response?.body?.error || error : null; return ( <div id="page-password-reset"> <Helmet title={intl.formatMessage(messages.passwordReset)} /> <Container> <Form title={intl.formatMessage(messages.title)} description={intl.formatMessage(messages.description)} onSubmit={onSubmit} onCancel={onCancel} error={localError || errmsg} schema={{ fieldsets: [ { id: 'default', title: intl.formatMessage(messages.default), fields: [identifierField, 'password', 'passwordRepeat'], }, ], properties: { [identifierField]: { type: 'string', title: identifierTitle, description: identifierDescription, }, password: { description: intl.formatMessage(messages.passwordDescription), title: intl.formatMessage(messages.passwordTitle), type: 'string', widget: 'password', }, passwordRepeat: { description: intl.formatMessage( messages.passwordRepeatDescription, ), title: intl.formatMessage(messages.passwordRepeatTitle), type: 'string', widget: 'password', }, }, submitLabel: intl.formatMessage(messages.setMyPassword), required: [identifierField, 'password', 'passwordRepeat'], }} /> </Container> </div> ); } return <div />; } export default PasswordReset;