From 9369baf308b448435051583a43d24acc03c93597 Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Wed, 21 Mar 2018 13:11:13 -0500 Subject: [PATCH] fix(createWalletPassword): refactor component to be stateless. use selector to show error on non matching passwords and not allow user to continue until passwords are matching --- .../Onboarding/NewWalletPassword.js | 45 ++++++++----------- .../Onboarding/NewWalletPassword.scss | 11 +++++ app/components/Onboarding/Onboarding.js | 7 ++- app/containers/Root.js | 8 +++- app/reducers/onboarding.js | 18 ++++++-- 5 files changed, 56 insertions(+), 33 deletions(-) diff --git a/app/components/Onboarding/NewWalletPassword.js b/app/components/Onboarding/NewWalletPassword.js index 1ab89d19..b530b2e9 100644 --- a/app/components/Onboarding/NewWalletPassword.js +++ b/app/components/Onboarding/NewWalletPassword.js @@ -4,31 +4,19 @@ import Isvg from 'react-inlinesvg' import eye from 'icons/eye.svg' import styles from './NewWalletPassword.scss' -class NewWalletPassword extends React.Component { - constructor(props) { - super(props) - - this.state = { - inputType: 'password', - confirmPassword: '' - } - } - - render() { - const { createWalletPassword, updateCreateWalletPassword } = this.props - const { inputType, confirmPassword } = this.state - - const toggleInputType = () => { - const newInputType = inputType === 'password' ? 'text' : 'password' - - this.setState({ inputType: newInputType }) - } - +const NewWalletPassword = ({ + createWalletPassword, + createWalletPasswordConfirmation, + showCreateWalletPasswordConfirmationError, + + updateCreateWalletPassword, + updateCreateWalletPasswordConfirmation +}) => { return (
this.setState({ confirmPassword: event.target.value })} + className={`${styles.password} ${showCreateWalletPasswordConfirmationError && styles.error}`} + value={createWalletPasswordConfirmation} + onChange={event => updateCreateWalletPasswordConfirmation(event.target.value)} /> +

Passwords do not match

) - } } NewWalletPassword.propTypes = { createWalletPassword: PropTypes.string.isRequired, - updateCreateWalletPassword: PropTypes.func.isRequired + createWalletPasswordConfirmation: PropTypes.string.isRequired, + showCreateWalletPasswordConfirmationError: PropTypes.bool.isRequired, + updateCreateWalletPassword: PropTypes.func.isRequired, + updateCreateWalletPasswordConfirmation: PropTypes.func.isRequired } export default NewWalletPassword diff --git a/app/components/Onboarding/NewWalletPassword.scss b/app/components/Onboarding/NewWalletPassword.scss index 1fd5fd6f..66aa30c5 100644 --- a/app/components/Onboarding/NewWalletPassword.scss +++ b/app/components/Onboarding/NewWalletPassword.scss @@ -22,3 +22,14 @@ text-shadow: none; -webkit-text-fill-color: initial; } + +.errorMessage { + color: $red; + margin-top: 10px; + font-size: 10px; + visibility: hidden; + + &.visible { + visibility: visible; + } +} diff --git a/app/components/Onboarding/Onboarding.js b/app/components/Onboarding/Onboarding.js index 631a721b..273d2781 100644 --- a/app/components/Onboarding/Onboarding.js +++ b/app/components/Onboarding/Onboarding.js @@ -78,7 +78,12 @@ const Onboarding = ({ title='Welcome!' description='Looks like you are new here. Set a password to encrypt your wallet. This password will be needed to unlock Zap in the future' // eslint-disable-line back={null} - next={() => changeStep(5)} + next={() => { + // dont allow the user to move on if the confirmation password doesnt match the original password + if (newWalletPasswordProps.showCreateWalletPasswordConfirmationError) { return } + + changeStep(5) + }} > diff --git a/app/containers/Root.js b/app/containers/Root.js index b5bffa74..d0d9f40d 100644 --- a/app/containers/Root.js +++ b/app/containers/Root.js @@ -15,6 +15,7 @@ import { startLnd, createWallet, updateCreateWalletPassword, + updateCreateWalletPasswordConfirmation, updateAezeedPassword, submitNewWallet, onboardingSelectors, @@ -30,6 +31,7 @@ const mapDispatchToProps = { updateAlias, updatePassword, updateCreateWalletPassword, + updateCreateWalletPasswordConfirmation, updateAezeedPassword, setAutopilot, changeStep, @@ -50,6 +52,7 @@ const mapStateToProps = state => ({ syncPercentage: lndSelectors.syncPercentage(state), passwordIsValid: onboardingSelectors.passwordIsValid(state), + showCreateWalletPasswordConfirmationError: onboardingSelectors.showCreateWalletPasswordConfirmationError(state), reEnterSeedChecker: onboardingSelectors.reEnterSeedChecker(state) }) @@ -98,7 +101,10 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { const newWalletPasswordProps = { createWalletPassword: stateProps.onboarding.createWalletPassword, - updateCreateWalletPassword: dispatchProps.updateCreateWalletPassword + createWalletPasswordConfirmation: stateProps.onboarding.createWalletPasswordConfirmation, + showCreateWalletPasswordConfirmationError: stateProps.showCreateWalletPasswordConfirmationError, + updateCreateWalletPassword: dispatchProps.updateCreateWalletPassword, + updateCreateWalletPasswordConfirmation: dispatchProps.updateCreateWalletPasswordConfirmation } const newAezeedPasswordProps = { diff --git a/app/reducers/onboarding.js b/app/reducers/onboarding.js index 73f64f16..36921f67 100644 --- a/app/reducers/onboarding.js +++ b/app/reducers/onboarding.js @@ -57,10 +57,10 @@ export function updateCreateWalletPassword(createWalletPassword) { } } -export function updateCreateWalletPasswordConfirmation(updateCreateWalletPasswordConfirmation) { +export function updateCreateWalletPasswordConfirmation(createWalletPasswordConfirmation) { return { type: UPDATE_CREATE_WALLET_PASSWORD_CONFIRMATION, - updateCreateWalletPasswordConfirmation + createWalletPasswordConfirmation } } @@ -172,7 +172,7 @@ const ACTION_HANDLERS = { [UPDATE_ALIAS]: (state, { alias }) => ({ ...state, alias }), [UPDATE_PASSWORD]: (state, { password }) => ({ ...state, password }), [UPDATE_CREATE_WALLET_PASSWORD]: (state, { createWalletPassword }) => ({ ...state, createWalletPassword }), - [UPDATE_CREATE_WALLET_PASSWORD_CONFIRMATION]: (state, { createWalletConfirmation }) => ({ ...state, createWalletConfirmation }), + [UPDATE_CREATE_WALLET_PASSWORD_CONFIRMATION]: (state, { createWalletPasswordConfirmation }) => ({ ...state, createWalletPasswordConfirmation }), [UPDATE_AEZEED_PASSWORD]: (state, { aezeedPassword }) => ({ ...state, aezeedPassword }), [UPDATE_SEED_INPUT]: (state, { inputSeedObj }) => { return { @@ -206,6 +206,10 @@ const ACTION_HANDLERS = { const onboardingSelectors = {} const passwordSelector = state => state.onboarding.password + +const createWalletPasswordSelector = state => state.onboarding.createWalletPassword +const createWalletPasswordConfirmationSelector = state => state.onboarding.createWalletPasswordConfirmation + const seedSelector = state => state.onboarding.seed const seedInputSelector = state => state.onboarding.seedInput @@ -214,6 +218,12 @@ onboardingSelectors.passwordIsValid = createSelector( password => password.length >= 8 ) +onboardingSelectors.showCreateWalletPasswordConfirmationError = createSelector( + createWalletPasswordSelector, + createWalletPasswordConfirmationSelector, + (pass1, pass2) => pass1 !== pass2 && pass2.length > 0 +) + onboardingSelectors.reEnterSeedChecker = createSelector( seedSelector, seedInputSelector, @@ -238,7 +248,7 @@ const initialState = { // wallet password. password used to encrypt the wallet and is required to unlock the daemon after set createWalletPassword: '', - createWalletConfirmation: '', + createWalletPasswordConfirmation: '', creatingNewWallet: false, // seed password. this is optional and used to encrypt the seed