import { Empty, TreeSelect } from "antd"; import { Title } from "../../components/Title"; import { useRegion } from "../../stores/useRegion"; import { useEffect, useMemo, useState } from "react"; import { useMap } from "react-map-gl"; import getBbox from "@turf/bbox"; import { polygon as getPolygon } from "@turf/helpers"; import { useRegionGeometry } from "../../stores/useRegionGeometry"; import { api } from "../../api"; const { TreeNode } = TreeSelect; const normalizeRegions = (rawRegions) => { if (!rawRegions) return {}; return rawRegions.reduce((acc, raw) => { acc[`ao-${raw.id}`] = raw; if (raw.children) { raw.children.forEach((child) => { acc[`rayon-${child.id}`] = child; }); } return acc; }, {}); }; export const RegionSelect = () => { const { current: map } = useMap(); const { region, setRegion } = useRegion(); const { setRegionGeometry } = useRegionGeometry(); const [data, setData] = useState([]); const normalizedData = useMemo(() => normalizeRegions(data), [data]); const [loading, setLoading] = useState(false); useEffect(() => { const getRegions = async () => { setLoading(true); try { const response = await api.get( "https://postamates.spatiality.website/api/ao_and_rayons" ); setData(response.data); } catch (err) { console.error(err); } finally { setLoading(false); } }; getRegions(); }, []); const onChange = (value) => { if (!value) return; const selectedRegion = normalizedData[value]; const polygon = getPolygon(selectedRegion.geometry[0]); const bbox = getBbox(polygon); setRegionGeometry(polygon); setRegion(value); map.fitBounds( [ [bbox[0], bbox[1]], // southwestern corner of the bounds [bbox[2], bbox[3]], // northeastern corner of the bounds ], { padding: 20, } ); }; const handleClear = () => { setRegion(null); setRegionGeometry(null); }; return (
<TreeSelect showSearch style={{ width: "100%" }} value={region} dropdownStyle={{ maxHeight: 400, overflow: "auto" }} placeholder="Выберите АО или район" allowClear treeDefaultExpandAll={false} onChange={onChange} loading={loading} treeNodeFilterProp="title" onClear={handleClear} notFoundContent={ <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={"Не найдено"} /> } > {data?.map((parent) => { return ( <TreeNode key={`ao-${parent.id}`} value={`ao-${parent.id}`} title={parent.name} > {parent.children?.map((child) => ( <TreeNode key={`rayon-${child.id}`} value={`rayon-${child.id}`} title={child.name} /> ))} </TreeNode> ); })} </TreeSelect> </div> ); };