oriyo_next/src/features/map/ui/yandex-map.tsx

104 lines
2.7 KiB
TypeScript

import {
GeolocationControl,
Map,
Placemark,
YMaps,
} from '@pbe/react-yandex-maps';
import { isEmpty } from 'lodash';
import { useEffect, useRef } from 'react';
import { Point } from '../model';
type YandexMapProps = {
points: Point[];
selectedStation: number | null;
handleMapStationClick: (id: number) => void;
};
const mapCenter = [38.53575, 68.77905];
export const YandexMap = ({
points,
selectedStation,
handleMapStationClick,
}: YandexMapProps) => {
const mapRef = useRef<any>(null);
useEffect(() => {
if (!mapRef.current) return;
if (selectedStation !== null) {
const selectedPoint = points.find(
(point) => point.id === selectedStation,
);
if (selectedPoint) {
mapRef.current
.setCenter(selectedPoint.coordinates, mapRef.current.getZoom(), {
duration: 1000,
})
.then(() => {
mapRef.current.setZoom(13, { duration: 300 });
});
}
} else {
mapRef.current.setZoom(11, { duration: 300 });
}
}, [selectedStation, points]);
return (
<YMaps
query={{
apikey: process.env.NEXT_PUBLIC_YANDEX_MAP_API_KEY,
lang: 'ru_RU',
}}
>
<Map
defaultState={{
center: !isEmpty(points) ? points[0].coordinates : mapCenter,
zoom: 11,
behaviors: ['drag', 'multiTouch', 'dblClickZoom', 'scrollZoom'],
}}
options={{
copyrightUaVisible: false,
copyrightProvidersVisible: false,
copyrightLogoVisible: false,
suppressMapOpenBlock: true,
suppressObsoleteBrowserNotifier: true,
}}
className='h-full max-h-[500px] w-full overflow-hidden rounded-md shadow-lg'
instanceRef={(ref) => {
mapRef.current = ref;
}}
>
{points.map((point) => {
const isSelectedStation = selectedStation === point.id;
return (
<Placemark
key={point.id}
geometry={point.coordinates}
options={{
iconLayout: 'default#image',
iconImageHref:
!selectedStation || isSelectedStation
? '/map/oriyo-marker.png'
: '/map/oriyo-inactive-marker.png',
iconImageSize: isSelectedStation ? [70, 70] : [64, 64],
iconImageOffset: isSelectedStation ? [-28, -40] : [-24, -36],
}}
onClick={() => handleMapStationClick(point.id)}
/>
);
})}
<GeolocationControl
options={{
position: {
bottom: 20,
right: 20,
},
}}
/>
</Map>
</YMaps>
);
};