parent
958726e783
commit
057a9416b5
@ -0,0 +1,82 @@
|
|||||||
|
import { AutoComplete, Input } from "antd";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { SearchOutlined } from "@ant-design/icons";
|
||||||
|
import { api } from "../../api";
|
||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { useMap } from "react-map-gl";
|
||||||
|
import parse from "wellknown";
|
||||||
|
|
||||||
|
function useDebounce(value, delay) {
|
||||||
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => setDebouncedValue(value), delay || 500);
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
};
|
||||||
|
}, [value, delay]);
|
||||||
|
|
||||||
|
return debouncedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddressSearch = () => {
|
||||||
|
const { map } = useMap();
|
||||||
|
const [value, setValue] = useState("");
|
||||||
|
const debouncedValue = useDebounce(value);
|
||||||
|
|
||||||
|
const { data } = useQuery(["address", debouncedValue], async () => {
|
||||||
|
const result = await api.get(
|
||||||
|
`/api/placement_points/search_address?page_size=100&address=${debouncedValue}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = useMemo(() => {
|
||||||
|
if (!data) return [];
|
||||||
|
|
||||||
|
return data.results.map((item) => ({
|
||||||
|
label: item.address,
|
||||||
|
value: `${item.address}$${item.location_id}`,
|
||||||
|
item: item,
|
||||||
|
}));
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
const handleChange = (value) => {
|
||||||
|
if (!value) {
|
||||||
|
setValue(value);
|
||||||
|
} else {
|
||||||
|
setValue(value.split("$")[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelect = (_value, option) => {
|
||||||
|
const geometry = parse(option.item.geometry);
|
||||||
|
map.flyTo({
|
||||||
|
center: [geometry.coordinates[0], geometry.coordinates[1]],
|
||||||
|
zoom: 15,
|
||||||
|
speed: 5,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="absolute top-[20px] left-[360px]">
|
||||||
|
<AutoComplete
|
||||||
|
options={options}
|
||||||
|
style={{
|
||||||
|
width: 300,
|
||||||
|
}}
|
||||||
|
value={value}
|
||||||
|
onChange={handleChange}
|
||||||
|
onSelect={handleSelect}
|
||||||
|
allowClear={true}
|
||||||
|
onClear={() => setValue("")}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
prefix={<SearchOutlined />}
|
||||||
|
placeholder="Введите адрес точки"
|
||||||
|
className="text-ellipsis"
|
||||||
|
/>
|
||||||
|
</AutoComplete>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
import { Radio } from "antd";
|
||||||
|
import { MODES } from "../../config";
|
||||||
|
import { useMode } from "../../stores/useMode";
|
||||||
|
|
||||||
|
const modeOptions = [
|
||||||
|
{
|
||||||
|
label: "ЛКР",
|
||||||
|
value: MODES.INITIAL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "ЛВР",
|
||||||
|
value: MODES.APPROVE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "РП",
|
||||||
|
value: MODES.WORKING,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Header = () => {
|
||||||
|
const { mode, setMode } = useMode();
|
||||||
|
|
||||||
|
const handleModeChange = ({ target: { value } }) => setMode(value);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-4">
|
||||||
|
<Radio.Group
|
||||||
|
options={modeOptions}
|
||||||
|
onChange={handleModeChange}
|
||||||
|
value={mode}
|
||||||
|
optionType="button"
|
||||||
|
buttonStyle="solid"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { create } from "zustand";
|
||||||
|
import { immer } from "zustand/middleware/immer";
|
||||||
|
import { MODES } from "../config";
|
||||||
|
|
||||||
|
const store = (set) => ({
|
||||||
|
mode: MODES.INITIAL,
|
||||||
|
|
||||||
|
setMode: (mode) => {
|
||||||
|
set((state) => {
|
||||||
|
state.mode = mode;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useMode = create(immer(store));
|
||||||
Loading…
Reference in new issue