"use client"; import { useMemo, useState } from "react"; import usePlacesAutocomplete, { getGeocode, getLatLng, } from "use-places-autocomplete"; import { Input } from "../ui/input"; import { cn } from "@/lib/utils"; import { HiOutlineBuildingStorefront, HiOutlineMapPin, HiOutlineHomeModern, HiOutlineFilm, HiOutlineShoppingBag, HiOutlineBuildingLibrary, } from "react-icons/hi2"; import { RxMagnifyingGlass } from "react-icons/rx"; import { LiaGlassMartiniSolid } from "react-icons/lia"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Button } from "@/components/ui/button"; import { useLoadScript } from "@react-google-maps/api"; import Spinner from "../spinner"; import Geohash from "latlon-geohash"; type LocationSearchInputProps = { onSelect: (location: { name: string; address: string; coordinates: { lat: number; lng: number }; geohash: string; }) => void; location?: { name: string; address: string; coordinates: { lat: number; lng: number }; geohash: string; }; }; export default function LocationSearchInput({ onSelect, location, }: LocationSearchInputProps) { console.log("LOCATION", location); const libraries = useMemo(() => ["places"], []); const { isLoaded, loadError } = useLoadScript({ googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY as string, libraries: libraries as any, }); if (loadError) { return

{JSON.stringify(loadError)}

; } if (!isLoaded) { return ( ); } return ; } type CommandSearchProps = { onSelect: (location: { name: string; address: string; coordinates: { lat: number; lng: number }; geohash: string; }) => void; location?: { name: string; address: string; coordinates: { lat: number; lng: number }; geohash: string; }; }; function CommandSearch({ location, onSelect }: CommandSearchProps) { const [open, setOpen] = useState(false); const { ready, value, suggestions: { status, data, loading }, // results from Google Places API for the given search term setValue, // use this method to link input value with the autocomplete hook clearSuggestions, } = usePlacesAutocomplete({ requestOptions: {}, debounce: 300, cache: 86400, }); async function handleSelect(placeId: string, name: string) { const result = await getGeocode({ placeId, }); if (!result[0]) return; const coordinates = getLatLng(result[0]); const geohash = Geohash.encode(coordinates.lat, coordinates.lng, 8); setOpen(false); return onSelect({ name, coordinates, address: result[0].formatted_address, geohash, }); } return (
setValue(e.target.value)} placeholder="Search places..." disabled={!ready} />
    {data.map((place) => { const { place_id, structured_formatting: { main_text, secondary_text }, types, } = place; return (
  • handleSelect(place_id, main_text)} className={cn( "relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-muted", )} >

    {main_text}

    {secondary_text}
  • ); })} {data.length === 0 && status === "ZERO_RESULTS" && (

    No results found

    )} {loading && (
    )}
); } function RenderIcon({ types, className, }: { types: string[]; className?: string; }) { if (types.includes("restaurant")) { return ; } else if (types.includes("art_gallery")) { return ; } else if (types.includes("bar")) { return ; } else if (types.includes("city_hall")) { return ; } else if (types.includes("store")) { return ; } else if (types.includes("movie_theater")) { return ; } return ; }