Skip to content

Commit

Permalink
Merge pull request #17472 from Expensify/bondy-login-component-migration
Browse files Browse the repository at this point in the history
Refactor NewContactMethodPage to use hooks
  • Loading branch information
marcaaron authored Apr 25, 2023
2 parents c3a8ad9 + 91e49c9 commit b047ec7
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 90 deletions.
3 changes: 1 addition & 2 deletions src/components/TextInput/baseTextInputPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ const propTypes = {
/** Forward the inner ref */
innerRef: PropTypes.oneOfType([
PropTypes.func,
// eslint-disable-next-line react/forbid-prop-types
PropTypes.shape({current: PropTypes.any}),
PropTypes.object,
]),

/** Maximum characters allowed */
Expand Down
163 changes: 75 additions & 88 deletions src/pages/settings/Profile/Contacts/NewContactMethodPage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, {Component} from 'react';
import React, {
useCallback, useMemo, useRef, useState,
} from 'react';
import PropTypes from 'prop-types';
import {View} from 'react-native';
import {ScrollView} from 'react-native-gesture-handler';
Expand Down Expand Up @@ -52,102 +54,87 @@ const defaultProps = {
loginList: {},
};

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

this.state = {
login: '',
password: '',
};
this.onLoginChange = this.onLoginChange.bind(this);
this.validateForm = this.validateForm.bind(this);
this.submitForm = this.submitForm.bind(this);
}

onLoginChange(login) {
this.setState({login});
}

/**
* Determine whether the form is valid
*
* @returns {Boolean}
*/
validateForm() {
const login = this.state.login.trim();
function NewContactMethodPage(props) {
const [login, setLogin] = useState('');
const [password, setPassword] = useState('');
const loginInputRef = useRef(null);

const handleLoginChange = useCallback((value) => {
setLogin(value.trim());
}, []);

const handlePasswordChange = useCallback((value) => {
setPassword(value.trim());
}, []);

const isFormValid = useMemo(() => {
const phoneLogin = LoginUtils.getPhoneNumberWithoutSpecialChars(login);

return (Permissions.canUsePasswordlessLogins(this.props.betas) || this.state.password)
return (Permissions.canUsePasswordlessLogins(props.betas) || password)
&& (Str.isValidEmail(login) || Str.isValidPhone(phoneLogin));
}

submitForm() {
// Trim leading and trailing space from login
const login = this.state.login.trim();
}, [login, password, props.betas]);

const submitForm = useCallback(() => {
// If this login already exists, just go back.
if (lodashGet(this.props.loginList, login)) {
if (lodashGet(props.loginList, login)) {
Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHODS);
return;
}
User.addNewContactMethodAndNavigate(login, this.state.password);
}

render() {
return (
<ScreenWrapper
onTransitionEnd={() => {
if (!this.loginInputRef) {
return;
}
this.loginInputRef.focus();
}}
>
<HeaderWithCloseButton
title={this.props.translate('contacts.newContactMethod')}
shouldShowBackButton
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHODS)}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<ScrollView>
<Text style={[styles.ph5, styles.mb5]}>
{this.props.translate('common.pleaseEnterEmailOrPhoneNumber')}
</Text>
<View style={[styles.ph5, styles.mb6]}>
<TextInput
label={`${this.props.translate('common.email')}/${this.props.translate('common.phoneNumber')}`}
ref={el => this.loginInputRef = el}
value={this.state.login}
onChangeText={this.onLoginChange}
autoCapitalize="none"
returnKeyType={Permissions.canUsePasswordlessLogins(this.props.betas) ? 'done' : 'next'}
/>
</View>
{!Permissions.canUsePasswordlessLogins(this.props.betas)
&& (
<View style={[styles.ph5, styles.mb6]}>
<TextInput
label={this.props.translate('common.password')}
value={this.state.password}
onChangeText={password => this.setState({password})}
returnKeyType="done"
/>
</View>
)}
</ScrollView>
<FixedFooter style={[styles.flexGrow0]}>
<Button
success
isDisabled={!this.validateForm()}
text={this.props.translate('common.add')}
onPress={this.submitForm}
pressOnEnter
User.addNewContactMethodAndNavigate(login, password);
}, [login, props.loginList, password]);

return (
<ScreenWrapper
onTransitionEnd={() => {
if (!loginInputRef.current) {
return;
}
loginInputRef.current.focus();
}}
>
<HeaderWithCloseButton
title={props.translate('contacts.newContactMethod')}
shouldShowBackButton
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHODS)}
onCloseButtonPress={() => Navigation.dismissModal(true)}
/>
<ScrollView>
<Text style={[styles.ph5, styles.mb5]}>
{props.translate('common.pleaseEnterEmailOrPhoneNumber')}
</Text>
<View style={[styles.ph5, styles.mb6]}>
<TextInput
label={`${props.translate('common.email')}/${props.translate('common.phoneNumber')}`}
ref={loginInputRef}
value={login}
onChangeText={handleLoginChange}
autoCapitalize="none"
returnKeyType={Permissions.canUsePasswordlessLogins(props.betas) ? 'done' : 'next'}
/>
</FixedFooter>
</ScreenWrapper>
);
}
</View>
{!Permissions.canUsePasswordlessLogins(props.betas)
&& (
<View style={[styles.ph5, styles.mb6]}>
<TextInput
label={props.translate('common.password')}
value={password}
onChangeText={handlePasswordChange}
returnKeyType="done"
/>
</View>
)}
</ScrollView>
<FixedFooter style={[styles.flexGrow0]}>
<Button
success
isDisabled={!isFormValid}
text={props.translate('common.add')}
onPress={submitForm}
pressOnEnter
/>
</FixedFooter>
</ScreenWrapper>
);
}

NewContactMethodPage.propTypes = propTypes;
Expand Down

0 comments on commit b047ec7

Please sign in to comment.