added geolocation
This commit is contained in:
@@ -8,6 +8,7 @@ import { useImageUpload, ACCEPT, MAX_SIZE_MB } from "../hooks/useImageUpload";
|
||||
import { validatePostForm } from "../utils/validatePostForm";
|
||||
import { formatPhone } from "../utils/formatPhone";
|
||||
import { useYandexMap } from "../hooks/useYandexMap";
|
||||
import { useGeolocation, GEO_STATUS } from "../hooks/useGeolocation";
|
||||
import MapModal from "./MapModal";
|
||||
import ClearableField from "../components/ClearableField";
|
||||
|
||||
@@ -62,12 +63,29 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
||||
? { latitude: initialData.latitude, longitude: initialData.longitude }
|
||||
: null;
|
||||
|
||||
const { mapRef, coords, address, addressRef, loading: mapLoading } = useYandexMap(
|
||||
const { mapRef, coords, address, addressRef, loading: mapLoading, moveTo } = useYandexMap(
|
||||
mapModalOpen,
|
||||
initialCoords,
|
||||
isEdit ? (initialData.location || "") : ""
|
||||
);
|
||||
|
||||
const { coords: geoCoords, status: geoStatus, requestLocation: requestGeoLocation } =
|
||||
useGeolocation();
|
||||
// При открытии окна карты запрашиваем геолокацию; если пользователь дал
|
||||
// разрешение — автоматически центрируем карту и ставим маркер на его место.
|
||||
// При отказе/недоступности API ничего не делаем — остаётся дефолтный центр.
|
||||
useEffect(() => {
|
||||
if (mapModalOpen) {
|
||||
requestGeoLocation();
|
||||
}
|
||||
}, [mapModalOpen, requestGeoLocation]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mapModalOpen && geoStatus === GEO_STATUS.SUCCESS && geoCoords) {
|
||||
moveTo(geoCoords.latitude, geoCoords.longitude);
|
||||
}
|
||||
}, [mapModalOpen, geoStatus, geoCoords, moveTo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (address) {
|
||||
setForm(prev => ({ ...prev, address }));
|
||||
@@ -394,6 +412,7 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
||||
mapRef={mapRef}
|
||||
address={address}
|
||||
mapLoading={mapLoading}
|
||||
geoStatus={geoStatus}
|
||||
onClose={() => setMapModalOpen(false)}
|
||||
onSave={() => setMapModalOpen(false)}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import CloseIcon from "../components/icons/CloseIcon";
|
||||
import { GEO_STATUS } from "../hooks/useGeolocation";
|
||||
|
||||
/**
|
||||
* MapModal — модальное окно с картой для выбора местоположения.
|
||||
@@ -8,10 +9,11 @@ import CloseIcon from "../components/icons/CloseIcon";
|
||||
* @param {object} mapRef — ref, в который монтируется Яндекс.Карта
|
||||
* @param {string} address — текущий (выбранный) адрес
|
||||
* @param {boolean} mapLoading — идёт ли подгрузка адреса по координатам
|
||||
* @param {string} geoStatus — статус геолокации (GEO_STATUS.*)
|
||||
* @param {function} onClose — закрыть окно без сохранения
|
||||
* @param {function} onSave — сохранить выбранное местоположение
|
||||
*/
|
||||
export default function MapModal({ mapRef, address, mapLoading, onClose, onSave }) {
|
||||
export default function MapModal({ mapRef, address, mapLoading, geoStatus, onClose, onSave }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -20,6 +22,14 @@ export default function MapModal({ mapRef, address, mapLoading, onClose, onSave
|
||||
return () => { document.body.style.overflow = prev; };
|
||||
}, []);
|
||||
|
||||
const geoHint =
|
||||
geoStatus === GEO_STATUS.SUCCESS ? t('post.geoSuccess')
|
||||
: geoStatus === GEO_STATUS.LOADING ? t('post.geoLoading')
|
||||
: geoStatus === GEO_STATUS.DENIED ? t('post.geoDenied')
|
||||
: geoStatus === GEO_STATUS.UNSUPPORTED ? t('post.geoUnsupported')
|
||||
: geoStatus === GEO_STATUS.TIMEOUT ? t('post.geoTimeout')
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div className="f-modal-bg" onClick={e => e.target === e.currentTarget && onClose()}>
|
||||
<div className="f-modal f-map-modal">
|
||||
@@ -36,6 +46,10 @@ export default function MapModal({ mapRef, address, mapLoading, onClose, onSave
|
||||
<div ref={mapRef} className="f-map-inner" />
|
||||
</div>
|
||||
|
||||
{geoHint && (
|
||||
<div className="f-map-geo">{geoHint}</div>
|
||||
)}
|
||||
|
||||
{/* Selected address */}
|
||||
<div className="f-map-selected">
|
||||
<span className="f-map-selected-label">{t('post.selectedAddress')}</span>
|
||||
@@ -51,3 +65,4 @@ export default function MapModal({ mapRef, address, mapLoading, onClose, onSave
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user