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.
137 lines
4.7 KiB
137 lines
4.7 KiB
import { Button, Spin, Tooltip } from "antd";
|
|
import { CATEGORIES, MODES, STATUSES } from "../../config";
|
|
import { useMode } from "../../stores/useMode";
|
|
import { LAYER_IDS } from "../Layers/constants";
|
|
import { PopupWrapper } from "./PopupWrapper";
|
|
import { PendingPointPopup } from "./mode-popup/PendingPointPopup";
|
|
import { OnApprovalPointPopup } from "./mode-popup/OnApprovalPointPopup";
|
|
import { WorkingPointPopup } from "./mode-popup/WorkingPointPopup";
|
|
import { FeatureProperties } from "./mode-popup/FeatureProperties";
|
|
import { usePopup } from "../../stores/usePopup.js";
|
|
import { PanoramaIcon } from "../../icons/PanoramaIcon";
|
|
import { useGetPopupPoints } from "../../api.js";
|
|
import { doesMatchFilter } from "../../utils.js";
|
|
import Checkbox from "antd/es/checkbox/Checkbox";
|
|
import { usePointSelection } from "../../stores/usePointSelection.js";
|
|
import { usePendingPointsFilters } from "../../stores/usePendingPointsFilters.js";
|
|
|
|
const SingleFeaturePopup = ({ feature, point }) => {
|
|
const { mode } = useMode();
|
|
const isRivals =
|
|
feature.layer?.id.includes(LAYER_IDS.pvz) ||
|
|
feature.layer?.id.includes(LAYER_IDS.other);
|
|
const isPendingPoint = feature.properties.status === STATUSES.pending;
|
|
const isWorkingPoint = feature.properties.status === STATUSES.working;
|
|
|
|
if (isRivals) {
|
|
return <FeatureProperties feature={feature} point={point} />;
|
|
}
|
|
|
|
if (mode === MODES.ON_APPROVAL && !isPendingPoint) {
|
|
return <OnApprovalPointPopup feature={feature} point={point} />;
|
|
}
|
|
|
|
if (mode === MODES.WORKING && isWorkingPoint) {
|
|
return <WorkingPointPopup feature={feature} point={point} />;
|
|
}
|
|
|
|
if (mode === MODES.PENDING && isPendingPoint)
|
|
return <PendingPointPopup feature={feature} point={point} />;
|
|
|
|
return <FeatureProperties feature={feature} point={point} />;
|
|
};
|
|
|
|
const MultipleFeaturesPopup = ({ features, points }) => {
|
|
const { setPopup } = usePopup();
|
|
const { selection, include, exclude } = usePointSelection();
|
|
const { filters, ranges } = usePendingPointsFilters();
|
|
|
|
return (
|
|
<div className="space-y-2 p-1">
|
|
{features.map((feature) => {
|
|
const featureId = feature.properties.id;
|
|
const point = points.find(p => p.id === featureId);
|
|
const isSelected = (doesMatchFilter(filters, ranges, feature) && !selection.excluded.has(featureId)) ||
|
|
selection.included.has(featureId);
|
|
const handleSelect = () => {
|
|
if (isSelected) {
|
|
exclude(featureId);
|
|
} else {
|
|
include(featureId);
|
|
}
|
|
};
|
|
return (
|
|
<div className="flex flex-row items-center gap-2 w-full">
|
|
{feature.properties.status === STATUSES.pending && (
|
|
<Checkbox
|
|
checked={isSelected}
|
|
onClick={handleSelect}
|
|
/>
|
|
)}
|
|
|
|
<Button
|
|
className="text-start flex-1 !w-0"
|
|
block
|
|
onClick={() => {
|
|
setPopup({
|
|
features: [feature],
|
|
coordinates: feature.geometry.coordinates,
|
|
});
|
|
}}
|
|
key={feature.properties.id}
|
|
>
|
|
{feature.properties.category === CATEGORIES.residential || feature.layer.id === LAYER_IDS.working ? (
|
|
<div className="space-x-2 flex items-center w-full">
|
|
<span className="flex-1 truncate inline-block">
|
|
{point.address}
|
|
</span>
|
|
<span>{point.name}</span>
|
|
</div>
|
|
) : (
|
|
<div className="flex w-full">
|
|
<span className="truncate">
|
|
{point.name ?? point.category}
|
|
{point.category_id && getRivalsName(feature).name}
|
|
</span>
|
|
</div>
|
|
)}
|
|
</Button>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const YandexPanoramaLink = ({ lat, lng }) => {
|
|
const link = `https://yandex.ru/maps/?panorama[point]=${lng},${lat}`
|
|
return (
|
|
<div className="pl-1 flex">
|
|
<Tooltip title="Перейти на Яндекс.Панорамы">
|
|
<a target="_blank" href={link}>
|
|
<PanoramaIcon />
|
|
</a>
|
|
</Tooltip>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export const MapPopup = ({ features, lat, lng, onClose }) => {
|
|
const {data: points, isLoading} = useGetPopupPoints(features);
|
|
|
|
const getContent = () => {
|
|
if (features.length === 1) {
|
|
return <SingleFeaturePopup feature={features[0]} point={points[0]}/>;
|
|
}
|
|
|
|
return <MultipleFeaturesPopup features={features} points={points} />;
|
|
};
|
|
|
|
return (
|
|
<PopupWrapper lat={lat} lng={lng} onClose={onClose}>
|
|
<YandexPanoramaLink lat={lat} lng={lng}/>
|
|
{isLoading ? <Spin /> : getContent()}
|
|
</PopupWrapper>
|
|
);
|
|
};
|