2020-04-16 17:39:41 +02:00
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
import { getJSON } from '@utils';
|
|
|
|
import {
|
|
|
|
Combobox,
|
|
|
|
ComboboxInput,
|
|
|
|
ComboboxPopover,
|
|
|
|
ComboboxList,
|
|
|
|
ComboboxOption
|
|
|
|
} from '@reach/combobox';
|
|
|
|
import '@reach/combobox/styles.css';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
|
|
|
|
let cache = {};
|
2020-04-30 15:42:29 +02:00
|
|
|
const useAddressSearch = (searchTerm) => {
|
2020-04-16 17:39:41 +02:00
|
|
|
const [addresses, setAddresses] = useState([]);
|
|
|
|
useEffect(() => {
|
|
|
|
if (searchTerm.trim() !== '') {
|
|
|
|
let isFresh = true;
|
2020-04-30 15:42:29 +02:00
|
|
|
fetchAddresses(searchTerm).then((addresses) => {
|
2020-04-16 17:39:41 +02:00
|
|
|
if (isFresh) setAddresses(addresses);
|
|
|
|
});
|
|
|
|
return () => (isFresh = false);
|
|
|
|
}
|
|
|
|
}, [searchTerm]);
|
|
|
|
return addresses;
|
|
|
|
};
|
|
|
|
|
2020-04-30 15:42:29 +02:00
|
|
|
const fetchAddresses = (value) => {
|
2020-04-16 17:39:41 +02:00
|
|
|
if (cache[value]) {
|
|
|
|
return Promise.resolve(cache[value]);
|
|
|
|
}
|
|
|
|
const url = `https://api-adresse.data.gouv.fr/search/`;
|
2020-04-30 15:42:29 +02:00
|
|
|
return getJSON(url, { q: value, limit: 5 }, 'get').then((result) => {
|
2020-04-16 17:39:41 +02:00
|
|
|
if (result) {
|
|
|
|
cache[value] = result;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const SearchInput = ({ getCoords }) => {
|
|
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
|
|
const addresses = useAddressSearch(searchTerm);
|
2020-04-30 15:42:29 +02:00
|
|
|
const handleSearchTermChange = (event) => {
|
2020-04-16 17:39:41 +02:00
|
|
|
setSearchTerm(event.target.value);
|
|
|
|
};
|
|
|
|
return (
|
|
|
|
<Combobox aria-label="addresses">
|
|
|
|
<ComboboxInput
|
2020-05-07 18:30:19 +02:00
|
|
|
placeholder="Rechercher une adresse : saisissez au moins 2 caractères"
|
2020-04-16 17:39:41 +02:00
|
|
|
className="address-search-input"
|
|
|
|
style={{
|
|
|
|
font: 'inherit',
|
|
|
|
padding: '.25rem .5rem',
|
|
|
|
width: '100%',
|
|
|
|
minHeight: '62px'
|
|
|
|
}}
|
|
|
|
onChange={handleSearchTermChange}
|
|
|
|
/>
|
|
|
|
{addresses.features && (
|
|
|
|
<ComboboxPopover
|
|
|
|
style={{
|
|
|
|
borderTopColor: '#ddd',
|
|
|
|
marginTop: '-1px',
|
|
|
|
boxShadow: '0 2px 4px rgba(0,0,0,.15)',
|
|
|
|
position: 'absolute',
|
|
|
|
width: '400px',
|
|
|
|
left: '351px',
|
|
|
|
top: '5562px'
|
|
|
|
}}
|
|
|
|
className="shadow-popup"
|
|
|
|
>
|
|
|
|
{addresses.features.length > 0 ? (
|
|
|
|
<ComboboxList>
|
2020-04-30 15:42:29 +02:00
|
|
|
{addresses.features.map((feature) => {
|
2020-04-16 17:39:41 +02:00
|
|
|
const str = `${feature.properties.name}, ${feature.properties.city}`;
|
|
|
|
return (
|
|
|
|
<ComboboxOption
|
|
|
|
onClick={() => getCoords(feature.geometry.coordinates)}
|
|
|
|
key={str}
|
|
|
|
value={str}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</ComboboxList>
|
|
|
|
) : (
|
|
|
|
<span style={{ display: 'block', margin: 8 }}>Aucun résultat</span>
|
|
|
|
)}
|
|
|
|
</ComboboxPopover>
|
|
|
|
)}
|
|
|
|
</Combobox>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
SearchInput.propTypes = {
|
|
|
|
getCoords: PropTypes.func
|
|
|
|
};
|
|
|
|
|
|
|
|
export default SearchInput;
|