import * as React from "react"; import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons"; import { cn } from "@/util/utils"; import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { GeoTarget } from "@/api/types"; import { formatGeoTargetCompact } from "@/util/geoData"; import { GroupedSearchResults, searchGeoData, SearchResultItem, } from "@/util/geoSearch"; import { useDebouncedCallback } from "use-debounce"; interface GeoTargetSelectorProps { value: GeoTarget | null; onChange: (value: GeoTarget) => void; className?: string; } export function GeoTargetSelector({ value, onChange, className, }: GeoTargetSelectorProps) { const [open, setOpen] = React.useState(false); const [query, setQuery] = React.useState(""); const [results, setResults] = React.useState({ countries: [], subdivisions: [], cities: [], }); const [loading, setLoading] = React.useState(false); const handleSearch = useDebouncedCallback(async (searchQuery: string) => { setLoading(true); try { const data = await searchGeoData(searchQuery); setResults(data); } catch (error) { console.error("Failed to search geo data", error); } finally { setLoading(false); } }, 300); // Initial load of countries React.useEffect(() => { if (open) { handleSearch(""); } }, [open, handleSearch]); const onInput = (val: string) => { setQuery(val); handleSearch(val); }; const handleSelect = (item: SearchResultItem) => { onChange(item.value); setOpen(false); }; const isSelected = (itemValue: GeoTarget) => { if (!value) return false; return ( value.country === itemValue.country && value.subdivision === itemValue.subdivision && value.city === itemValue.city && Boolean(value.isISP) === Boolean(itemValue.isISP) ); }; return ( {loading && (
Loading...
)} {!loading && results.countries.length === 0 && results.subdivisions.length === 0 && results.cities.length === 0 && ( No location found. )} {!loading && ( <> {results.countries.length > 0 && ( {results.countries.map((item) => ( handleSelect(item)} > {item.icon} {item.label} ))} )} {results.subdivisions.length > 0 && ( {results.subdivisions.map((item) => ( handleSelect(item)} > {item.icon}
{item.label} {item.description}
))}
)} {results.cities.length > 0 && ( {results.cities.map((item) => ( handleSelect(item)} > {item.icon}
{item.label} {item.description}
))}
)} )}
); }