mirror of
https://github.com/zvx-echo6/navi.git
synced 2026-05-20 22:54:42 +02:00
feat: geocode search + map pick for contact location
This commit is contained in:
parent
a7519a3aab
commit
99bd2218a4
3 changed files with 227 additions and 20 deletions
|
|
@ -665,6 +665,9 @@ const MapView = forwardRef(function MapView(_, ref) {
|
|||
const geoPermission = useStore((s) => s.geoPermission)
|
||||
const setSheetState = useStore((s) => s.setSheetState)
|
||||
const setMapCenter = useStore((s) => s.setMapCenter)
|
||||
const pickingLocationFor = useStore((s) => s.pickingLocationFor)
|
||||
const setEditingContact = useStore((s) => s.setEditingContact)
|
||||
const clearPickingLocationFor = useStore((s) => s.clearPickingLocationFor)
|
||||
|
||||
// Zoom level indicator state
|
||||
const [zoomLevel, setZoomLevel] = useState(10)
|
||||
|
|
@ -1021,6 +1024,35 @@ const MapView = forwardRef(function MapView(_, ref) {
|
|||
return
|
||||
}
|
||||
|
||||
// Handle location pick mode for contacts
|
||||
const pickState = useStore.getState().pickingLocationFor
|
||||
if (pickState) {
|
||||
const { lng, lat } = e.lngLat
|
||||
map.getCanvas().style.cursor = ''
|
||||
// Reverse geocode for address
|
||||
fetchReverse(lat, lng).then((place) => {
|
||||
const addr = place?.address || place?.name || ''
|
||||
// Rebuild form data with new location
|
||||
useStore.getState().setEditingContact({
|
||||
...pickState,
|
||||
lat,
|
||||
lon: lng,
|
||||
address: addr || pickState.address || '',
|
||||
})
|
||||
useStore.getState().clearPickingLocationFor()
|
||||
}).catch(() => {
|
||||
// Even if reverse geocode fails, set the location
|
||||
useStore.getState().setEditingContact({
|
||||
...pickState,
|
||||
lat,
|
||||
lon: lng,
|
||||
})
|
||||
useStore.getState().clearPickingLocationFor()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
const store = useStore.getState()
|
||||
const marker = store.clickMarker
|
||||
|
|
@ -1646,6 +1678,36 @@ const MapView = forwardRef(function MapView(_, ref) {
|
|||
return () => window.removeEventListener("keydown", handleKeyDown)
|
||||
}, [measuring.active])
|
||||
|
||||
// Handle location pick mode for contacts
|
||||
useEffect(() => {
|
||||
const map = mapInstance.current
|
||||
if (!map) return
|
||||
if (pickingLocationFor) {
|
||||
map.getCanvas().style.cursor = 'crosshair'
|
||||
}
|
||||
return () => {
|
||||
if (map && !measuring.active) {
|
||||
map.getCanvas().style.cursor = ''
|
||||
}
|
||||
}
|
||||
}, [pickingLocationFor, measuring.active])
|
||||
|
||||
// ESC key handler for location pick mode
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e) => {
|
||||
if (e.key === 'Escape' && pickingLocationFor) {
|
||||
// Cancel pick mode, reopen modal with original form data
|
||||
const map = mapInstance.current
|
||||
if (map) map.getCanvas().style.cursor = ''
|
||||
setEditingContact(pickingLocationFor)
|
||||
clearPickingLocationFor()
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
return () => window.removeEventListener('keydown', handleKeyDown)
|
||||
}, [pickingLocationFor, setEditingContact, clearPickingLocationFor])
|
||||
|
||||
|
||||
// Track zoom level for indicator
|
||||
useEffect(() => {
|
||||
const map = mapInstance.current
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue