Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor CloseAccountPage to functional component #19328

Merged
merged 26 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
014d239
refactor to functional component
bondydaa May 19, 2023
db0d53e
Merge branch 'main' of github.com:Expensify/App into bondy-refactor-c…
bondydaa May 22, 2023
bd80ad9
remove unused method
bondydaa May 22, 2023
86c0b3f
dont use useCallback here as its most likely not needed
bondydaa May 22, 2023
df15ca0
clean up imports
bondydaa May 22, 2023
ac211e3
Merge branch 'main' of github.com:Expensify/App into bondy-refactor-c…
bondydaa May 25, 2023
270b71c
export default and clean up usage
bondydaa May 25, 2023
5d050a0
fix default error key as defined by Onyx::handleException in web-e
bondydaa May 25, 2023
ba1c8fb
Merge branch 'main' of github.com:Expensify/App into bondy-refactor-c…
bondydaa May 26, 2023
ecbef94
Revert "remove unused method"
bondydaa May 26, 2023
4779d8e
Revert "export default and clean up usage"
bondydaa May 26, 2023
cce3f22
Revert "clean up imports"
bondydaa May 26, 2023
e25a3b1
copy functionality based on lifecycle methods to not change behavior …
bondydaa May 26, 2023
5da45fa
fix default type to stop console error
bondydaa Jun 2, 2023
477631e
remove setting default data on component mount, its not 100% necessary
bondydaa Jun 2, 2023
3830a3e
fix linter
bondydaa Jun 2, 2023
633535b
Merge branch 'main' of github.com:Expensify/App into bondy-refactor-c…
bondydaa Jun 2, 2023
b9069f7
fix styles with prettier
bondydaa Jun 2, 2023
d5d59c2
prevent execution of hook on every re-render by passing empty depeden…
bondydaa Jun 2, 2023
a3ffe91
Merge branch 'main' of github.com:Expensify/App into bondy-refactor-c…
bondydaa Jun 5, 2023
7bcb7a9
initial fix of merge conflicts, doesnt include all changes yet though
bondydaa Jun 27, 2023
d71f54b
apply changes from commit 38e49c372
bondydaa Jun 27, 2023
57a33a4
pull in change from commit b2dda336
bondydaa Jun 27, 2023
3c806f1
pull in changes from commit 1b36c75b17
bondydaa Jun 27, 2023
7bd01cb
pull in changes from commit 3b5e279fe7
bondydaa Jun 27, 2023
15f6982
pull in changes from commit 1e456f6788d1d
bondydaa Jun 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions src/libs/actions/CloseAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@ import Onyx from 'react-native-onyx';
import ONYXKEYS from '../../ONYXKEYS';
import CONST from '../../CONST';

/**
* Clear CloseAccount error message to hide modal
*/
function clearError() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should clear the errors as before because the next time I open the page, the loader is shown on the Close Account button.

Steps.

  1. Go to the close account page.
  2. press the close account button.
  3. See the errors on the page.
  4. Now, Close the page and reopen.

Might be unrelated to this change but exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm you might be right, I noticed at one point in testing but then it went away after I'd reloaded and then I couldn't reproduce. Let me try again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though don't think this method would actually stop the loader from showing since I think that is controlled by the isLoading key that's defined here:

DEFAULT_CLOSE_ACCOUNT_DATA: {error: '', success: '', isLoading: false},

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I noodle on this I think maybe we shouldn't be trying to address this here?

Really these props are all reacted-to by the Form component, this component is sort of just attempting to pass that data down along to it.

The only way to really solve it is to use the useEffect / lifecycle methods that were being used but those don't really make sense to add here since our component doesn't actually depend on them.

If we were to re-implement the lifecycle methods here we'd need useEffect which is just going to set some onyx data to the default because that's what the <Form> component will react to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried again and now this issue is not reproducible as you said.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I think that these errors are backend errors that we were clearing earlier. But I am not sure how to create a backend error so I can't test that.

Onyx.merge(ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM, {errors: null});
}

/**
* Set default Onyx data
*/
Expand All @@ -17,7 +10,5 @@ function setDefaultData() {
}

export {
// eslint-disable-next-line import/prefer-default-export
clearError,
setDefaultData,
};
127 changes: 55 additions & 72 deletions src/pages/settings/Security/CloseAccountPage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, {Component} from 'react';
import React, {
useState,
} from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
Expand All @@ -14,7 +16,6 @@ import TextInput from '../../../components/TextInput';
import Text from '../../../components/Text';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
import * as CloseAccount from '../../../libs/actions/CloseAccount';
import ONYXKEYS from '../../../ONYXKEYS';
import Form from '../../../components/Form';
import CONST from '../../../CONST';
Expand All @@ -37,105 +38,87 @@ const defaultProps = {
},
};

class CloseAccountPage extends Component {
constructor(props) {
super(props);
function CloseAccountPage (props) {
const [isConfirmModalVisible, setConfirmModalVisibility] = useState(false);
const [reasonForLeaving, setReasonForLeaving] = useState('');

this.onConfirm = this.onConfirm.bind(this);
this.validate = this.validate.bind(this);
this.hideConfirmModal = this.hideConfirmModal.bind(this);
this.showConfirmModal = this.showConfirmModal.bind(this);
CloseAccount.clearError();
this.state = {
isConfirmModalVisible: false,
reasonForLeaving: '',
};
}
const hideConfirmModal = () => {
setConfirmModalVisibility(false);
};

componentWillUnmount() {
CloseAccount.clearError();
}
const onConfirm = () => {
User.closeAccount(reasonForLeaving);
hideConfirmModal();
};

onConfirm() {
User.closeAccount(this.state.reasonForLeaving);
this.hideConfirmModal();
}
const showConfirmModal = (values) => {
setConfirmModalVisibility(true);
setReasonForLeaving(values.reasonForLeaving);
};

showConfirmModal(values) {
this.setState({
isConfirmModalVisible: true,
reasonForLeaving: values.reasonForLeaving,
});
}

hideConfirmModal() {
this.setState({isConfirmModalVisible: false});
}

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

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

const userEmailOrPhone = props.formatPhoneNumber(props.session.email);

render() {
const userEmailOrPhone = this.props.formatPhoneNumber(this.props.session.email);
return (
<ScreenWrapper includeSafeAreaPaddingBottom={false}>
<HeaderWithCloseButton
title={this.props.translate('closeAccountPage.closeAccount')}
shouldShowBackButton
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_SECURITY)}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<Form
formID={ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM}
validate={this.validate}
onSubmit={this.showConfirmModal}
submitButtonText={this.props.translate('closeAccountPage.closeAccount')}
style={[styles.flexGrow1, styles.mh5]}
isSubmitActionDangerous
>
<View style={[styles.flexGrow1]}>
<Text>{this.props.translate('closeAccountPage.reasonForLeavingPrompt')}</Text>
return (
<ScreenWrapper includeSafeAreaPaddingBottom={false}>
<HeaderWithCloseButton
title={props.translate('closeAccountPage.closeAccount')}
shouldShowBackButton
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_SECURITY)}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<Form
formID={ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM}
validate={validate}
onSubmit={showConfirmModal}
submitButtonText={props.translate('closeAccountPage.closeAccount')}
style={[styles.flexGrow1, styles.mh5]}
isSubmitActionDangerous
>
<View style={[styles.flexGrow1]}>
<Text>{props.translate('closeAccountPage.reasonForLeavingPrompt')}</Text>
<TextInput
inputID="reasonForLeaving"
multiline
numberOfLines={6}
textAlignVertical="top"
label={this.props.translate('closeAccountPage.enterMessageHere')}
label={props.translate('closeAccountPage.enterMessageHere')}
containerStyles={[styles.mt5, styles.closeAccountMessageInput]}
/>
<Text style={[styles.mt5]}>
{this.props.translate('closeAccountPage.enterDefaultContactToConfirm')} <Text style={[styles.textStrong]}>{userEmailOrPhone}</Text>.
{props.translate('closeAccountPage.enterDefaultContactToConfirm')} <Text style={[styles.textStrong]}>{userEmailOrPhone}</Text>.
</Text>
<TextInput
inputID="phoneOrEmail"
autoCapitalize="none"
label={this.props.translate('closeAccountPage.enterDefaultContact')}
label={props.translate('closeAccountPage.enterDefaultContact')}
containerStyles={[styles.mt5]}
autoCorrect={false}
keyboardType={CONST.KEYBOARD_TYPE.EMAIL_ADDRESS}
/>
<ConfirmModal
title={this.props.translate('closeAccountPage.closeAccountWarning')}
onConfirm={this.onConfirm}
onCancel={this.hideConfirmModal}
isVisible={this.state.isConfirmModalVisible}
prompt={this.props.translate('closeAccountPage.closeAccountPermanentlyDeleteData')}
confirmText={this.props.translate('common.yes')}
cancelText={this.props.translate('common.cancel')}
title={props.translate('closeAccountPage.closeAccountWarning')}
onConfirm={onConfirm}
onCancel={hideConfirmModal}
isVisible={isConfirmModalVisible}
prompt={props.translate('closeAccountPage.closeAccountPermanentlyDeleteData')}
confirmText={props.translate('common.yes')}
cancelText={props.translate('common.cancel')}
shouldShowCancelButton
/>
</View>
</Form>
</ScreenWrapper>
);
}
</View>
</Form>
</ScreenWrapper>
);
}

CloseAccountPage.propTypes = propTypes;
Expand Down