You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1210 lines
43 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { Fragment, useState, useRef } from "react";
import { Dialog, Disclosure, Menu, Transition } from "@headlessui/react";
import { XMarkIcon } from "@heroicons/react/24/outline";
import {
ChevronUpIcon,
ChevronDownIcon,
FunnelIcon,
MinusIcon,
PlusIcon,
} from "@heroicons/react/20/solid";
import Map, { Layer, Source, Popup, ScaleControl } from "react-map-gl";
import mapstyle from "./points.json";
mapstyle.sources.remap.url = import.meta.env.MODE === "development" ? "http://localhost:8080/capabilities/remap.json" : mapstyle.sources.remap.url
const MAPBOX_TOKEN =
"pk.eyJ1IjoiZ2hlcm1hbnQiLCJhIjoiY2wzbHR0YW1sMXB0YjNkcXd5NWpqaWpybiJ9.jyLcIcB7NLbtZzGYIJZWWg";
const paintedLayers = mapstyle.layers.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {})
const pointsColors = mapstyle.layers.find(layer => layer.id == "Объекты").paint["circle-color"].slice(2, -1).reduce((acc, cur, i, source) => (i % 2 == 0 ? [...acc, { name: cur, color: source[i + 1] }] : acc), [])
const pointsSizes = mapstyle.layers.find(layer => layer.id == "Объекты").paint["circle-radius"].slice(3).reduce((acc, cur, i, source) => (i % 2 == 0 ? [...acc, { value: cur, size: source[i + 1] }] : acc), [])
const initialFilters = [
{
id: "id_tech",
name: "ВИЭ-технология",
options: [
{
"value": 1,
"label": "СЭС",
"checked": true
},
{
"value": 2,
"label": "ВЭС",
"checked": true
},
{
"value": 3,
"label": "мГЭС",
"checked": true
},
{
"value": 4,
"label": "БиоЭС (биомасса)",
"checked": true
},
{
"value": 5,
"label": "БиоЭС (биогаз)",
"checked": true
},
{
"value": 6,
"label": "БиоЭС (свалочный газ)",
"checked": true
},
{
"value": 8,
"label": "ПЭС",
"checked": true
},
{
"value": 9,
"label": "ГеоЭС",
"checked": true
}
]
},
{
"id": "region_name",
"name": "Регион размещения",
"options": [
{
"value": "Республика Адыгея ",
"label": "Республика Адыгея ",
"checked": true
},
{
"value": "Республика Алтай",
"label": "Республика Алтай",
"checked": true
},
{
"value": "Республика Башкортостан",
"label": "Республика Башкортостан",
"checked": true
},
{
"value": "Республика Бурятия",
"label": "Республика Бурятия",
"checked": true
},
{
"value": "Республика Дагестан",
"label": "Республика Дагестан",
"checked": true
},
{
"value": "Республика Ингушетия",
"label": "Республика Ингушетия",
"checked": true
},
{
"value": "Кабардино-Балкарская Республика",
"label": "Кабардино-Балкарская Республика",
"checked": true
},
{
"value": "Республика Калмыкия",
"label": "Республика Калмыкия",
"checked": true
},
{
"value": "Карачаево-Черкесская Республика",
"label": "Карачаево-Черкесская Республика",
"checked": true
},
{
"value": "Республика Карелия",
"label": "Республика Карелия",
"checked": true
},
{
"value": "Республика Коми",
"label": "Республика Коми",
"checked": true
},
{
"value": "Республика Крым",
"label": "Республика Крым",
"checked": true
},
{
"value": "Республика Марий Эл",
"label": "Республика Марий Эл",
"checked": true
},
{
"value": "Республика Мордовия",
"label": "Республика Мордовия",
"checked": true
},
{
"value": "Республика Саха (Якутия)",
"label": "Республика Саха (Якутия)",
"checked": true
},
{
"value": "Республика Северная Осетия Алания",
"label": "Республика Северная Осетия Алания",
"checked": true
},
{
"value": "Республика Татарстан ",
"label": "Республика Татарстан ",
"checked": true
},
{
"value": "Республика Тыва",
"label": "Республика Тыва",
"checked": true
},
{
"value": "Удмуртская Республика",
"label": "Удмуртская Республика",
"checked": true
},
{
"value": "Республика Хакасия",
"label": "Республика Хакасия",
"checked": true
},
{
"value": "Чеченская Республика",
"label": "Чеченская Республика",
"checked": true
},
{
"value": "Чувашская Республика",
"label": "Чувашская Республика",
"checked": true
},
{
"value": "Алтайский край",
"label": "Алтайский край",
"checked": true
},
{
"value": "Забайкальский край",
"label": "Забайкальский край",
"checked": true
},
{
"value": "Камчатский край",
"label": "Камчатский край",
"checked": true
},
{
"value": "Краснодарский край",
"label": "Краснодарский край",
"checked": true
},
{
"value": "Красноярский край",
"label": "Красноярский край",
"checked": true
},
{
"value": "Пермский край",
"label": "Пермский край",
"checked": true
},
{
"value": "Приморский край",
"label": "Приморский край",
"checked": true
},
{
"value": "Ставропольский край",
"label": "Ставропольский край",
"checked": true
},
{
"value": "Хабаровский край",
"label": "Хабаровский край",
"checked": true
},
{
"value": "Амурская область",
"label": "Амурская область",
"checked": true
},
{
"value": "Архангельская область",
"label": "Архангельская область",
"checked": true
},
{
"value": "Астраханская область",
"label": "Астраханская область",
"checked": true
},
{
"value": "Белгородская область",
"label": "Белгородская область",
"checked": true
},
{
"value": "Брянская область",
"label": "Брянская область",
"checked": true
},
{
"value": "Владимирская область",
"label": "Владимирская область",
"checked": true
},
{
"value": "Волгоградская область",
"label": "Волгоградская область",
"checked": true
},
{
"value": "Вологодская область",
"label": "Вологодская область",
"checked": true
},
{
"value": "Воронежская область",
"label": "Воронежская область",
"checked": true
},
{
"value": "Ивановская область",
"label": "Ивановская область",
"checked": true
},
{
"value": "Иркутская область",
"label": "Иркутская область",
"checked": true
},
{
"value": "Калининградская область",
"label": "Калининградская область",
"checked": true
},
{
"value": "Калужская область",
"label": "Калужская область",
"checked": true
},
{
"value": "Кемеровская область",
"label": "Кемеровская область",
"checked": true
},
{
"value": "Кировская область",
"label": "Кировская область",
"checked": true
},
{
"value": "Костромская область",
"label": "Костромская область",
"checked": true
},
{
"value": "Курганская область",
"label": "Курганская область",
"checked": true
},
{
"value": "Курская область",
"label": "Курская область",
"checked": true
},
{
"value": "Ленинградская область",
"label": "Ленинградская область",
"checked": true
},
{
"value": "Липецкая область",
"label": "Липецкая область",
"checked": true
},
{
"value": "Магаданская область",
"label": "Магаданская область",
"checked": true
},
{
"value": "Московская область",
"label": "Московская область",
"checked": true
},
{
"value": "Мурманская область",
"label": "Мурманская область",
"checked": true
},
{
"value": "Нижегородская область",
"label": "Нижегородская область",
"checked": true
},
{
"value": "Новгородская область",
"label": "Новгородская область",
"checked": true
},
{
"value": "Новосибирская область",
"label": "Новосибирская область",
"checked": true
},
{
"value": "Омская область",
"label": "Омская область",
"checked": true
},
{
"value": "Оренбургская область",
"label": "Оренбургская область",
"checked": true
},
{
"value": "Орловская область",
"label": "Орловская область",
"checked": true
},
{
"value": "Пензенская область",
"label": "Пензенская область",
"checked": true
},
{
"value": "Псковская область",
"label": "Псковская область",
"checked": true
},
{
"value": "Ростовская область",
"label": "Ростовская область",
"checked": true
},
{
"value": "Рязанская область",
"label": "Рязанская область",
"checked": true
},
{
"value": "Самарская область",
"label": "Самарская область",
"checked": true
},
{
"value": "Саратовская область",
"label": "Саратовская область",
"checked": true
},
{
"value": "Сахалинская область",
"label": "Сахалинская область",
"checked": true
},
{
"value": "Свердловская область",
"label": "Свердловская область",
"checked": true
},
{
"value": "Смоленская область",
"label": "Смоленская область",
"checked": true
},
{
"value": "Тамбовская область",
"label": "Тамбовская область",
"checked": true
},
{
"value": "Тверская область",
"label": "Тверская область",
"checked": true
},
{
"value": "Томская область",
"label": "Томская область",
"checked": true
},
{
"value": "Тульская область",
"label": "Тульская область",
"checked": true
},
{
"value": "Тюменская область",
"label": "Тюменская область",
"checked": true
},
{
"value": "Ульяновская область",
"label": "Ульяновская область",
"checked": true
},
{
"value": "Челябинская область",
"label": "Челябинская область",
"checked": true
},
{
"value": "Ярославская область",
"label": "Ярославская область",
"checked": true
},
{
"value": "Город Москва",
"label": "Город Москва",
"checked": true
},
{
"value": "Город Санкт-Петербург",
"label": "Город Санкт-Петербург",
"checked": true
},
{
"value": "Город Севастополь",
"label": "Город Севастополь",
"checked": true
},
{
"value": "Еврейская автономная область",
"label": "Еврейская автономная область",
"checked": true
},
{
"value": "Ненецкий автономный округ",
"label": "Ненецкий автономный округ",
"checked": true
},
{
"value": "Ханты-Мансийский автономный округ Югра",
"label": "Ханты-Мансийский автономный округ Югра",
"checked": true
},
{
"value": "Чукотский автономный округ",
"label": "Чукотский автономный округ",
"checked": true
},
{
"value": "Ямало-Ненецкий автономный округ",
"label": "Ямало-Ненецкий автономный округ",
"checked": true
}
]
},
{
"id": "id_support",
"name": "Форма поддержки",
"options": [
{
"value": 1,
"label": "ДПМ ВИЭ 1.0 (оптовый рынок)",
"checked": true
},
{
"value": 2,
"label": "ДПМ ВИЭ 2.0 (оптовый рынок)",
"checked": true
},
{
"value": 3,
"label": "Розничный рынок (с поддержкой)",
"checked": true
},
{
"value": 4,
"label": "Розничный рынок (без поддержки)",
"checked": true
},
{
"value": 5,
"label": "Оптовый рынок (без поддержки)",
"checked": true
},
{
"value": 6,
"label": "Собственная генерация промышленности",
"checked": true
},
{
"value": 7,
"label": "ВИЭ в изолированнных энергосистемах",
"checked": true
}
]
},
{
"id": "main_company_for_site",
"name": "Компания-владелец",
"options": [
{
"value": "ООО \"Вершина Девелопмент\"",
"label": "ООО \"Вершина Девелопмент\"",
"checked": true
},
{
"value": "АО \"НоваВинд\"",
"label": "АО \"НоваВинд\"",
"checked": true
},
{
"value": "ООО \"Ветропарки ФРВ\"",
"label": "ООО \"Ветропарки ФРВ\"",
"checked": true
},
{
"value": "ПАО \"ТГК-1\"",
"label": "ПАО \"ТГК-1\"",
"checked": true
},
{
"value": "ООО \"Солар Системс\"",
"label": "ООО \"Солар Системс\"",
"checked": true
},
{
"value": "ГК \"Хевел\"",
"label": "ГК \"Хевел\"",
"checked": true
},
{
"value": "ПАО \"ЭЛ5-Энерго\"",
"label": "ПАО \"ЭЛ5-Энерго\"",
"checked": true
},
{
"value": "ПАО \"Форвард Энерго\"",
"label": "ПАО \"Форвард Энерго\"",
"checked": true
},
{
"value": "Другие",
"label": "Другие",
"checked": true
}
]
},
{
"id": "year_commissioning_filter",
"name": "Год ввода в эксплуатацию",
"options": [
{
"value": "1905-2009",
"label": "1905-2009",
"checked": true
},
{
"value": "2010",
"label": "2010",
"checked": true
},
{
"value": "2011",
"label": "2011",
"checked": true
},
{
"value": "2012",
"label": "2012",
"checked": true
},
{
"value": "2013",
"label": "2013",
"checked": true
},
{
"value": "2014",
"label": "2014",
"checked": true
},
{
"value": "2015",
"label": "2015",
"checked": true
},
{
"value": "2016",
"label": "2016",
"checked": true
},
{
"value": "2017",
"label": "2017",
"checked": true
},
{
"value": "2018",
"label": "2018",
"checked": true
},
{
"value": "2019",
"label": "2019",
"checked": true
},
{
"value": "2020",
"label": "2020",
"checked": true
},
{
"value": "2021",
"label": "2021",
"checked": true
},
{
"value": "2022",
"label": "2022",
"checked": true
},
{
"value": "2023",
"label": "2023",
"checked": true
}
]
}
]
export default function Points({ mapOptions, onMapOptionClick }) {
const mapRef = useRef(null);
const [open, setOpen] = useState(false)
const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false);
const [popupInfo, setPopupInfo] = useState(null);
const [filters, setFilters] = useState(initialFilters);
const generatePopup = (info) => {
console.log(info)
return (
<div>
<img src={`/photos/${info.id_rreda_parc}.jpg`} className="mb-4 rounded" />
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{info.power_fact_parc_mw != null &&
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" className="px-2 py-4 font-medium text-gray-900 dark:text-white">
Установленная мощность
</th>
<td className="px-2 py-4">
{info.power_fact_parc_mw.toFixed(2).replace(".", ",")} МВт
</td>
</tr>
}
{info.year_commissioning &&
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" className="px-2 py-4 font-medium text-gray-900 dark:text-white">
Год ввода в эксплуатацию
</th>
<td className="px-2 py-4">
{info.year_commissioning}
</td>
</tr>
}
{info.year_qualification &&
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" className="px-2 py-4 font-medium text-gray-900 dark:text-white">
Год квалификации
</th>
<td className="px-2 py-4">
{info.year_qualification}
</td>
</tr>
}
{info.support_name &&
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" className="px-2 py-4 font-medium text-gray-900 dark:text-white">
Механизм поддержки
</th>
<td className="px-2 py-4">
{info.support_name}
</td>
</tr>
}
{info.region_name &&
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" className="px-2 py-4 font-medium text-gray-900 dark:text-white">
Регион размещения
</th>
<td className="px-2 py-4">
{info.region_name}
</td>
</tr>
}
{info.residence_area &&
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" className="px-2 py-4 font-medium text-gray-900 dark:text-white">
Район размещения
</th>
<td className="px-2 py-4">
{[info.residence_area, info.settlement, info.natural_object].filter(item => item).join(", ")}
</td>
</tr>
}
{info.main_owner_company &&
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" className="px-2 py-4 font-medium text-gray-900 dark:text-white">
Владелец объекта
</th>
<td className="px-2 py-4">
{info.current_owner_name && info.main_owner_company != info.current_owner_name ? `${info.current_owner_name} (${info.main_owner_company})` : info.main_owner_company}
</td>
</tr>
}
</tbody>
</table>
{Boolean(info.rreda_member) && info.company_link_rreda && <p className="text-sm mt-4 text-gray-600">Ссылка на компанию: <a href={info.company_link_rreda} target="_blank" className="text-indigo-800">{info.company_link_rreda}</a></p>}
{info.date_actualization && <p className="text-sm mt-1 text-gray-600">Дата актуализации: {info.date_actualization}</p>}
</div>
)
}
const clearAllOptions = (event) => {
event.preventDefault()
const newStateFilters = filters.map((filter) =>
filter.id == event.target.value
? {
...filter,
options: filter.options.map((option) => {
const newoption = { ...option, checked: false }
return (newoption)
})
}
: filter
)
setFilters(newStateFilters);
}
const addAllOptions = (event) => {
event.preventDefault();
const newStateFilters = filters.map((filter) =>
filter.id == event.target.value
? {
...filter,
options: filter.options.map((option) => {
const newoption = { ...option, checked: true }
return (newoption)
})
}
: filter
)
setFilters(newStateFilters);
}
const handleFilterToggle = function (event) {
const newStateFilters = filters.map((filter) =>
filter.id == event.target.name
? {
...filter,
options: filter.options.map((option) =>
option.value == event.target.defaultValue
? { ...option, checked: !option.checked }
: option
),
}
: filter
);
setFilters(newStateFilters);
};
const applyFilters = (filtersObj) => {
const checkedFilters = ["all", ...filtersObj.map((propertyFilter) => [
"in",
["get", propertyFilter.id],
["literal", propertyFilter.options.filter(option => option.checked).map(option => option.value)],
])]
return checkedFilters
};
const handleClick = (event) => {
setOpen(false)
setPopupInfo(null)
if (event.features[0]) {
console.log(event.features[0].geometry)
// event.originalEvent.stopPropagation();
setPopupInfo({
lon: event.features[0].geometry.coordinates[0],
lat: event.features[0].geometry.coordinates[1],
...event.features[0].properties
})
setOpen(true)
}
};
const handleMouseEnter = (event) => {
const feature = event.features[0];
if (!feature) return;
mapRef.current.getCanvas().style.cursor = "pointer";
};
const handleMouseLeave = (event) => {
const feature = event.features[0];
if (!feature) {
return;
}
mapRef.current.getCanvas().style.cursor = "";
};
return (
<div className="bg-white">
<div>
<main className="mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-baseline justify-between border-b border-gray-200 pt-24 pb-6">
<h1 className="text-4xl font-bold tracking-tight text-gray-900">
Объекты ВИЭ-генерации в регионах России
</h1>
<div className="flex items-center">
<Menu as="div" className="relative inline-block text-left">
<Menu.Button className="hidden group inline-flex justify-center text-sm font-medium text-gray-700 hover:text-gray-900">
{mapOptions.find((option) => option.current).name}
<ChevronDownIcon
className="-mr-1 ml-1 h-5 w-5 flex-shrink-0 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
show={true}
>
<Menu.Items className="absolute right-0 z-10 mt-2 w-40 origin-top-right rounded-md bg-white shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="py-1">
{mapOptions.map((option) => (
<Menu.Item key={option.name}>
<a
href="#"
className={option.current ? 'font-medium text-gray-900 block px-4 py-2 text-sm' : 'text-gray-500 block px-4 py-2 text-sm'}
onClick={onMapOptionClick}
>
{option.name}
</a>
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
</div>
</div>
<section aria-labelledby="products-heading" className="pt-6 pb-24">
<div className="grid grid-cols-1 gap-x-8 gap-y-10 md:grid-cols-4">
<form className="hidden md:block h-[65vh] px-1 py-1 overflow-y-scroll">
{/* Layers */}
<ul
role="list"
className="space-y-4 border-b border-gray-200 pb-6 text-sm font-medium text-gray-900"
>
{mapstyle.layers.map((layer) => (
<div key={layer.id} className="flex items-center">
<input
id={layer.id}
name={layer.id}
defaultValue={layer.id}
type="checkbox"
defaultChecked={true}
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
onChange={(event) => {
mapRef.current
.getMap()
.setLayoutProperty(
event.target.id,
"visibility",
event.target.checked ? "visible" : "none"
);
}}
/>
<label
htmlFor={layer.id}
className="ml-3 text-sm text-gray-600"
>
{layer.id}
</label>
</div>
))}
</ul>
{/* Legend */}
<Disclosure as="div" className="border-b border-gray-200 py-6">
{({ open }) => (
<>
<h3 className="-my-3 flow-root">
<Disclosure.Button className="flex w-full items-center justify-between bg-white py-3 text-sm text-gray-400 hover:text-gray-500">
<span className="font-medium text-gray-900">
Легенда
</span>
<span className="ml-6 flex items-center">
{open ? (
<ChevronUpIcon
className="h-5 w-5"
aria-hidden="true"
/>
) : (
<ChevronDownIcon
className="h-5 w-5"
aria-hidden="true"
/>
)}
</span>
</Disclosure.Button>
</h3>
<Disclosure.Panel className="pt-6">
<div className="space-y-4">
<p className="text-sm">Установленная мощность</p>
<div className="flex items-center"><span className="text-sm text-gray-600">{pointsSizes[0].value}</span><div className={"ml-3 rounded-full border-2 border-gray-400"} style={{ width: pointsSizes[0].size, height: pointsSizes[0].size }}></div><div className={`ml-5 rounded-full border-2 border-gray-400`} style={{ width: pointsSizes[1].size, height: pointsSizes[1].size }}></div><span className="ml-3 text-sm text-gray-600">{pointsSizes[1].value} МВт</span></div>
<p className="text-sm">ВИЭ-технология</p>
{pointsColors.map(e => <div key={e.name} className="flex items-center"><div className={"w-3 h-3 rounded-full"} style={{ backgroundColor: e.color }}></div><p className="ml-2 text-sm text-gray-600">{e.name}</p></div>)}
</div>
<div className="mt-4 space-y-4 text-xs text-gray-600">
<p >СЭС солнечные электростанции</p>
<p>ВЭС ветроэлектростанции</p>
<p>мГЭС малые гидроэлектростанции</p>
<p>БиоЭС (биомасса) биоэлектростанции на основе биомассы</p>
<p>БиоЭС (биогаз) биоэлектростанции на основе биогаза</p>
<p>БиоЭС (свалочный газ) биоэлектростанции на основе свалочного газа</p>
<p>ГеоЭС геотермальные электростанции</p>
<p>ПЭС приливные электростанции</p>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
{/* Filters */}
{filters.map((section) => (
<Disclosure
as="div"
key={section.id}
className="border-b border-gray-200 py-6"
>
{({ open }) => (
<>
<h3 className="-my-3 flow-root">
<Disclosure.Button className="flex w-full items-center justify-between bg-white py-3 text-sm text-gray-400 hover:text-gray-500">
<span className="font-medium text-gray-900">
{section.name}
</span>
<span className="ml-6 flex items-center">
{open ? (
<ChevronUpIcon
className="h-5 w-5"
aria-hidden="true"
/>
) : (
<ChevronDownIcon
className="h-5 w-5"
aria-hidden="true"
/>
)}
</span>
</Disclosure.Button>
</h3>
<Disclosure.Panel className="pt-4">
<button value={section.id} onClick={addAllOptions} className="text-sm pb-3 text-gray-500">Добавить все</button>
<span className="text-sm pb-3 text-gray-500"> / </span>
<button value={section.id} onClick={clearAllOptions} className="text-sm pb-3 text-gray-500">Убрать все</button>
<div className="space-y-4">
{section.options.map((option, optionIdx) => (
<div
key={option.value}
className="flex items-center"
>
<input
id={`filter-${section.id}-${optionIdx}`}
name={`${section.id}`}
defaultValue={option.value}
type="checkbox"
checked={option.checked}
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
onChange={handleFilterToggle}
/>
<label
htmlFor={`filter-${section.id}-${optionIdx}`}
className="ml-3 text-sm text-gray-600"
>
{option.label}
</label>
{pointsColors.find(color => color.name == option.label) && <div className={"w-3 h-3 rounded-full ml-2"} style={{ backgroundColor: pointsColors.find(color => color.name == option.label).color }}></div>}
</div>
))}
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
))}
{/* Metadata */}
<Disclosure as="div" className="border-b border-gray-200 py-6">
{({ open }) => (
<>
<h3 className="-my-3 flow-root">
<Disclosure.Button className="flex w-full items-center justify-between bg-white py-3 text-sm text-gray-400 hover:text-gray-500">
<span className="font-medium text-gray-900">
Метаданные
</span>
<span className="ml-6 flex items-center">
{open ? (
<ChevronUpIcon
className="h-5 w-5"
aria-hidden="true"
/>
) : (
<ChevronDownIcon
className="h-5 w-5"
aria-hidden="true"
/>
)}
</span>
</Disclosure.Button>
</h3>
<Disclosure.Panel className="pt-6">
<div className="space-y-4">
<p className="text-sm">
&copy; Ассоциация развития возобновляемой энергетики
</p>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
</form>
{/* Map itself */}
<div className="md:col-span-3">
<div className="h-[65vh]">
<Map
initialViewState={{
latitude: mapstyle.center[0],
longitude: mapstyle.center[1],
zoom: mapstyle.zoom,
}}
minZoom={mapstyle.minZoom}
ref={mapRef}
mapboxAccessToken={MAPBOX_TOKEN}
interactiveLayerIds={["Объекты"]}
onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{open && <Popup
longitude={popupInfo.lon}
latitude={popupInfo.lat}
closeButton={false}
>
<h3>{popupInfo.res_name_parc}</h3>
{popupInfo.region_name}
</Popup>}
<ScaleControl />
<Source
id="basemap"
tileSize={512}
{...mapstyle.sources.basemap}
>
<Layer {...paintedLayers["Подложка"]} />
</Source>
<Source
id="remap"
{...mapstyle.sources.remap}
>
<Layer {...paintedLayers["Границы"]} />
<Layer {...paintedLayers["Объекты"]} filter={applyFilters(filters)} />
</Source>
</Map>
</div>
</div>
</div>
</section>
</main>
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={setOpen}>
<Transition.Child
as={Fragment}
enter="ease-in-out duration-500"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in-out duration-500"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 overflow-hidden">
<div className="absolute inset-0 overflow-hidden">
<div className="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10">
<Transition.Child
as={Fragment}
enter="transform transition ease-in-out duration-500 sm:duration-700"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transform transition ease-in-out duration-500 sm:duration-700"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<Dialog.Panel className="pointer-events-auto relative w-screen max-w-md">
<Transition.Child
as={Fragment}
enter="ease-in-out duration-500"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in-out duration-500"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="absolute top-0 left-0 -ml-8 flex pt-4 pr-2 sm:-ml-10 sm:pr-4">
<button
type="button"
className="rounded-md text-gray-300 hover:text-white focus:outline-none focus:ring-2 focus:ring-white"
onClick={() => setOpen(false)}
>
<span className="sr-only">Close panel</span>
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
</Transition.Child>
<div className="flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl">
<div className="px-4 sm:px-6">
<Dialog.Title className="text-lg font-medium text-gray-900">{popupInfo && popupInfo.res_name_parc}</Dialog.Title>
</div>
<div className="relative mt-6 flex-1 px-4 sm:px-6">
{/* Replace with your content */}
{popupInfo && generatePopup(popupInfo)}
{/* /End replace */}
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</div>
</Dialog>
</Transition.Root>
</div>
</div>
);
}