diff --git a/packages/peregrine/lib/store/reducers/user.js b/packages/peregrine/lib/store/reducers/user.js index 71bba7561c..30b959b80a 100755 --- a/packages/peregrine/lib/store/reducers/user.js +++ b/packages/peregrine/lib/store/reducers/user.js @@ -19,11 +19,11 @@ const initialState = { }, createAccountError: null, getDetailsError: null, - isCreatingAccount: null, - isGettingDetails: null, - isResettingPassword: null, + isCreatingAccount: false, + isGettingDetails: false, + isResettingPassword: false, isSignedIn: isSignedIn(), - isSigningIn: null, + isSigningIn: false, resetPasswordError: null, signInError: null }; diff --git a/packages/peregrine/lib/talons/CreateAccount/useCreateAccount.js b/packages/peregrine/lib/talons/CreateAccount/useCreateAccount.js new file mode 100644 index 0000000000..930ebce044 --- /dev/null +++ b/packages/peregrine/lib/talons/CreateAccount/useCreateAccount.js @@ -0,0 +1,38 @@ +import { useMemo } from 'react'; +import { useUserContext } from '@magento/peregrine/lib/context/user'; + +/** + * Returns props necessary to render CreateAccount component. + * + * @param {Object} props.initialValues initial values to sanitize and seed the form + * @returns {{ + * hasError: boolean, + * isDisabled: boolean, + * isSignedIn: boolean, + * initialValues: object + * }} + */ +export const useCreateAccount = props => { + const { initialValues = {} } = props; + + const [ + { createAccountError, isCreatingAccount, isSignedIn } + ] = useUserContext(); + const hasError = !!createAccountError; + + const sanitizedInitialValues = useMemo(() => { + const { email, firstName, lastName, ...rest } = initialValues; + + return { + customer: { email, firstname: firstName, lastname: lastName }, + ...rest + }; + }, [initialValues]); + + return { + hasError, + isDisabled: isCreatingAccount, + isSignedIn, + initialValues: sanitizedInitialValues + }; +}; diff --git a/packages/peregrine/lib/talons/CreateAccountPage/useCreateAccountPage.js b/packages/peregrine/lib/talons/CreateAccountPage/useCreateAccountPage.js new file mode 100644 index 0000000000..603d13f79a --- /dev/null +++ b/packages/peregrine/lib/talons/CreateAccountPage/useCreateAccountPage.js @@ -0,0 +1,46 @@ +import { useCallback, useMemo } from 'react'; +import { useUserContext } from '@magento/peregrine/lib/context/user'; + +const validCreateAccountParams = ['email', 'firstName', 'lastName']; + +const getCreateAccountInitialValues = search => { + const params = new URLSearchParams(search); + + return validCreateAccountParams.reduce( + (values, param) => ({ ...values, [param]: params.get(param) }), + {} + ); +}; + +/** + * Returns props necessary to render CreateAccountPage component. + * + * @param {Object} props.history router history object + * @returns {{ + * handleCreateAccount: function, + * initialValues: object + * }} + */ +export const useCreateAccountPage = props => { + const [, { createAccount }] = useUserContext(); + // TODO replace with useHistory in React Router 5.1 + const { history } = props; + + const handleCreateAccount = useCallback( + async accountInfo => { + await createAccount(accountInfo); + history.push('/'); + }, + [createAccount, history] + ); + + const initialValues = useMemo( + () => getCreateAccountInitialValues(window.location.search), + [] + ); + + return { + handleCreateAccount, + initialValues + }; +}; diff --git a/packages/venia-ui/lib/components/CreateAccount/createAccount.js b/packages/venia-ui/lib/components/CreateAccount/createAccount.js index a997d7fb34..e519ffc922 100644 --- a/packages/venia-ui/lib/components/CreateAccount/createAccount.js +++ b/packages/venia-ui/lib/components/CreateAccount/createAccount.js @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React from 'react'; import { Redirect } from '@magento/venia-drivers'; import { func, shape, string } from 'prop-types'; import { Form } from 'informed'; @@ -17,28 +17,17 @@ import { hasLengthAtLeast } from '../../util/formValidators'; import defaultClasses from './createAccount.css'; -import { useUserContext } from '@magento/peregrine/lib/context/user'; +import { useCreateAccount } from '@magento/peregrine/lib/talons/CreateAccount/useCreateAccount'; const LEAD = 'Check out faster, use multiple addresses, track orders and more by creating an account!'; const CreateAccount = props => { - const { initialValues = {}, onSubmit } = props; + const talonProps = useCreateAccount({ + initialValues: props.initialValues + }); - const [ - { createAccountError, isCreatingAccount, isSignedIn } - ] = useUserContext(); - const hasError = !!createAccountError; - - const classes = mergeClasses(defaultClasses, props.classes); - const sanitizedInitialValues = useMemo(() => { - const { email, firstName, lastName, ...rest } = initialValues; - - return { - customer: { email, firstname: firstName, lastname: lastName }, - ...rest - }; - }, [initialValues]); + const { hasError, isDisabled, isSignedIn, initialValues } = talonProps; const errorMessage = hasError ? 'An error occurred. Please try again.' @@ -48,11 +37,13 @@ const CreateAccount = props => { return ; } + const classes = mergeClasses(defaultClasses, props.classes); + return (

{LEAD}

@@ -108,11 +99,7 @@ const CreateAccount = props => {
{errorMessage}
-
diff --git a/packages/venia-ui/lib/components/CreateAccountPage/__tests__/helpers.spec.js b/packages/venia-ui/lib/components/CreateAccountPage/__tests__/helpers.spec.js deleted file mode 100644 index af43a4e471..0000000000 --- a/packages/venia-ui/lib/components/CreateAccountPage/__tests__/helpers.spec.js +++ /dev/null @@ -1,28 +0,0 @@ -import { getCreateAccountInitialValues } from '../helpers'; - -const email = 'roni_cost@example.com'; -const firstName = 'Veronica'; -const lastName = 'Costello'; -const invalidParameter = 'invalid'; - -test('getCreateAccountInitialValues takes initial values from search string', () => { - const search = `?${new URLSearchParams({ email, firstName, lastName })}`; - expect(getCreateAccountInitialValues(search)).toEqual({ - email, - firstName, - lastName - }); -}); - -test('getCreateAccountInitialValues filters values from search string', () => { - const search = `?${new URLSearchParams({ - email, - firstName, - lastName, - invalidParameter - })}`; - - expect(getCreateAccountInitialValues(search)).not.toHaveProperty( - 'invalidParameter' - ); -}); diff --git a/packages/venia-ui/lib/components/CreateAccountPage/createAccountPage.js b/packages/venia-ui/lib/components/CreateAccountPage/createAccountPage.js index 895a937f65..21e4716448 100644 --- a/packages/venia-ui/lib/components/CreateAccountPage/createAccountPage.js +++ b/packages/venia-ui/lib/components/CreateAccountPage/createAccountPage.js @@ -1,31 +1,20 @@ -import React, { useCallback, useMemo } from 'react'; +import React from 'react'; import { shape } from 'prop-types'; import { withRouter } from '@magento/venia-drivers'; import { compose } from 'redux'; import CreateAccountForm from '../CreateAccount'; import { mergeClasses } from '../../classify'; import defaultClasses from './createAccountPage.css'; -import { getCreateAccountInitialValues } from './helpers'; -import { useUserContext } from '@magento/peregrine/lib/context/user'; +import { useCreateAccountPage } from '@magento/peregrine/lib/talons/CreateAccountPage/useCreateAccountPage'; const CreateAccountPage = props => { - const [, { createAccount }] = useUserContext(); - const classes = mergeClasses(defaultClasses, props.classes); - const { history } = props; + const talonProps = useCreateAccountPage({ + history: props.history + }); - const handleCreateAccount = useCallback( - async accountInfo => { - await createAccount(accountInfo); - history.push('/'); - }, - [createAccount, history] - ); - - const initialValues = useMemo( - () => getCreateAccountInitialValues(window.location.search), - [] - ); + const { initialValues, handleCreateAccount } = talonProps; + const classes = mergeClasses(defaultClasses, props.classes); return (
{ - const params = new URLSearchParams(search); - - return validCreateAccountParams.reduce( - (values, param) => ({ ...values, [param]: params.get(param) }), - {} - ); -};