Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Local Pickup: merge country and state into same field in location modal #8408

Merged
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
*/
import { __ } from '@wordpress/i18n';
import { SelectControl, TextControl } from '@wordpress/components';
import { getSetting } from '@woocommerce/settings';

/**
* Internal dependencies
*/
import type { PickupLocation } from '../types';
import StateControl from './state-control';
import { countryStateOptions, states } from '../utils';

const Form = ( {
formRef,
Expand All @@ -20,11 +19,7 @@ const Form = ( {
values: PickupLocation;
setValues: React.Dispatch< React.SetStateAction< PickupLocation > >;
} ) => {
const countries = getSetting< Record< string, string > >( 'countries', [] );
const states = getSetting< Record< string, Record< string, string > > >(
'countryStates',
[]
);
const { country: selectedCountry, state: selectedState } = values.address;
const setLocationField =
( field: keyof PickupLocation ) => ( newValue: string | boolean ) => {
setValues( ( prevValue: PickupLocation ) => ( {
Expand All @@ -45,6 +40,10 @@ const Form = ( {
} ) );
};

const countryHasStates =
states[ selectedCountry ] &&
Object.keys( states[ selectedCountry ] ).length > 0;

return (
<form ref={ formRef }>
<TextControl
Expand Down Expand Up @@ -97,42 +96,77 @@ const Form = ( {
onChange={ setLocationAddressField( 'postcode' ) }
autoComplete="off"
/>
<StateControl
label={ __( 'State', 'woo-gutenberg-products-block' ) }
name={ 'location_state' }
hideLabelFromVision={ true }
placeholder={ __( 'State', 'woo-gutenberg-products-block' ) }
value={ values.address.state }
onChange={ setLocationAddressField( 'state' ) }
autoComplete="off"
states={ states }
currentCountry={ values.address.country }
/>
{ ! countryHasStates && (
<TextControl
placeholder={ __(
'State',
'woo-gutenberg-products-block'
) }
value={ selectedState }
onChange={ setLocationAddressField( 'state' ) }
/>
) }
<SelectControl
label={ __( 'Country', 'woo-gutenberg-products-block' ) }
name={ 'location_country' }
name="location_country_state"
label={ __(
'Country / State',
'woo-gutenberg-products-block'
) }
hideLabelFromVision={ true }
placeholder={ __( 'Country', 'woo-gutenberg-products-block' ) }
value={ values.address.country }
placeholder={ __(
'Country / State',
'woo-gutenberg-products-block'
) }
value={ ( () => {
if ( ! selectedState && countryHasStates ) {
return `${ selectedCountry }:${
Object.keys( states[ selectedCountry ] )[ 0 ]
}`;
}

return `${ selectedCountry }${
selectedState &&
states[ selectedCountry ]?.[ selectedState ]
? ':' + selectedState
: ''
}`;
} )() }
onChange={ ( val: string ) => {
setLocationAddressField( 'state' )( '' );
setLocationAddressField( 'country' )( val );
const [ country, state = '' ] = val.split( ':' );
setLocationAddressField( 'country' )( country );
setLocationAddressField( 'state' )( state );
} }
autoComplete="off"
options={ [
{
value: '',
disabled: true,
label: __( 'Country', 'woo-gutenberg-products-block' ),
},
...Object.entries( countries ).map(
( [ code, country ] ) => ( {
value: code,
label: country,
} )
),
] }
/>
>
{ countryStateOptions.options.map( ( option ) => {
if ( option.label ) {
return (
<optgroup
key={ option.label }
label={ option.label }
>
{ option.options.map( ( subOption ) => (
<option
key={ subOption.value }
value={ subOption.value }
>
{ subOption.label }
</option>
) ) }
</optgroup>
);
}

return (
<option
key={ option.options[ 0 ].value }
value={ option.options[ 0 ].value }
>
{ option.options[ 0 ].label }
</option>
);
} ) }
</SelectControl>

<TextControl
label={ __( 'Pickup details', 'woo-gutenberg-products-block' ) }
name={ 'pickup_details' }
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import type { UniqueIdentifier } from '@dnd-kit/core';
import { isObject, isBoolean } from '@woocommerce/types';
import { isBoolean } from '@woocommerce/types';
import { ToggleControl, Button, ExternalLink } from '@wordpress/components';
import styled from '@emotion/styled';

Expand All @@ -19,6 +19,7 @@ import {
import EditLocation from './edit-location';
import type { SortablePickupLocation } from './types';
import { useSettingsContext } from './settings-context';
import { getUserFriendlyAddress } from './utils';

const LocationSettingsDescription = () => (
<>
Expand Down Expand Up @@ -62,10 +63,7 @@ const LocationSettings = () => {
<>
{ row.name }
<StyledAddress>
{ isObject( row.address ) &&
Object.values( row.address )
.filter( ( value ) => value !== '' )
.join( ', ' ) }
{ getUserFriendlyAddress( row.address ) }
</StyledAddress>
</>
),
Expand Down Expand Up @@ -137,7 +135,7 @@ const LocationSettings = () => {
address: {
address_1: '',
city: '',
state: '',
state: readOnlySettings.storeState,
postcode: '',
country: readOnlySettings.storeCountry,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type ShippingMethodSettings = {

export type ReadOnlySettings = {
storeCountry: string;
storeState: string;
hasLegacyPickup: boolean;
};

Expand Down
60 changes: 60 additions & 0 deletions assets/js/extensions/shipping-methods/pickup-location/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/
import { cleanForSlug } from '@wordpress/url';
import { __ } from '@wordpress/i18n';
import { isObject } from '@woocommerce/types';
import { getSetting } from '@woocommerce/settings';
/**
* Internal dependencies
*/
Expand Down Expand Up @@ -33,6 +35,7 @@ export const defaultSettings = {
export const defaultReadyOnlySettings = {
hasLegacyPickup: false,
storeCountry: '',
storeState: '',
};
declare global {
const hydratedScreenSettings: {
Expand Down Expand Up @@ -65,3 +68,60 @@ export const getInitialPickupLocations = (): SortablePickupLocation[] =>

export const readOnlySettings =
hydratedScreenSettings.readonlySettings || defaultReadyOnlySettings;

export const countries = getSetting< Record< string, string > >(
'countries',
[]
);
export const states = getSetting< Record< string, Record< string, string > > >(
'countryStates',
[]
);
export const getUserFriendlyAddress = ( address: unknown ) => {
const updatedAddress = isObject( address ) && {
...address,
country:
typeof address.country === 'string' && countries[ address.country ],
state:
typeof address.country === 'string' &&
typeof address.state === 'string' &&
states[ address.country ]?.[ address.state ]
? states[ address.country ][ address.state ]
: address.state,
};

return Object.values( updatedAddress )
.filter( ( value ) => value !== '' )
.join( ', ' );
};

// Outputs the list of countries and states in a single dropdown select.
const countryStateDropdownOptions = () => {
const countryStateOptions = Object.keys( countries ).map( ( country ) => {
const countryStates = states[ country ] || {};

if ( Object.keys( countryStates ).length === 0 ) {
return {
options: [
{
value: country,
label: countries[ country ],
},
],
};
}

const stateOptions = Object.keys( countryStates ).map( ( state ) => ( {
value: `${ country }:${ state }`,
label: `${ countries[ country ] } — ${ countryStates[ state ] }`,
} ) );
return {
label: countries[ country ],
options: [ ...stateOptions ],
};
} );
return {
options: countryStateOptions,
};
};
export const countryStateOptions = countryStateDropdownOptions();
1 change: 1 addition & 0 deletions src/Shipping/ShippingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ public function hydrate_client_settings() {
'readonlySettings' => array(
'hasLegacyPickup' => $has_legacy_pickup,
'storeCountry' => WC()->countries->get_base_country(),
'storeState' => WC()->countries->get_base_state(),
),
);

Expand Down