import React, { FC, ReactElement, useState, useEffect } from 'react'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import ClearRounded from '@mui/icons-material/ClearRounded'; import MyLocation from '@mui/icons-material/MyLocation'; import TextField from '@mui/material/TextField'; import ReactGoogleMapLoader from 'react-google-maps-loader'; import ReactGooglePlacesSuggest from 'react-google-places-suggest'; import { STXGoogleMapsLocationPickerProps, MapsProps, MapAutocompletionRequestOptions, ReactGooglePlacesSuggestProps, LatLng, } from './types'; import { MapComponent, determineAddressFromLocation, } from './google-maps-utils'; const ButtonDetermineLocation = ({ mapsProps, setDeterminedLocation, onError, }: { mapsProps: MapsProps; setDeterminedLocation: any; onError: any; }): ReactElement => { const { determiningPositionText, geoLocationUnsupportedText, locationErrorText, } = mapsProps; const determineLocation = () => { if (!navigator.geolocation) { setDeterminedLocation( undefined, geoLocationUnsupportedText || 'Geolocation wird von Ihrem Browser nicht unterstützt.' ); } else { setDeterminedLocation( undefined, determiningPositionText || 'Ermittle Standort...' ); navigator.geolocation.getCurrentPosition( (position) => { setDeterminedLocation({ lat: position.coords.latitude, lng: position.coords.longitude, }); }, () => { setDeterminedLocation(undefined); onError( locationErrorText || 'Position kann nicht bestimmt werden. Bitte aktivieren Sie die Ortungsdienste für diesen Browser in den Telefoneinstellungen oder geben Sie die Adresse manuell ein.' ); } ); } }; return ( ); }; const InputLocation = ({ initialValue, googleMaps, mapsProps, mapAutocompletionRequestOptions, setDeterminedLocation, reactGooglePlacesSuggestProps, error, setError, }: { initialValue: string | undefined; googleMaps: any; mapsProps: MapsProps; mapAutocompletionRequestOptions: MapAutocompletionRequestOptions; reactGooglePlacesSuggestProps: ReactGooglePlacesSuggestProps; setDeterminedLocation: any; error: any; setError: any; }): ReactElement => { const [search, setSearch] = useState(''); const [value, setValue] = useState(''); const { placeholderText, inputLabel } = mapsProps; const { minChars, autocompletionRequestOptions } = mapAutocompletionRequestOptions; useEffect(() => { setSearch(''); setValue(initialValue || ''); }, [initialValue]); const handleChange = (e: any) => { if (value.length >= (minChars || 3)) { setSearch(e.target.value); // minimum of 3 chars need to be entered } setValue(e.target.value); if (!!error) setError(undefined); }; // does not work: const handleChangeDebounced = useMemo(() => debounce(handleChange, 300), [handleChange]); const handleSelectSuggest = ( geocodedPrediction: any /*, originalPrediction: any*/ ) => { setSearch(''); setValue(geocodedPrediction.formatted_address); setDeterminedLocation(geocodedPrediction.geometry.location); }; /* only triggered when enter key is pressed */ const handleNoResult = () => {}; const handleStatusUpdate = (/*status: string*/) => {}; const clearValue = () => { setSearch(''); setValue(initialValue || ''); setDeterminedLocation(''); setError(undefined); }; return ( ( <> {prediction && ( {prediction.description} )} {!prediction && ( {reactGooglePlacesSuggestProps.textNoResults || 'No results found.'} )} > )} {...reactGooglePlacesSuggestProps} > ); }; // Please do not use types off of a default export module or else Storybook Docs will suffer. // see: https://github.com/storybookjs/storybook/issues/9556 /** * Sensotix Google Maps Location Picker */ export const STXGoogleMapsLocationPicker: FC = ({ mapsProps, mapOptions, mapAutocompletionRequestOptions, gridMapProps, reactGooglePlacesSuggestProps, initialValue, initialLatLng, onChange, }): ReactElement | null => { const initialCenter = initialLatLng?.lat && initialLatLng?.lng ? { lat: initialLatLng?.lat, lng: initialLatLng?.lng } : undefined; const [center, setCenter] = useState< google.maps.LatLng | google.maps.LatLngLiteral | undefined | null >(initialCenter); const [location, setLocation] = useState(initialValue); const [error, setError] = useState(undefined); if (!mapsProps.apiKey) { setError( 'Error: Please provide a Google Places API Key in mapsProps.apiKey.' ); return null; } if (!gridMapProps.width || !gridMapProps.height) { setError( 'Error: Please provide both gridMapProps.width and gridMapProps.height.' ); return null; } const setDeterminedLocation = async ( latLng: google.maps.LatLng | undefined ) => { setCenter(latLng); const address = !!latLng ? await determineAddressFromLocation(latLng) : undefined; setLocation(address); }; const handleMapClick = async (latLng: google.maps.LatLng) => { setCenter(latLng); const address = await determineAddressFromLocation(latLng); setLocation(address); }; // call the provided onChange hook on every change useEffect(() => { if (!!window.google?.maps) { const latLng: LatLng = { lat: center instanceof google.maps.LatLng ? center.lat() : center?.lat, lng: center instanceof google.maps.LatLng ? center.lng() : center?.lng, }; !!onChange && onChange(location, latLng); } }, [location]); return ( googleMaps ? ( {/*Show a custom error if SDK Authentication Error. See N/B 2 below.*/} {renderError && render Error} {!renderError && ( )} {!!center && ( )} ) : ( {/*Check for network error so loading state ends if user lost connection.*/} {error === 'Network Error' ? ( {mapsProps.statusFailureText} ) : ( {mapsProps.statusLoadingText} )} ) } /> ); }; export * from './types';
{mapsProps.statusFailureText}
{mapsProps.statusLoadingText}