MCPcopy Create free account
hub / github.com/Thanas-R/Virdis / SearchBar

Function SearchBar

src/components/SearchBar.tsx:18–95  ·  view source on GitHub ↗
({ onSearch, onLocationSelect }: SearchBarProps)

Source from the content-addressed store, hash-verified

16 center: [number, number];
17}
18
19const SearchBar = ({ onSearch, onLocationSelect }: SearchBarProps) => {
20 const [query, setQuery] = useState("");
21 const [results, setResults] = useState<GeocodingResult[]>([]);
22 const [showResults, setShowResults] = useState(false);
23 const debounceRef = useRef<ReturnType<typeof setTimeout>>();
24 const containerRef = useRef<HTMLDivElement>(null);
25
26 useEffect(() => {
27 const handleClickOutside = (e: MouseEvent) => {
28 if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
29 setShowResults(false);
30 }
31 };
32 document.addEventListener("mousedown", handleClickOutside);
33 return () => document.removeEventListener("mousedown", handleClickOutside);
34 }, []);
35
36 const geocode = async (text: string) => {
37 if (text.length < 2) {
38 setResults([]);
39 return;
40 }
41 try {
42 const { data } = await callBackend("mapbox-geocode", { mode: "forward", query: text, limit: 4 });
43 setResults(((data?.features as GeocodingResult[]) || []).slice(0, 4));
44 setShowResults(true);
45 } catch {
46 setResults([]);
47 }
48 };
49
50 const handleChange = (value: string) => {
51 setQuery(value);
52 onSearch(value);
53 if (debounceRef.current) clearTimeout(debounceRef.current);
54 debounceRef.current = setTimeout(() => geocode(value), 300);
55 };
56
57 const handleSelect = (result: GeocodingResult) => {
58 setQuery(result.place_name);
59 setShowResults(false);
60 onLocationSelect?.(result.center[0], result.center[1], result.place_name);
61 };
62
63 return (
64 <div className="absolute top-4 left-4 z-10" ref={containerRef}>
65 <div className="relative opacity-85">
66 <input
67 type="text"
68 placeholder="Location…"
69 value={query}
70 onChange={(e) => handleChange(e.target.value)}
71 onFocus={() => results.length > 0 && setShowResults(true)}
72 className="w-72 backdrop-blur-sm border border-border rounded-lg px-4 py-2.5 pr-10 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring"
73 style={{ backgroundColor: "#041009" }} />
74
75 <Search className="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />

Callers

nothing calls this directly

Calls 2

handleSelectFunction · 0.85
handleChangeFunction · 0.70

Tested by

no test coverage detected