all repos — caroster @ fe359e3d0bd28293a74106f4ce391f5127bce55f

[Octree] Group carpool to your event https://caroster.io

frontend/containers/PlaceInput/index.tsx (view raw)

 1import {useState} from 'react';
 2import TextField, {TextFieldProps} from '@mui/material/TextField';
 3import InputAdornment from '@mui/material/InputAdornment';
 4import PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined';
 5import Autocomplete from '@mui/material/Autocomplete';
 6import {debounce} from '@mui/material/utils';
 7import {useTranslation} from 'react-i18next';
 8import useLocale from '../../hooks/useLocale';
 9import getPlacesSuggestions from '../../lib/getPlacesSuggestion';
10
11interface Props {
12  place: string;
13  onSelect: ({
14    location,
15    place,
16  }: {
17    location: [number, number];
18    place: string;
19  }) => void;
20  label?: string;
21  textFieldProps?: TextFieldProps;
22}
23
24const PlaceInput = ({
25  place = '',
26  onSelect,
27  label,
28  textFieldProps,
29}: Props) => {
30  const {t} = useTranslation();
31  const {locale} = useLocale();
32
33  const [options, setOptions] = useState([] as Array<any>);
34
35  const onChange = async (e, selectedOption) => {
36    onSelect({
37      place: selectedOption.place_name,
38      location: selectedOption.center,
39    });
40  };
41
42  const updateOptions = debounce(async (e, search: string) => {
43    if (search !== '') {
44      getPlacesSuggestions({search, proximity: 'ip', locale}).then(suggestions => {
45        setOptions(suggestions);
46      });
47    }
48  }, 400);
49
50  return (
51    <Autocomplete
52      freeSolo
53      disableClearable
54      getOptionLabel={option => option.place_name}
55      options={options}
56      autoComplete
57      defaultValue={{place_name: place}}
58      filterOptions={x => x}
59      noOptionsText={t('autocomplete.noMatch')}
60      onChange={onChange}
61      onInputChange={updateOptions}
62      renderInput={params => (
63        <TextField
64          label={label}
65          multiline
66          maxRows={4}
67          InputProps={{
68            endAdornment: (
69              <InputAdornment position="end" sx={{mr: -0.5}}>
70                <PlaceOutlinedIcon />
71              </InputAdornment>
72            ),
73          }}
74          {...params}
75          {...textFieldProps}
76        />
77      )}
78      renderOption={(props, option) => {
79        return <li {...props}>{option.place_name}</li>;
80      }}
81    />
82  );
83};
84
85export default PlaceInput;