import { useState } from '@wordpress/element';
|
import { TextControl, Spinner, Button } from '@wordpress/components';
|
import apiFetch from '@wordpress/api-fetch';
|
import { useDebounce } from '@wordpress/compose';
|
|
const LocationField = ({field, value, onChange }) => {
|
const address = value || {};
|
|
const [query, setQuery] = useState(address.address || '');
|
const [results, setResults] = useState([]);
|
const [loading, setLoading] = useState(false);
|
|
const search = useDebounce((search) => {
|
if (!search) return setResults([]);
|
setLoading(true);
|
|
apiFetch({path: `jvb/v1/geocode?q=${encodeURIComponent(search)}`})
|
.then(setResults)
|
.finally(()=>setLoading(false));
|
|
}, 400);
|
|
const onSelect = (result) => {
|
const a = result.address || {};
|
|
const newAddress = {
|
address: [a.house_number, a.road].filter(Boolean).join(' '),
|
city: a.city||a.town||a.village||'',
|
province: a.state || '',
|
postal_code:a.postcode||'',
|
country: a.country||'',
|
lat: parseFloat(result.lat),
|
lng: parseFloat(result.lng),
|
};
|
onChange(newAddress);
|
setQuery(newAddress.address);
|
setResults([]);
|
};
|
|
const onClear = () => {
|
onChange({});
|
setQuery('');
|
setResults([]);
|
}
|
|
return (
|
<div className="jvb-location-field" id={field.name}>
|
<TextControl
|
label={field.label}
|
value={query}
|
onChange={(newQuery) => {
|
setQuery(newQuery);
|
search(newQuery)
|
}}
|
/>
|
{loading && <Spinner />}
|
{!!results.length && (
|
<div className="jvb-location-results">
|
{results.map((result) => (
|
|
<Button
|
key={result.place_id}
|
variant="tertiary"
|
onClick={()=>onSelect(result)}
|
style={{display:'block', textAlign:'left'}}
|
>
|
{result.display_name}
|
</Button>
|
))}
|
{!!address.lat && (
|
<p className="jvb-location-summary">
|
{address.address}, {address.city}, {address.province}{' '}
|
{address.postal_code}, {address.country}
|
<br />
|
<Button variant="link" isDestructive onClick={onClear}>Clear</Button>
|
</p>
|
)}
|
</div>
|
)}
|
</div>
|
);
|
};
|
|
export default LocationField;
|