diff --git a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/LocationPicker.tsx b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/LocationPicker.tsx index b2f14b16f..6a53be5cc 100644 --- a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/LocationPicker.tsx +++ b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/LocationPicker.tsx @@ -409,7 +409,11 @@ function LocationPickerInline({ const geocoder = useGeocoder(); const places = usePlacesSearch(); const placesLib = useMapsLibrary("places"); - const [query, setQuery] = useState(""); + // `null` means "not editing" (show the saved address); any string — including + // "" after the user clears the field — is live edit state. A plain `query || + // value.address` fallback would snap the saved address back the moment the + // user cleared the input, making it impossible to retype the location. + const [query, setQuery] = useState(null); const [results, setResults] = useState([]); const [searching, setSearching] = useState(false); const [resolving, setResolving] = useState(false); @@ -430,7 +434,7 @@ function LocationPickerInline({ // than one per keystroke. While it runs, the input shows a spinner; the // dropdown itself only appears once there are predictions to show. useEffect(() => { - const q = query.trim(); + const q = (query ?? "").trim(); if (q.length < MIN_QUERY_LEN) { setResults([]); setSearching(false); @@ -469,7 +473,7 @@ function LocationPickerInline({ async (prediction: PlacePrediction) => { // Clear the query/results immediately so the pending debounce can't fire // a search for the picked address and pop the dropdown back open. - setQuery(""); + setQuery(null); setResults([]); // Predictions carry no coordinates — resolve them now via Place Details. if (!places) return; @@ -498,6 +502,9 @@ function LocationPickerInline({ const handlePin = useCallback( async (lat: number, lng: number) => { // Show the pin immediately; fill the address once reverse geocoding lands. + // Leave edit mode so the input reflects the reverse-geocoded address + // instead of whatever half-typed query the user abandoned for the map. + setQuery(null); onChange({ address: value.address, lat, lng }); if (!geocoder) return; // Mark any in-flight reverse lookup stale — only the latest pin counts. @@ -525,7 +532,7 @@ function LocationPickerInline({ [handlePin], ); - const inputValue = query || value.address; + const inputValue = query ?? value.address; const center = hasPin ? { lat: value.lat as number, lng: value.lng as number } : DEFAULT_CENTER;