UNPKG

@fanam-pkg/core-utils

Version:

Core Functions are managed here for quick web development

158 lines (137 loc) 4.75 kB
import {useState, useEffect} from "react" import {Loader} from "@googlemaps/js-api-loader" import { AutocompletePrediction, CoreLibrary, GeocoderAddressComponent, GeocodingLibrary, IDecodedAddress, MapsLibrary, PlacesLibrary, } from "../model" export const useMaps = () => { const loader = new Loader({ apiKey: process.env.NEXT_PUBLIC_GOOGLE_API_KEY || "", libraries: ["maps", "places", "geocoding", "core"], }) const [maps, setMaps] = useState<MapsLibrary | null>(null) const [places, setPlaces] = useState<PlacesLibrary | null>(null) const [geocoding, setGeocoding] = useState<GeocodingLibrary | null>(null) const [mapCore, setMapCore] = useState<CoreLibrary | null>(null) useEffect(() => { if (!maps) loadMaps() if (!places) loadPlaces() if (!geocoding) loadGeoCoding() if (!mapCore) loadMapCore() }, []) const loadMaps = async () => { const response = await loader.importLibrary("maps") if (response) { setMaps(response) } } const loadPlaces = async () => { const response = await loader.importLibrary("places") if (response) { setPlaces(response) } } const loadGeoCoding = async () => { const response = await loader.importLibrary("geocoding") if (response) { setGeocoding(response) } } const loadMapCore = async () => { const response = await loader.importLibrary("core") if (response) { setMapCore(response) } } const decodeAddressComponents = (addressComponents: GeocoderAddressComponent[]) => { const getAddressComponent = (type: string, value: "short_name" | "long_name" = "long_name") => { const {short_name = "", long_name = ""} = addressComponents.find(({types}) => types.includes(type)) || {} return value === "long_name" ? long_name : short_name } const doorAndFloorNo = getAddressComponent("premise") const subLocality = addressComponents .filter(it => it.types.includes("sublocality_level_1")) .map(lMark => lMark.long_name) .join(", ") const city = getAddressComponent("locality") || getAddressComponent("political") const state = getAddressComponent("administrative_area_level_1") const country = getAddressComponent("country") const countryCode = getAddressComponent("country") const pinCode = getAddressComponent("postal_code") return { doorAndFloorNo, subLocality, city: city || subLocality, state, country, countryCode, pinCode, } } const reverseGeoCode = async (lat: number, lng: number): Promise<IDecodedAddress | undefined> => { if (geocoding) { const {Geocoder} = geocoding const geoCoder = new Geocoder() const {results} = await geoCoder.geocode({location: {lat, lng}}) if (results[0]) { const sorted = results?.find(result => result?.address_components?.find(addrComp => addrComp.types.includes("postal_code")) ) const addressComponents = sorted?.address_components || [] /* const address = sorted?.formatted_address */ const data = decodeAddressComponents(addressComponents) return { ...data, latitude: Number(lat.toFixed(14)), longitude: Number(lng.toFixed(14)), } } } } const getCurrentLocationData = (callback: (addressData: IDecodedAddress | null) => void) => { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( async position => { const response = await reverseGeoCode(position.coords.latitude, position.coords.longitude) callback(response || null) }, err => { console.error("User denied access to location >>>>>>>>>>", err) callback(null) }, {enableHighAccuracy: true} ) } else { console.error("Geolocation is not supported by this browser. >>>>>>>>>>") callback(null) } } const getPlacesPredictions = (searchText: string, onCallback: (predictions: AutocompletePrediction[]) => void) => { if (places) { const service = new places.AutocompleteService() service.getPlacePredictions( {input: searchText, componentRestrictions: {country: "in"}}, (predictions, status) => { if (status === places.PlacesServiceStatus.OK) { onCallback(predictions || []) } } ) } } return { loader, maps, places, geocoding, mapCore, reverseGeoCode, getCurrentLocationData, getPlacesPredictions, } }