| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- 'use client'
- import { useEffect, useRef, useState } from 'react'
- import L from 'leaflet'
- import 'leaflet/dist/leaflet.css'
- interface MapPickerProps {
- onSelect: (lat: number, lng: number, address?: string) => void
- onClose: () => void
- }
- export default function MapPicker({ onSelect, onClose }: MapPickerProps) {
- const mapRef = useRef<HTMLDivElement>(null)
- const markerRef = useRef<L.Marker | null>(null)
- const mapInstanceRef = useRef<L.Map | null>(null)
- const [lat, setLat] = useState(55.7558)
- const [lng, setLng] = useState(37.6173)
- const [loading, setLoading] = useState(false)
- useEffect(() => {
- if (!mapRef.current || mapInstanceRef.current) return
- const map = L.map(mapRef.current, {
- zoomControl: false,
- attributionControl: false,
- }).setView([lat, lng], 12)
- L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
- maxZoom: 19,
- }).addTo(map)
- map.on('click', (e) => {
- const newLat = e.latlng.lat
- const newLng = e.latlng.lng
- setLat(newLat)
- setLng(newLng)
- if (markerRef.current) markerRef.current.remove()
- markerRef.current = L.marker([newLat, newLng]).addTo(map)
- })
- mapInstanceRef.current = map
- return () => {
- map.remove()
- mapInstanceRef.current = null
- }
- }, [])
- const handleConfirm = async () => {
- setLoading(true)
- try {
- const res = await fetch(
- `https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=json&accept-language=ru`
- )
- const data = await res.json()
- onSelect(lat, lng, data.display_name || undefined)
- } catch {
- onSelect(lat, lng)
- }
- }
- return (
- <div className="fixed inset-0 z-[60] flex flex-col bg-black/80 backdrop-blur-sm">
- <div ref={mapRef} className="flex-1" />
- <div className="flex items-center justify-between bg-[#1e293b] px-4 py-3">
- <div className="text-sm text-white/60">
- {lat.toFixed(6)}, {lng.toFixed(6)}
- </div>
- <div className="flex gap-3">
- <button
- onClick={onClose}
- className="rounded-lg bg-white/10 px-4 py-2 text-sm text-white hover:bg-white/20 transition"
- >
- Отмена
- </button>
- <button
- onClick={handleConfirm}
- disabled={loading}
- className="rounded-lg bg-green-600 px-4 py-2 text-sm text-white hover:bg-green-500 transition disabled:opacity-50"
- >
- {loading ? 'Загрузка...' : 'Подтвердить'}
- </button>
- </div>
- </div>
- </div>
- )
- }
|