asb_cloud_front/src/pages/Deposit.jsx

82 lines
2.5 KiB
React
Raw Normal View History

import { Map, Overlay } from 'pigeon-maps'
import { Link, useLocation } from 'react-router-dom'
import { useState, useEffect, memo } from 'react'
import { ClusterService } from '@api'
import { arrayOrDefault } from '@utils'
import { PointerIcon } from '@components/icons'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import '@styles/index.css'
const defaultViewParams = { center: [60.81226, 70.0562], zoom: 5 }
2021-07-20 14:10:01 +05:00
const calcViewParams = (clusters) => {
if ((clusters?.length ?? 0) <= 0)
return defaultViewParams
2021-07-20 14:10:01 +05:00
const center = clusters.reduce((sum, cluster) => {
sum[0] += (cluster.latitude / clusters.length)
sum[1] += (cluster.longitude / clusters.length)
return sum
}, [0, 0])
const maxDeg = clusters.reduce((max, cluster) => {
const dLatitude = Math.abs(center[0] - cluster.latitude)
const dLongitude = Math.abs(center[1] - cluster.longitude)
const d = dLatitude > dLongitude ? dLatitude : dLongitude
return d > max ? d : max
}, 0)
2021-09-15 12:03:03 +05:00
// zoom max = 20 (too close)
// zoom min = 1 (mega far)
// 4 - full Russia (161.6 deg)
// 13.5 - Khanty-Mansiysk
const zoom = Math.min(Math.max(5, 5 + 5 / (maxDeg + 0.5)), 15)
2021-09-15 12:03:03 +05:00
return { center, zoom }
2021-07-20 14:10:01 +05:00
}
export const Deposit = memo(() => {
2021-07-20 14:10:01 +05:00
const [clustersData, setClustersData] = useState([])
const [showLoader, setShowLoader] = useState(false)
const [viewParams, setViewParams] = useState(defaultViewParams)
2021-07-20 14:10:01 +05:00
const location = useLocation()
useEffect(() => invokeWebApiWrapperAsync(
async () => {
const data = await ClusterService.getClusters()
setClustersData(arrayOrDefault(data))
setViewParams(calcViewParams(data))
},
setShowLoader,
`Не удалось загрузить список кустов`,
'Получить список кустов'
), [])
2021-07-20 14:10:01 +05:00
return (
<LoaderPortal show={showLoader}>
2021-09-02 16:33:02 +05:00
<div className={'h-100vh'}>
2021-09-15 12:03:03 +05:00
<Map {...viewParams}>
{clustersData.map(cluster => (
<Overlay
width={32}
anchor={[cluster.latitude, cluster.longitude]}
key={`${cluster.latitude} ${cluster.longitude}`}
>
<Link to={{ pathname: `/cluster/${cluster.id}`, state: { from: location.pathname }}}>
<PointerIcon state={'active'} width={48} height={59} />
<span>{cluster.caption}</span>
</Link>
</Overlay>
))}
2021-09-02 16:33:02 +05:00
</Map>
</div>
2021-07-20 14:10:01 +05:00
</LoaderPortal>
)
})
export default Deposit