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

[CP-stag] Get CompanyAddress field to autofill and show errors #5800

Merged
merged 17 commits into from
Oct 13, 2021
132 changes: 62 additions & 70 deletions src/components/AddressSearch.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'underscore';
import React from 'react';
import React, {useEffect, useRef} from 'react';
import PropTypes from 'prop-types';
import {LogBox} from 'react-native';
import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
Expand Down Expand Up @@ -33,87 +33,79 @@ const defaultProps = {
containerStyles: null,
};

class AddressSearch extends React.Component {
constructor(props) {
super(props);
this.googlePlacesRef = React.createRef();
}
const AddressSearch = (props) => {
const googlePlacesRef = useRef();
useEffect(() => {
googlePlacesRef.current?.setAddressText(props.value);
}, []);

componentDidMount() {
this.googlePlacesRef.current?.setAddressText(this.props.value);
}

getAddressComponent(object, field, nameType) {
// eslint-disable-next-line
const getAddressComponent = (object, field, nameType) => {
return _.chain(object.address_components)
.find(component => _.contains(component.types, field))
.get(nameType)
.value();
}
};

/**
* @param {Object} details See https://developers.google.com/maps/documentation/places/web-service/details#PlaceDetailsResponses
*/
saveLocationDetails = (details) => {
const saveLocationDetails = (details) => {
if (details.address_components) {
// Gather the values from the Google details
const streetNumber = this.getAddressComponent(details, 'street_number', 'long_name');
const streetName = this.getAddressComponent(details, 'route', 'long_name');
const city = this.getAddressComponent(details, 'locality', 'long_name');
const state = this.getAddressComponent(details, 'administrative_area_level_1', 'short_name');
const zipCode = this.getAddressComponent(details, 'postal_code', 'long_name');
const streetNumber = getAddressComponent(details, 'street_number', 'long_name');
const streetName = getAddressComponent(details, 'route', 'long_name');
const city = getAddressComponent(details, 'locality', 'long_name');
const state = getAddressComponent(details, 'administrative_area_level_1', 'short_name');
const zipCode = getAddressComponent(details, 'postal_code', 'long_name');

// Trigger text change events for each of the individual fields being saved on the server
this.props.onChangeText('addressStreet', `${streetNumber} ${streetName}`);
this.props.onChangeText('addressCity', city);
this.props.onChangeText('addressState', state);
this.props.onChangeText('addressZipCode', zipCode);
props.onChangeText('addressStreet', `${streetNumber} ${streetName}`);
props.onChangeText('addressCity', city);
props.onChangeText('addressState', state);
props.onChangeText('addressZipCode', zipCode);
}
}
};

render() {
return (
<GooglePlacesAutocomplete
ref={this.googlePlacesRef}
fetchDetails
keepResultsAfterBlur
suppressDefaultStyles
enablePoweredByContainer={false}
onPress={(data, details) => this.saveLocationDetails(details)}
query={{
key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
language: this.props.preferredLocale,
}}
requestUrl={{
useOnPlatform: 'web',
url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
}}
textInputProps={{
InputComp: ExpensiTextInput,
label: this.props.label,
containerStyles: this.props.containerStyles,
}}
styles={{
textInputContainer: [styles.flexColumn],
listView: [
styles.borderTopRounded,
styles.borderBottomRounded,
styles.mt1,
styles.overflowAuto,
styles.borderLeft,
styles.borderRight,
],
row: [
styles.pv4,
styles.ph3,
styles.overflowAuto,
],
description: [styles.googleSearchText],
separator: [styles.googleSearchSeparator],
}}
/>
);
}
}
return (
<GooglePlacesAutocomplete
ref={googlePlacesRef}
fetchDetails
suppressDefaultStyles
enablePoweredByContainer={false}
onPress={(data, details) => saveLocationDetails(details)}
query={{
key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
language: props.preferredLocale,
}}
requestUrl={{
useOnPlatform: 'web',
url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
}}
textInputProps={{
InputComp: ExpensiTextInput,
label: props.label,
containerStyles: props.containerStyles,
errorText: props.errorText,
}}
styles={{
textInputContainer: [styles.flexColumn],
listView: [
styles.borderTopRounded,
styles.borderBottomRounded,
styles.mt1,
styles.overflowAuto,
styles.borderLeft,
styles.borderRight,
],
row: [
styles.pv4,
styles.ph3,
styles.overflowAuto,
],
description: [styles.googleSearchText],
separator: [styles.googleSearchSeparator],
}}
/>
);
};

AddressSearch.propTypes = propTypes;
AddressSearch.defaultProps = defaultProps;
Expand Down
2 changes: 1 addition & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ export default {
phoneNumber: 'Please enter a valid phone number',
companyName: 'Please enter a valid legal business name',
addressCity: 'Please enter a valid city',
addressStreet: 'Please enter a valid address street that is not a PO Box',
addressStreet: 'Please enter a valid street address that is not a PO Box',
addressState: 'Please select a valid state',
incorporationDate: 'Please enter a valid date',
incorporationState: 'Please enter a valid state',
Expand Down
29 changes: 27 additions & 2 deletions src/pages/ReimbursementAccount/CompanyStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class CompanyStep extends React.Component {
// These fields need to be filled out in order to submit the form
this.requiredFields = [
'companyName',
'addressStreet',
'addressCity',
'addressState',
'addressZipCode',
'website',
'companyTaxID',
'incorporationDate',
Expand All @@ -82,6 +86,10 @@ class CompanyStep extends React.Component {
// Map a field to the key of the error's translation
this.errorTranslationKeys = {
companyName: 'bankAccount.error.companyName',
addressStreet: 'bankAccount.error.addressStreet',
addressCity: 'bankAccount.error.addressCity',
addressState: 'bankAccount.error.addressState',
addressZipCode: 'bankAccount.error.zipCode',
companyPhone: 'bankAccount.error.phoneNumber',
website: 'bankAccount.error.website',
companyTaxID: 'bankAccount.error.taxID',
Expand All @@ -95,6 +103,23 @@ class CompanyStep extends React.Component {
this.getErrors = () => ReimbursementAccountUtils.getErrors(this.props);
}

getFormattedAddressValue() {
let addressString = '';
if (this.state.addressStreet) {
addressString += `${this.state.addressStreet}, `;
}
if (this.state.addressCity) {
addressString += `${this.state.addressCity}, `;
}
if (this.state.addressState) {
addressString += `${this.state.addressState}, `;
}
if (this.state.addressZipCode) {
addressString += `${this.state.addressZipCode}`;
}
return addressString;
}

/**
* @param {String} value
*/
Expand Down Expand Up @@ -183,8 +208,9 @@ class CompanyStep extends React.Component {
<AddressSearch
label={this.props.translate('common.companyAddress')}
containerStyles={[styles.mt4]}
value={`${this.state.addressStreet} ${this.state.addressCity} ${this.state.addressState} ${this.state.addressZipCode}`}
value={this.getFormattedAddressValue()}
onChangeText={(fieldName, value) => this.clearErrorAndSetValue(fieldName, value)}
errorText={this.getErrorText('addressStreet')}
/>
<ExpensiTextInput
label={this.props.translate('common.phoneNumber')}
Expand All @@ -195,7 +221,6 @@ class CompanyStep extends React.Component {
placeholder={this.props.translate('companyStep.companyPhonePlaceholder')}
errorText={this.getErrorText('companyPhone')}
maxLength={CONST.PHONE_MAX_LENGTH}

/>
<ExpensiTextInput
label={this.props.translate('companyStep.companyWebsite')}
Expand Down