diff --git a/front/src/api/osmAddress/index.ts b/front/src/api/osmAddress/index.ts
new file mode 100644
index 0000000..90df60d
--- /dev/null
+++ b/front/src/api/osmAddress/index.ts
@@ -0,0 +1,12 @@
+import { LatLng } from 'leaflet'
+import { OsmAddressResponse } from './types'
+
+const initialOsmAddress = ''
+
+const composeOsmAddressURL = (addressPosition: LatLng) =>
+ `${location.protocol}//nominatim.openstreetmap.org/reverse?format=json&accept-language=ru&lat=${addressPosition.lat}&lon=${addressPosition.lng}`
+
+const processOsmAddress = (data: OsmAddressResponse): string =>
+ data.display_name
+
+export { initialOsmAddress, composeOsmAddressURL, processOsmAddress }
diff --git a/front/src/api/osmAddress/types.ts b/front/src/api/osmAddress/types.ts
new file mode 100644
index 0000000..8d58a89
--- /dev/null
+++ b/front/src/api/osmAddress/types.ts
@@ -0,0 +1,17 @@
+import { isObject } from '../../utils/types'
+
+type OsmAddressResponse = {
+ display_name: string
+}
+
+const isOsmAddressResponse = (obj: unknown): obj is OsmAddressResponse => isObject(obj, {
+ 'display_name': 'string',
+})
+
+export type {
+ OsmAddressResponse,
+}
+
+export {
+ isOsmAddressResponse,
+}
diff --git a/front/src/hooks/api/index.ts b/front/src/hooks/api/index.ts
index 277a716..9023aee 100644
--- a/front/src/hooks/api/index.ts
+++ b/front/src/hooks/api/index.ts
@@ -3,3 +3,4 @@ export { default as useBook } from './useBook'
export { default as useAuth } from './useAuth'
export { default as useTrashboxes } from './useTrashboxes'
export { default as useAddAnnouncement } from './useAddAnnouncement'
+export { default as useOsmAddresses } from './useOsmAddress'
diff --git a/front/src/hooks/api/useOsmAddress.ts b/front/src/hooks/api/useOsmAddress.ts
new file mode 100644
index 0000000..17d5f5b
--- /dev/null
+++ b/front/src/hooks/api/useOsmAddress.ts
@@ -0,0 +1,17 @@
+import { LatLng } from 'leaflet'
+
+import useFetch from './useFetch'
+import { composeOsmAddressURL, processOsmAddress } from '../../api/osmAddress'
+import { isOsmAddressResponse } from '../../api/osmAddress/types'
+
+const useOsmAddresses = (addressPosition: LatLng) =>
+ useFetch(
+ composeOsmAddressURL(addressPosition),
+ 'GET',
+ false,
+ isOsmAddressResponse,
+ processOsmAddress,
+ ''
+ )
+
+export default useOsmAddresses
diff --git a/front/src/pages/AddPage.tsx b/front/src/pages/AddPage.tsx
index b9f9f70..17816b6 100644
--- a/front/src/pages/AddPage.tsx
+++ b/front/src/pages/AddPage.tsx
@@ -5,56 +5,37 @@ import { latLng } from 'leaflet'
import { ClickHandler, LocationMarker, TrashboxMarkers } from '../components'
import { useAddAnnouncement, useTrashboxes } from '../hooks/api'
-import { isObject } from '../utils/types'
import { handleHTTPErrors } from '../utils'
import { categories, categoryNames } from '../assets/category'
import { stations, lines, lineNames } from '../assets/metro'
-import { gotError } from '../hooks/api/useFetch'
+import { fallbackError, gotError } from '../hooks/api/useFetch'
+import { useOsmAddresses } from '../hooks/api'
function AddPage() {
const [addressPosition, setAddressPosition] = useState(latLng(59.972, 30.3227))
- const [address, setAddress] = useState('')
const trashboxes = useTrashboxes(addressPosition)
const [selectedTrashbox, setSelectedTrashbox] = useState({ index: -1, category: '' })
- useEffect(() => {
- void (async () => {
- try {
- const res = await fetch(location.protocol + '//nominatim.openstreetmap.org/search?format=json&q=' + address)
-
- handleHTTPErrors(res)
-
- const fetchData: unknown = await res.json()
-
- console.log('f', fetchData)
-
- } catch (err) {
- console.error(err)
- }
- })()
- }, [address])
+ const address = useOsmAddresses(addressPosition)
useEffect(() => {
- void (async () => {
- try {
- const res = await fetch(`${location.protocol}//nominatim.openstreetmap.org/reverse?format=json&accept-language=ru&lat=${addressPosition.lat}&lon=${addressPosition.lng}`)
+ if (!gotError(address))
+ void (async () => {
+ try {
+ const res = await fetch(location.protocol + '//nominatim.openstreetmap.org/search?format=json&q=' + encodeURIComponent(address.data))
- handleHTTPErrors(res)
+ handleHTTPErrors(res)
- const fetchData: unknown = await res.json()
+ const fetchData: unknown = await res.json()
- if (!isObject<{ display_name: string }>(fetchData, { 'display_name': 'string' })) {
- throw new Error('Malformed server response')
+ console.log('f', fetchData)
+
+ } catch (err) {
+ console.error(err)
}
-
- setAddress(fetchData.display_name)
-
- } catch (err) {
- console.error(err)
- }
- })()
- }, [addressPosition])
+ })()
+ }, [address])
const { doAdd, status } = useAddAnnouncement()
@@ -66,7 +47,7 @@ function AddPage() {
formData.append('latitude', addressPosition.lat.toString())
formData.append('longtitude', addressPosition.lng.toString())
- formData.append('address', address)
+ formData.append('address', address.data || '') // if address.error
formData.set('bestBy', new Date((formData.get('bestBy') as number | null) || 0).getTime().toString())
void doAdd(formData)
@@ -112,7 +93,7 @@ function AddPage() {
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
/>
Адрес: {address}
+Адрес: {fallbackError(address)}