parent
7ac62be115
commit
e775c07c63
@ -1,7 +1,7 @@
|
|||||||
import { AutoComplete, Input } from "antd";
|
import { AutoComplete, Input } from "antd";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { SearchOutlined } from "@ant-design/icons";
|
import { SearchOutlined } from "@ant-design/icons";
|
||||||
import { api } from "../../api";
|
import { api } from "../api";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { useMap } from "react-map-gl";
|
import { useMap } from "react-map-gl";
|
||||||
import parse from "wellknown";
|
import parse from "wellknown";
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { Button } from "antd";
|
import { Button } from "antd";
|
||||||
import { FiltersIcon } from "../../icons/FiltersIcon";
|
import { FiltersIcon } from "../icons/FiltersIcon";
|
||||||
|
|
||||||
export const FiltersButton = ({ toggleCollapse }) => {
|
export const SidebarControl = ({ toggleCollapse }) => {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
icon={<FiltersIcon width={16} height={16} />}
|
icon={<FiltersIcon width={16} height={16} />}
|
||||||
@ -1,22 +1,33 @@
|
|||||||
import { Button } from "antd";
|
import { Button, Popover } from "antd";
|
||||||
import { LogoutOutlined } from "@ant-design/icons";
|
import { LogoutOutlined } from "@ant-design/icons";
|
||||||
import { setAuth } from "./stores/auth";
|
|
||||||
import { api } from "./api";
|
import { api } from "./api";
|
||||||
|
import { setAuth } from "./stores/auth";
|
||||||
|
|
||||||
export function SignOut() {
|
export function SignOut() {
|
||||||
|
const logOut = async () => {
|
||||||
|
await api.post("accounts/logout/");
|
||||||
|
|
||||||
|
setAuth(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute top-[20px] right-[20px]">
|
<div className="absolute top-[20px] right-[20px]">
|
||||||
|
<Popover
|
||||||
|
content={
|
||||||
|
<Button type={"primary"} onClick={logOut}>
|
||||||
|
Выйти
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
trigger="click"
|
||||||
|
placement={"bottomRight"}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
icon={<LogoutOutlined />}
|
icon={<LogoutOutlined />}
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
title="Выйти"
|
title="Выйти"
|
||||||
onClick={async () => {
|
|
||||||
await api.post("accounts/logout/");
|
|
||||||
|
|
||||||
setAuth(false);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,63 @@
|
|||||||
|
import { RegionSelect } from "./RegionSelect";
|
||||||
|
import { CategoriesSelect } from "./InitialSidebar/CategoriesSelect";
|
||||||
|
import { PredictionSlider } from "./InitialSidebar/PredictionSlider";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Tooltip } from "antd";
|
||||||
|
import { DISABLED_FILTER_TEXT, MODES } from "../../config";
|
||||||
|
import { useMode } from "../../stores/useMode";
|
||||||
|
import { DeltaTrafficSlider } from "./WorkingFilters/DeltaSlider";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { api } from "../../api";
|
||||||
|
import { FactTrafficSlider } from "./WorkingFilters/FactTrafficSlider";
|
||||||
|
import { AgeSlider } from "./WorkingFilters/AgeSlider";
|
||||||
|
|
||||||
|
export const Filters = ({ disabled }) => {
|
||||||
|
const [hover, setHover] = useState(false);
|
||||||
|
const { mode } = useMode();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => setHover(false), 1500);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [hover]);
|
||||||
|
|
||||||
|
const { data: fullRange } = useQuery(["max-min"], async () => {
|
||||||
|
const { data } = await api.get(`/api/placement_points/filters/`);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
setHover(true);
|
||||||
|
};
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
setHover(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
title={DISABLED_FILTER_TEXT}
|
||||||
|
placement="right"
|
||||||
|
open={disabled && hover}
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
>
|
||||||
|
<div className="space-y-5">
|
||||||
|
<RegionSelect disabled={disabled} />
|
||||||
|
{mode === MODES.INITIAL && (
|
||||||
|
<>
|
||||||
|
<CategoriesSelect disabled={disabled} />
|
||||||
|
<PredictionSlider disabled={disabled} fullRange={fullRange} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{mode === MODES.WORKING && (
|
||||||
|
<div className={"space-y-12"}>
|
||||||
|
<DeltaTrafficSlider fullRange={fullRange} />
|
||||||
|
<FactTrafficSlider fullRange={fullRange} />
|
||||||
|
<AgeSlider fullRange={fullRange} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -1,45 +0,0 @@
|
|||||||
import { RegionSelect } from "../RegionSelect";
|
|
||||||
import { CategoriesSelect } from "./CategoriesSelect";
|
|
||||||
import { PredictionSlider } from "./PredictionSlider";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { Tooltip } from "antd";
|
|
||||||
import { DISABLED_FILTER_TEXT, MODES } from "../../../config";
|
|
||||||
import { useMode } from "../../../stores/useMode";
|
|
||||||
|
|
||||||
export const Filters = ({ disabled }) => {
|
|
||||||
const [hover, setHover] = useState(false);
|
|
||||||
const { mode } = useMode();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const timer = setTimeout(() => setHover(false), 1500);
|
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, [hover]);
|
|
||||||
|
|
||||||
const handleMouseEnter = () => {
|
|
||||||
setHover(true);
|
|
||||||
};
|
|
||||||
const handleMouseLeave = () => {
|
|
||||||
setHover(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tooltip
|
|
||||||
title={DISABLED_FILTER_TEXT}
|
|
||||||
placement="right"
|
|
||||||
open={disabled && hover}
|
|
||||||
onMouseEnter={handleMouseEnter}
|
|
||||||
onMouseLeave={handleMouseLeave}
|
|
||||||
>
|
|
||||||
<div className="space-y-5">
|
|
||||||
<RegionSelect disabled={disabled} />
|
|
||||||
{mode === MODES.INITIAL && (
|
|
||||||
<>
|
|
||||||
<CategoriesSelect disabled={disabled} />
|
|
||||||
<PredictionSlider disabled={disabled} />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
import { INITIAL, useFilters } from "../../../stores/useFilters";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { SliderComponent as Slider } from "../../../components/SliderComponent";
|
||||||
|
|
||||||
|
export const AgeSlider = ({ fullRange }) => {
|
||||||
|
const {
|
||||||
|
filters: { age },
|
||||||
|
setAge,
|
||||||
|
} = useFilters();
|
||||||
|
|
||||||
|
const handleAfterChange = (range) => setAge(range);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!fullRange) return;
|
||||||
|
|
||||||
|
const min = fullRange.age_day[0];
|
||||||
|
const max = fullRange.age_day[1];
|
||||||
|
|
||||||
|
if (age[0] === INITIAL.age[0] && age[1] === INITIAL.age[1]) {
|
||||||
|
setAge([min, max]);
|
||||||
|
}
|
||||||
|
}, [fullRange, age]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Slider
|
||||||
|
title={"Зреслость постамата, дней"}
|
||||||
|
value={age}
|
||||||
|
onAfterChange={handleAfterChange}
|
||||||
|
min={fullRange?.age_day[0]}
|
||||||
|
max={fullRange?.age_day[1]}
|
||||||
|
range
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
import { INITIAL, useFilters } from "../../../stores/useFilters";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { SliderComponent as Slider } from "../../../components/SliderComponent";
|
||||||
|
|
||||||
|
export const FactTrafficSlider = ({ fullRange }) => {
|
||||||
|
const {
|
||||||
|
filters: { factTraffic },
|
||||||
|
setFactTraffic,
|
||||||
|
} = useFilters();
|
||||||
|
|
||||||
|
const handleAfterChange = (range) => setFactTraffic(range);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!fullRange) return;
|
||||||
|
|
||||||
|
const min = fullRange.fact[0];
|
||||||
|
const max = fullRange.fact[1];
|
||||||
|
|
||||||
|
if (
|
||||||
|
factTraffic[0] === INITIAL.factTraffic[0] &&
|
||||||
|
factTraffic[1] === INITIAL.factTraffic[1]
|
||||||
|
) {
|
||||||
|
setFactTraffic([min, max]);
|
||||||
|
}
|
||||||
|
}, [fullRange, factTraffic]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Slider
|
||||||
|
title={"Фактический трафик"}
|
||||||
|
value={factTraffic}
|
||||||
|
onAfterChange={handleAfterChange}
|
||||||
|
min={fullRange?.fact[0]}
|
||||||
|
max={fullRange?.fact[1]}
|
||||||
|
range
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
Loading…
Reference in new issue