Skip to content

Commit

Permalink
Merge pull request #12534 from Puneet-here/form-refactor-close-accoun…
Browse files Browse the repository at this point in the history
…t-page

Refactor close account page to use Form
  • Loading branch information
Beamanator authored Nov 18, 2022
2 parents e1fceb3 + 003391b commit 46c1c7b
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 101 deletions.
4 changes: 1 addition & 3 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,6 @@ export default {
// Is Keyboard shortcuts modal open?
IS_SHORTCUTS_MODAL_OPEN: 'isShortcutsModalOpen',

// Data related to user closing their account (loading status and error message)
CLOSE_ACCOUNT: 'closeAccount',

// Stores information about active wallet transfer amount, selectedAccountID, status, etc
WALLET_TRANSFER: 'walletTransfer',

Expand All @@ -173,6 +170,7 @@ export default {
REQUEST_CALL_FORM: 'requestCallForm',
REIMBURSEMENT_ACCOUNT_FORM: 'reimbursementAccount',
WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
CLOSE_ACCOUNT_FORM: 'closeAccount',
PROFILE_SETTINGS_FORM: 'profileSettingsForm',
DISPLAY_NAME_FORM: 'displayNameForm',
},
Expand Down
5 changes: 5 additions & 0 deletions src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ const propTypes = {
/** Should the button be enabled when offline */
enabledWhenOffline: PropTypes.bool,

/** Whether the action is dangerous */
isDangerousAction: PropTypes.bool,

...withLocalizePropTypes,
};

Expand All @@ -59,6 +62,7 @@ const defaultProps = {
},
draftValues: {},
enabledWhenOffline: false,
isDangerousAction: false,
};

class Form extends React.Component {
Expand Down Expand Up @@ -233,6 +237,7 @@ class Form extends React.Component {
}}
containerStyles={[styles.mh0, styles.mt5]}
enabledWhenOffline={this.props.enabledWhenOffline}
isDangerousAction={this.props.isDangerousAction}
/>
)}
</View>
Expand Down
6 changes: 6 additions & 0 deletions src/components/FormAlertWithSubmitButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const propTypes = {

/** Should the button be enabled when offline */
enabledWhenOffline: PropTypes.bool,

/** Whether the action is dangerous */
isDangerousAction: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -45,6 +48,7 @@ const defaultProps = {
isLoading: false,
onFixTheErrorsLinkPressed: () => {},
enabledWhenOffline: false,
isDangerousAction: false,
};

const FormAlertWithSubmitButton = props => (
Expand All @@ -61,6 +65,7 @@ const FormAlertWithSubmitButton = props => (
isDisabled
text={props.buttonText}
style={[styles.mb3]}
danger={props.isDangerousAction}
/>
) : (
<Button
Expand All @@ -70,6 +75,7 @@ const FormAlertWithSubmitButton = props => (
onPress={props.onSubmit}
isDisabled={props.isDisabled}
isLoading={props.isLoading}
danger={props.isDangerousAction}
/>
))}
</FormAlertWrapper>
Expand Down
5 changes: 1 addition & 4 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,9 @@ export default {
enterMessageHere: 'Enter message here',
closeAccountWarning: 'Closing your account cannot be undone.',
closeAccountPermanentlyDeleteData: 'This will permanently delete all of your unsubmitted expense data. Type your phone number or email address to confirm.',
closeAccountActionRequired: 'Looks like you need to complete some actions before closing your account. Check out the guide',
closeAccountTryAgainAfter: 'and try again after.',
enterDefaultContact: 'Enter your default contact method',
defaultContact: 'Default contact method:',
okayGotIt: 'Okay, Got it',
closeAccountError: 'Unable to close account',
enterYourDefaultContactMethod: 'Please enter your default contact method to close your account.',
},
passwordPage: {
changePassword: 'Change password',
Expand Down
23 changes: 10 additions & 13 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,9 @@ export default {
enterMessageHere: 'Ingresa el mensaje aquí',
closeAccountWarning: 'Una vez cerrada tu cuenta no se puede revertir.',
closeAccountPermanentlyDeleteData: 'Esta acción eliminará permanentemente toda la información de tus gastos no enviados. Escribe tu número de teléfono o correo electrónico para confirmar',
closeAccountActionRequired: 'Parece que necesitas completar algunas acciones antes de cerrar tu cuenta. Mira la guía',
closeAccountTryAgainAfter: 'e intenta nuevamente',
enterDefaultContact: 'Tu método de contacto predeterminado',
defaultContact: 'Método de contacto predeterminado:',
okayGotIt: 'Ok, entendido',
closeAccountError: 'No se pudo cerrar tu cuenta',
enterYourDefaultContactMethod: 'Por favor ingresa tu método de contacto predeterminado para cerrar tu cuenta.',
},
passwordPage: {
changePassword: 'Cambiar contraseña',
Expand Down Expand Up @@ -420,16 +417,16 @@ export default {
growlMessageOnSave: 'Su tarteja de débito se agregó correctamente',
expensifyPassword: 'Contraseña de Expensify',
error: {
invalidName: 'Por favor ingrese un nombre válido',
addressZipCode: 'Por favor ingrese un código postal válido',
debitCardNumber: 'Ingrese un número de tarjeta de débito válido',
invalidName: 'Por favor ingresa un nombre válido',
addressZipCode: 'Por favor ingresa un código postal válido',
debitCardNumber: 'Ingresa un número de tarjeta de débito válido',
expirationDate: 'Por favor introduzca una fecha de vencimiento válida',
securityCode: 'Ingrese un código de seguridad válido',
addressStreet: 'Ingrese una dirección de facturación válida que no sea un apartado postal',
securityCode: 'Ingresa un código de seguridad válido',
addressStreet: 'Ingresa una dirección de facturación válida que no sea un apartado postal',
addressState: 'Por favor seleccione un estado',
addressCity: 'Por favor ingrese una ciudad',
addressCity: 'Por favor ingresa una ciudad',
genericFailureMessage: 'Se produjo un error al agregar su tarjeta. Vuelva a intentarlo',
password: 'Por favor ingrese tu contraseña de Expensify',
password: 'Por favor ingresa tu contraseña de Expensify',
},
},
paymentsPage: {
Expand Down Expand Up @@ -510,7 +507,7 @@ export default {
pleaseFillOutAllFields: 'Por favor completa todos los campos',
pleaseFillPassword: 'Por favor, introduce tu contraseña',
pleaseFillTwoFactorAuth: 'Por favor, introduce tu código 2 factores',
enterYourTwoFactorAuthenticationCodeToContinue: 'Ingrese su código de autenticación de dos factores para continuar',
enterYourTwoFactorAuthenticationCodeToContinue: 'Ingresa su código de autenticación de dos factores para continuar',
forgot: '¿Te has olvidado?',
twoFactorCode: 'Autenticación de 2 factores',
requiredWhen2FAEnabled: 'Obligatorio cuando A2F está habilitado',
Expand Down Expand Up @@ -787,7 +784,7 @@ export default {
buttonText: 'Finalizar configuración',
maxAttemptsReached: 'Se ha inhabilitado la validación de esta cuenta bancaria, debido a demasiados intentos incorrectos.',
description: 'Uno o dos días después de agregar su cuenta a Expensify, enviamos tres (3) transacciones a su cuenta. Tienen una línea comercial como "Expensify, Inc. Validation".',
descriptionCTA: 'Ingrese el monto de cada transacción en los campos a continuación. Ejemplo: 1.51.',
descriptionCTA: 'Ingresa el monto de cada transacción en los campos a continuación. Ejemplo: 1.51.',
reviewingInfo: '¡Gracias! Estamos revisando tu información y nos comunicaremos contigo en breve. Consulte su chat con Concierge ',
forNextSteps: ' para conocer los próximos pasos para terminar de configurar su cuenta bancaria.',
letsChatCTA: 'Sí, vamos a chatear',
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/CloseAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import CONST from '../../CONST';
* Clear CloseAccount error message to hide modal
*/
function clearError() {
Onyx.merge(ONYXKEYS.CLOSE_ACCOUNT, {error: ''});
Onyx.merge(ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM, {error: ''});
}

/**
* Set default Onyx data
*/
function setDefaultData() {
Onyx.merge(ONYXKEYS.CLOSE_ACCOUNT, {...CONST.DEFAULT_CLOSE_ACCOUNT_DATA});
Onyx.merge(ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM, {...CONST.DEFAULT_CLOSE_ACCOUNT_DATA});
}

export {
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ function closeAccount(message) {
optimisticData: [
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.CLOSE_ACCOUNT,
key: ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM,
value: {isLoading: true},
},
],
failureData: [
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.CLOSE_ACCOUNT,
key: ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM,
value: {isLoading: false},
},
],
Expand Down
110 changes: 34 additions & 76 deletions src/pages/settings/Security/CloseAccountPage.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, {Component} from 'react';
import {Linking, ScrollView, View} from 'react-native';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import Str from 'expensify-common/lib/str';
import _ from 'underscore';
import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton';
import Navigation from '../../../libs/Navigation/Navigation';
import ROUTES from '../../../ROUTES';
Expand All @@ -11,54 +12,49 @@ import compose from '../../../libs/compose';
import styles from '../../../styles/styles';
import ScreenWrapper from '../../../components/ScreenWrapper';
import TextInput from '../../../components/TextInput';
import Button from '../../../components/Button';
import Text from '../../../components/Text';
import ConfirmModal from '../../../components/ConfirmModal';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
import * as CloseAccount from '../../../libs/actions/CloseAccount';
import ONYXKEYS from '../../../ONYXKEYS';
import OfflineIndicator from '../../../components/OfflineIndicator';
import {withNetwork} from '../../../components/OnyxProvider';
import networkPropTypes from '../../../components/networkPropTypes';
import Form from '../../../components/Form';

const propTypes = {
/** Onyx Props */

/** Data from when user attempts to close their account */
closeAccount: PropTypes.shape({
/** Error message if previous attempt to close account was unsuccessful */
error: PropTypes.string,

/** Is account currently being closed? */
isLoading: PropTypes.bool,
}),

/** Session of currently logged in user */
session: PropTypes.shape({
/** Email address */
email: PropTypes.string.isRequired,
}).isRequired,

/** Information about the network */
network: networkPropTypes.isRequired,

...windowDimensionsPropTypes,
...withLocalizePropTypes,
};

const defaultProps = {
closeAccount: {error: '', isLoading: false},
};

class CloseAccountPage extends Component {
constructor(props) {
super(props);

this.state = {
reasonForLeaving: '',
phoneOrEmail: '',
};
this.onSubmit = this.onSubmit.bind(this);
this.validate = this.validate.bind(this);
CloseAccount.clearError();
}

componentWillUnmount() {
CloseAccount.clearError();
}

onSubmit(values) {
User.closeAccount(values.reasonForLeaving);
}

validate(values) {
const userEmailOrPhone = Str.removeSMSDomain(this.props.session.email);
const errors = {};

if (_.isEmpty(values.phoneOrEmail) || userEmailOrPhone.toLowerCase() !== values.phoneOrEmail.toLowerCase()) {
errors.phoneOrEmail = this.props.translate('closeAccountPage.enterYourDefaultContactMethod');
}
return errors;
}

render() {
Expand All @@ -71,21 +67,21 @@ class CloseAccountPage extends Component {
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_SECURITY)}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<ScrollView
contentContainerStyle={[
styles.flexGrow1,
styles.flexColumn,
styles.p5,
]}
<Form
formID={ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM}
validate={this.validate}
onSubmit={this.onSubmit}
submitButtonText={this.props.translate('closeAccountPage.closeAccount')}
style={[styles.flexGrow1, styles.mh5]}
isDangerousAction
>
<View style={[styles.flexGrow1]}>
<Text>{this.props.translate('closeAccountPage.reasonForLeavingPrompt')}</Text>
<TextInput
inputID="reasonForLeaving"
multiline
numberOfLines={6}
textAlignVertical="top"
value={this.state.reasonForLeaving}
onChangeText={reasonForLeaving => this.setState({reasonForLeaving})}
label={this.props.translate('closeAccountPage.enterMessageHere')}
containerStyles={[styles.mt5, styles.closeAccountMessageInput]}
/>
Expand All @@ -104,62 +100,24 @@ class CloseAccountPage extends Component {
{userEmailOrPhone}
</Text>
<TextInput
inputID="phoneOrEmail"
autoCapitalize="none"
value={this.state.phoneOrEmail}
onChangeText={phoneOrEmail => this.setState({phoneOrEmail: phoneOrEmail.toLowerCase()})}
label={this.props.translate('closeAccountPage.enterDefaultContact')}
containerStyles={[styles.mt5]}
/>
</View>
<Button
danger
text={this.props.translate('closeAccountPage.closeAccount')}
isLoading={this.props.closeAccount.isLoading}
onPress={() => User.closeAccount(this.state.reasonForLeaving)}
isDisabled={Str.removeSMSDomain(userEmailOrPhone).toLowerCase() !== this.state.phoneOrEmail.toLowerCase() || this.props.network.isOffline}
style={[styles.mt5]}
/>
{!this.props.isSmallScreenWidth
&& <OfflineIndicator containerStyles={[styles.mt2]} />}
</ScrollView>
<ConfirmModal
title={this.props.translate('closeAccountPage.closeAccountError')}
success
confirmText={this.props.translate('closeAccountPage.okayGotIt')}
prompt={(
<Text>
{this.props.translate('closeAccountPage.closeAccountActionRequired')}
{' '}
<Text
style={styles.link}
onPress={() => { Linking.openURL('https://community.expensify.com/discussion/4724/faq-why-cant-i-close-my-account'); }}
>
{this.props.translate('common.here')}
</Text>
{' '}
{this.props.translate('closeAccountPage.closeAccountTryAgainAfter')}
</Text>
)}
onConfirm={CloseAccount.clearError}
isVisible={Boolean(this.props.closeAccount.error)}
shouldShowCancelButton={false}
/>
</Form>
</ScreenWrapper>
);
}
}

CloseAccountPage.propTypes = propTypes;
CloseAccountPage.defaultProps = defaultProps;

export default compose(
withLocalize,
withWindowDimensions,
withNetwork(),
withOnyx({
closeAccount: {
key: ONYXKEYS.CLOSE_ACCOUNT,
},
session: {
key: ONYXKEYS.SESSION,
},
Expand Down
2 changes: 1 addition & 1 deletion src/pages/signin/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ LoginForm.defaultProps = defaultProps;
export default compose(
withOnyx({
account: {key: ONYXKEYS.ACCOUNT},
closeAccount: {key: ONYXKEYS.CLOSE_ACCOUNT},
closeAccount: {key: ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM},
}),
withWindowDimensions,
withLocalize,
Expand Down

0 comments on commit 46c1c7b

Please sign in to comment.