187 lines
6.1 KiB
TypeScript
187 lines
6.1 KiB
TypeScript
import { useEffect, useMemo, useState } from "react";
|
|
import { Input, List, Spin, Empty, Typography, Tag } from "antd";
|
|
import { FolderOpenOutlined, SearchOutlined } from "@ant-design/icons";
|
|
import { useAppDispatch, useAppSelector } from "../../store/store";
|
|
import { getCompanyGroupsThunk } from "../../store/slices/companyGroupsSlice/thunks";
|
|
import { setActiveCompanyGroup } from "../../store/slices/companyGroupsSlice/companyGroupsSlice";
|
|
|
|
const { Text } = Typography;
|
|
|
|
export const CompanyGroupsList = () => {
|
|
const dispatch = useAppDispatch();
|
|
|
|
const rawRows = useAppSelector((state) => state.company_groups.raw_rows);
|
|
const loading = useAppSelector((state) => state.company_groups.loading);
|
|
const activeCompanyGroup = useAppSelector(
|
|
(state) => state.company_groups.activeCompanyGroup,
|
|
);
|
|
|
|
const [query, setQuery] = useState("");
|
|
|
|
const filtered = useMemo(() => {
|
|
const q = query.trim().toLowerCase();
|
|
if (!q) return rawRows;
|
|
return rawRows.filter(
|
|
(g) =>
|
|
g.name.toLowerCase().includes(q) || g.crm_id?.toLowerCase().includes(q),
|
|
);
|
|
}, [rawRows, query]);
|
|
|
|
useEffect(() => {
|
|
dispatch(getCompanyGroupsThunk());
|
|
}, [dispatch]);
|
|
|
|
useEffect(() => {
|
|
if (!activeCompanyGroup && rawRows?.length) {
|
|
dispatch(setActiveCompanyGroup(rawRows?.[0]));
|
|
}
|
|
}, [rawRows, activeCompanyGroup]);
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
height: "100%",
|
|
background: "#fff",
|
|
borderRight: "1px solid #f0f0f0",
|
|
borderRadius: 12,
|
|
}}
|
|
>
|
|
<div style={{ padding: "12px 16px", borderBottom:"1px solid #0f172a0f" }}>
|
|
<Input
|
|
allowClear
|
|
prefix={<SearchOutlined style={{ color: "#bfbfbf" }} />}
|
|
placeholder={"Поиск по ЮЛ или ГСК"}
|
|
value={query}
|
|
onChange={(e) => setQuery(e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div style={{ flex: 1, overflowY: "auto", padding: "10px" }}>
|
|
{loading ? (
|
|
<div style={{ textAlign: "center", padding: 24 }}>
|
|
<Spin />
|
|
</div>
|
|
) : filtered.length === 0 ? (
|
|
<Empty
|
|
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
|
description="Компании и организации не найдены"
|
|
style={{ marginTop: 32 }}
|
|
/>
|
|
) : (
|
|
<List
|
|
dataSource={filtered}
|
|
split={false}
|
|
renderItem={(item) => {
|
|
const active = item.id === activeCompanyGroup?.id;
|
|
return (
|
|
<List.Item
|
|
onClick={() => dispatch(setActiveCompanyGroup(item))}
|
|
style={{
|
|
cursor: "pointer",
|
|
borderRadius: 8,
|
|
padding: "10px 12px",
|
|
marginBottom: 4,
|
|
background: active ? "#e6f4ea" : "transparent",
|
|
boxShadow: active
|
|
? "inset 0 0 0 1px #2ea64b3d, inset 3px 0 0 #258141"
|
|
: "inset 0 0 0 1px #0f172a14",
|
|
transition: "background 0.15s",
|
|
}}
|
|
onMouseEnter={(e) => {
|
|
if (!active) {
|
|
(e.currentTarget as HTMLElement).style.background =
|
|
"#fafafa";
|
|
}
|
|
}}
|
|
onMouseLeave={(e) => {
|
|
if (!active) {
|
|
(e.currentTarget as HTMLElement).style.background =
|
|
"transparent";
|
|
}
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
alignItems: "center",
|
|
width: "100%",
|
|
gap: 12,
|
|
minWidth: 0,
|
|
}}
|
|
>
|
|
<Tag
|
|
style={{
|
|
borderRadius: 8,
|
|
width: 28,
|
|
height: 28,
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
}}
|
|
color={"success"}
|
|
>
|
|
<FolderOpenOutlined
|
|
style={{
|
|
fontSize: 18,
|
|
color: "green",
|
|
flexShrink: 0,
|
|
}}
|
|
/>
|
|
</Tag>
|
|
|
|
<div style={{ flex: 1, minWidth: 0 }}>
|
|
<Text
|
|
strong
|
|
ellipsis
|
|
style={{
|
|
display: "block",
|
|
fontSize: 14,
|
|
lineHeight: "20px",
|
|
}}
|
|
>
|
|
{item.name}
|
|
</Text>
|
|
<Text
|
|
type="secondary"
|
|
ellipsis
|
|
style={{
|
|
display: "block",
|
|
fontSize: 12,
|
|
lineHeight: "16px",
|
|
}}
|
|
>
|
|
CRM ID: {item.crm_id ?? "-"}
|
|
</Text>
|
|
</div>
|
|
|
|
<Tag
|
|
style={{
|
|
margin: 0,
|
|
borderRadius: 10,
|
|
background: "#f5f5f5",
|
|
border: "none",
|
|
color: "#595959",
|
|
fontWeight: 500,
|
|
minWidth: 24,
|
|
height: 20,
|
|
lineHeight: "20px",
|
|
textAlign: "center",
|
|
padding: "0 8px",
|
|
flexShrink: 0,
|
|
}}
|
|
>
|
|
{item.legal_entities_count}
|
|
</Tag>
|
|
</div>
|
|
</List.Item>
|
|
);
|
|
}}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|