zkt25/sk1/frontend/src/components/AddressAutocomplete.jsx

68 lines
1.9 KiB
JavaScript

import React, { useState, useEffect } from "react";
export default function AddressAutocomplete({ onSelect }) {
const [input, setInput] = useState("");
const [options, setOptions] = useState([]);
useEffect(() => {
if (input.length < 3) {
setOptions([]);
return;
}
const ctrl = new AbortController();
fetch(`/api/autocomplete?input=${encodeURIComponent(input)}`, {
signal: ctrl.signal,
})
.then((res) => res.json())
.then((json) => setOptions(json.predictions || []))
.catch(() => {})
.finally(() => {});
return () => ctrl.abort();
}, [input]);
return (
<div className="address-autocomplete" style={{ position: "relative" }}>
<input
type="text"
placeholder="Start typing address…"
value={input}
onChange={(e) => setInput(e.target.value)}
style={{ width: "100%", padding: "0.5rem", boxSizing: "border-box" }}
/>
{options.length > 0 && (
<ul
className="autocomplete-list"
style={{
listStyle: "none",
margin: 0,
padding: "0.5rem",
position: "absolute",
top: "100%",
left: 0,
right: 0,
background: "#fff",
border: "1px solid #ccc",
maxHeight: "200px",
overflowY: "auto",
zIndex: 1000,
}}
>
{options.map((opt) => (
<li
key={opt.place_id}
onClick={() => {
setInput(opt.description);
setOptions([]);
onSelect(opt.description);
}}
style={{ padding: "0.25rem 0", cursor: "pointer" }}
>
{opt.description}
</li>
))}
</ul>
)}
</div>
);
}