2020-03-03 10:46:53 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import PropTypes from 'prop-types';
|
2020-03-23 11:22:00 +00:00
|
|
|
import { ValidatedTextInput } from '@woocommerce/base-components/text-input';
|
2020-03-04 15:13:38 +00:00
|
|
|
import {
|
|
|
|
BillingCountryInput,
|
|
|
|
ShippingCountryInput,
|
|
|
|
} from '@woocommerce/base-components/country-input';
|
|
|
|
import {
|
|
|
|
BillingStateInput,
|
|
|
|
ShippingStateInput,
|
|
|
|
} from '@woocommerce/base-components/state-input';
|
2020-03-17 11:45:33 +00:00
|
|
|
import { useValidationContext } from '@woocommerce/base-context';
|
|
|
|
import { useEffect } from '@wordpress/element';
|
|
|
|
import { __ } from '@wordpress/i18n';
|
2020-03-03 10:46:53 +00:00
|
|
|
|
2020-03-09 14:23:16 +00:00
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import defaultAddressFields from './default-address-fields';
|
|
|
|
import countryAddressFields from './country-address-fields';
|
2020-03-03 10:46:53 +00:00
|
|
|
|
2020-03-23 11:22:00 +00:00
|
|
|
// If it's the shipping address form and the user starts entering address
|
|
|
|
// values without having set the country first, show an error.
|
|
|
|
const validateShippingCountry = (
|
2020-03-17 11:45:33 +00:00
|
|
|
values,
|
|
|
|
setValidationErrors,
|
|
|
|
clearValidationError,
|
|
|
|
hasValidationError
|
|
|
|
) => {
|
|
|
|
if (
|
|
|
|
! hasValidationError &&
|
|
|
|
! values.country &&
|
2020-03-23 11:22:00 +00:00
|
|
|
( values.city || values.state || values.postcode )
|
2020-03-17 11:45:33 +00:00
|
|
|
) {
|
|
|
|
setValidationErrors( {
|
2020-03-23 11:22:00 +00:00
|
|
|
'shipping-missing-country': {
|
|
|
|
message: __(
|
|
|
|
'Please select a country to calculate rates.',
|
|
|
|
'woo-gutenberg-products-block'
|
|
|
|
),
|
|
|
|
hidden: false,
|
|
|
|
},
|
2020-03-17 11:45:33 +00:00
|
|
|
} );
|
|
|
|
}
|
|
|
|
if ( hasValidationError && values.country ) {
|
2020-03-23 11:22:00 +00:00
|
|
|
clearValidationError( 'shipping-missing-country' );
|
2020-03-17 11:45:33 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-03-09 14:23:16 +00:00
|
|
|
/**
|
|
|
|
* Checkout address form.
|
|
|
|
*/
|
2020-03-03 10:46:53 +00:00
|
|
|
const AddressForm = ( {
|
2020-03-09 14:23:16 +00:00
|
|
|
fields = Object.keys( defaultAddressFields ),
|
|
|
|
fieldConfig = {},
|
2020-03-03 10:46:53 +00:00
|
|
|
onChange,
|
2020-03-04 15:13:38 +00:00
|
|
|
type = 'shipping',
|
2020-03-03 10:46:53 +00:00
|
|
|
values,
|
|
|
|
} ) => {
|
2020-03-17 11:45:33 +00:00
|
|
|
const {
|
|
|
|
getValidationError,
|
|
|
|
setValidationErrors,
|
|
|
|
clearValidationError,
|
|
|
|
} = useValidationContext();
|
2020-03-09 14:23:16 +00:00
|
|
|
const countryLocale = countryAddressFields[ values.country ] || {};
|
2020-03-03 10:46:53 +00:00
|
|
|
const addressFields = fields.map( ( field ) => ( {
|
|
|
|
key: field,
|
2020-03-09 14:23:16 +00:00
|
|
|
...defaultAddressFields[ field ],
|
|
|
|
...countryLocale[ field ],
|
2020-03-23 11:22:00 +00:00
|
|
|
...fieldConfig[ field ],
|
2020-03-03 10:46:53 +00:00
|
|
|
} ) );
|
|
|
|
const sortedAddressFields = addressFields.sort(
|
2020-03-09 14:23:16 +00:00
|
|
|
( a, b ) => a.index - b.index
|
2020-03-03 10:46:53 +00:00
|
|
|
);
|
2020-03-23 11:22:00 +00:00
|
|
|
const countryValidationError =
|
|
|
|
getValidationError( 'shipping-missing-country' ) || {};
|
2020-03-17 11:45:33 +00:00
|
|
|
useEffect( () => {
|
2020-03-23 11:22:00 +00:00
|
|
|
if ( type === 'shipping' ) {
|
|
|
|
validateShippingCountry(
|
|
|
|
values,
|
|
|
|
setValidationErrors,
|
|
|
|
clearValidationError,
|
|
|
|
countryValidationError.message &&
|
|
|
|
! countryValidationError.hidden
|
|
|
|
);
|
|
|
|
}
|
2020-03-17 11:45:33 +00:00
|
|
|
}, [
|
|
|
|
values,
|
|
|
|
countryValidationError,
|
|
|
|
setValidationErrors,
|
|
|
|
clearValidationError,
|
|
|
|
] );
|
2020-03-03 10:46:53 +00:00
|
|
|
return (
|
|
|
|
<div className="wc-block-address-form">
|
2020-03-09 14:23:16 +00:00
|
|
|
{ sortedAddressFields.map( ( field ) => {
|
|
|
|
if ( field.hidden ) {
|
2020-03-03 10:46:53 +00:00
|
|
|
return null;
|
|
|
|
}
|
2020-03-05 13:06:47 +00:00
|
|
|
|
2020-03-09 14:23:16 +00:00
|
|
|
if ( field.key === 'country' ) {
|
2020-03-04 15:13:38 +00:00
|
|
|
const Tag =
|
|
|
|
type === 'shipping'
|
|
|
|
? ShippingCountryInput
|
|
|
|
: BillingCountryInput;
|
2020-03-03 10:46:53 +00:00
|
|
|
return (
|
2020-03-04 15:13:38 +00:00
|
|
|
<Tag
|
2020-03-09 14:23:16 +00:00
|
|
|
key={ field.key }
|
|
|
|
label={
|
|
|
|
field.required
|
|
|
|
? field.label
|
|
|
|
: field.optionalLabel
|
|
|
|
}
|
2020-03-03 10:46:53 +00:00
|
|
|
value={ values.country }
|
2020-03-09 14:23:16 +00:00
|
|
|
autoComplete={ field.autocomplete }
|
2020-03-03 10:46:53 +00:00
|
|
|
onChange={ ( newValue ) =>
|
|
|
|
onChange( {
|
|
|
|
...values,
|
|
|
|
country: newValue,
|
|
|
|
state: '',
|
2020-03-13 19:04:03 +00:00
|
|
|
city: '',
|
|
|
|
postcode: '',
|
2020-03-03 10:46:53 +00:00
|
|
|
} )
|
|
|
|
}
|
2020-03-23 11:22:00 +00:00
|
|
|
errorId={
|
|
|
|
type === 'shipping'
|
|
|
|
? 'shipping-missing-country'
|
|
|
|
: null
|
|
|
|
}
|
|
|
|
errorMessage={ field.errorMessage }
|
2020-03-09 14:23:16 +00:00
|
|
|
required={ field.required }
|
2020-03-03 10:46:53 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
2020-03-05 13:06:47 +00:00
|
|
|
|
2020-03-09 14:23:16 +00:00
|
|
|
if ( field.key === 'state' ) {
|
2020-03-04 15:13:38 +00:00
|
|
|
const Tag =
|
|
|
|
type === 'shipping'
|
|
|
|
? ShippingStateInput
|
|
|
|
: BillingStateInput;
|
2020-03-03 10:46:53 +00:00
|
|
|
return (
|
2020-03-04 15:13:38 +00:00
|
|
|
<Tag
|
2020-03-09 14:23:16 +00:00
|
|
|
key={ field.key }
|
2020-03-03 10:46:53 +00:00
|
|
|
country={ values.country }
|
2020-03-09 14:23:16 +00:00
|
|
|
label={
|
|
|
|
field.required
|
|
|
|
? field.label
|
|
|
|
: field.optionalLabel
|
|
|
|
}
|
2020-03-03 10:46:53 +00:00
|
|
|
value={ values.state }
|
2020-03-09 14:23:16 +00:00
|
|
|
autoComplete={ field.autocomplete }
|
2020-03-03 10:46:53 +00:00
|
|
|
onChange={ ( newValue ) =>
|
|
|
|
onChange( {
|
|
|
|
...values,
|
|
|
|
state: newValue,
|
|
|
|
} )
|
|
|
|
}
|
2020-03-23 11:22:00 +00:00
|
|
|
errorMessage={ field.errorMessage }
|
2020-03-09 14:23:16 +00:00
|
|
|
required={ field.required }
|
2020-03-03 10:46:53 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
2020-03-05 13:06:47 +00:00
|
|
|
|
2020-03-03 10:46:53 +00:00
|
|
|
return (
|
2020-03-23 11:22:00 +00:00
|
|
|
<ValidatedTextInput
|
2020-03-09 14:23:16 +00:00
|
|
|
key={ field.key }
|
|
|
|
className={ `wc-block-address-form__${ field.key }` }
|
|
|
|
label={
|
|
|
|
field.required ? field.label : field.optionalLabel
|
|
|
|
}
|
|
|
|
value={ values[ field.key ] }
|
|
|
|
autoComplete={ field.autocomplete }
|
2020-03-03 10:46:53 +00:00
|
|
|
onChange={ ( newValue ) =>
|
|
|
|
onChange( {
|
|
|
|
...values,
|
2020-03-09 14:23:16 +00:00
|
|
|
[ field.key ]: newValue,
|
2020-03-03 10:46:53 +00:00
|
|
|
} )
|
|
|
|
}
|
2020-03-23 11:22:00 +00:00
|
|
|
errorMessage={ field.errorMessage }
|
2020-03-09 14:23:16 +00:00
|
|
|
required={ field.required }
|
2020-03-03 10:46:53 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
} ) }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
AddressForm.propTypes = {
|
|
|
|
onChange: PropTypes.func.isRequired,
|
|
|
|
values: PropTypes.object.isRequired,
|
2020-03-05 13:06:47 +00:00
|
|
|
fields: PropTypes.arrayOf(
|
2020-03-09 14:23:16 +00:00
|
|
|
PropTypes.oneOf( Object.keys( defaultAddressFields ) )
|
2020-03-05 13:06:47 +00:00
|
|
|
),
|
|
|
|
fieldConfig: PropTypes.object,
|
2020-03-04 15:13:38 +00:00
|
|
|
type: PropTypes.oneOf( [ 'billing', 'shipping' ] ),
|
2020-03-03 10:46:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
export default AddressForm;
|