@fanam-pkg/core-utils
Version:
Core Functions are managed here for quick web development
118 lines (107 loc) • 3.81 kB
text/typescript
import {useState, useEffect} from "react"
import {AutocompletePrediction, IDecodedAddress} from "../model"
import {useMaps} from "./maps"
const searchTimer: NodeJS.Timeout | null = null
export const useMapAutoComplete = (decodedAddress?: IDecodedAddress) => {
const [searchText, setSearchText] = useState("")
const [predictions, setPredictions] = useState<AutocompletePrediction[]>([])
const [addressData, setAddressData] = useState<IDecodedAddress>(
decodedAddress || {
subLocality: "",
city: "",
state: "",
pinCode: "",
country: "",
latitude: 0,
longitude: 0,
}
)
const {getPlacesPredictions, getCurrentLocationData, reverseGeoCode, geocoding, maps, mapCore} = useMaps()
const {latitude = 0, longitude = 0} = addressData
useEffect(() => {
if (searchText.length >= 3) {
if (searchTimer) clearTimeout(searchTimer)
setTimeout(() => getPlacesPredictions(searchText, setPredictions), 50)
} else {
setPredictions([])
if (searchTimer) {
clearTimeout(searchTimer)
}
}
}, [searchText])
useEffect(() => {
try {
const element = document.getElementById("map") as HTMLElement
const markerElement = document.getElementById("marker-element") as HTMLElement
if (maps && mapCore && element && markerElement) {
const {LatLng, event} = mapCore
const {Map} = maps
const mapOptions = {
zoom: 18,
minZoom: 18,
maxZoom: 18,
panControl: false,
mapTypeControl: false,
streetViewControl: false,
center: new LatLng(latitude, longitude),
disableDefaultUI: false,
scrollWheel: true,
draggable: true,
zoomControl: false,
fullscreenControl: false,
}
const map = new Map(element, mapOptions)
// element.appendChild(markerElement)
const handleMapDrag = async () => {
const position = map.getCenter()
if (position) {
const addressData = await reverseGeoCode(position.lat(), position.lng())
if (addressData) {
setAddressData(addressData)
}
}
}
const dragListener = event.addListener(map, "dragend", handleMapDrag)
const zoomListener = event.addListener(map, "zoom_changed", handleMapDrag)
return () => {
dragListener.remove()
zoomListener.remove()
}
}
} catch (error) {
console.error(">>>>>>>>>>>>> Google Map Loading Error: ", error)
}
}, [maps, latitude, longitude])
const fetchCurrentLocation = (onSelect: (locationData: IDecodedAddress | null) => void) => {
getCurrentLocationData(locationData => {
onSelect(locationData)
if (locationData) setAddressData(locationData)
})
}
const onClickPlace = async (
{place_id, structured_formatting}: AutocompletePrediction,
onDecoded?: (locationData: IDecodedAddress) => void
) => {
if (place_id && geocoding) {
const geoCoder = new geocoding.Geocoder()
const {results} = await geoCoder.geocode({placeId: place_id})
if (results.length) {
const {lat, lng} = results[0].geometry.location
let locationData = await reverseGeoCode(lat(), lng())
if (locationData) {
locationData = {...locationData, subLocality: structured_formatting.main_text}
setAddressData(locationData)
if (onDecoded) onDecoded(locationData)
}
}
}
}
return {
predictions,
onClickPlace,
fetchCurrentLocation,
onChangeSearch: setSearchText,
searchText,
addressData,
}
}