import { LeftOutlined, PlusOutlined, RightOutlined } from '@ant-design/icons';
import { Button, Divider, Layout, Tooltip, message } from 'antd';
import { Archive, Building2, ScrollText, UserCog2, Users2 } from 'lucide-react';
import { type ReactNode, memo, useState } from 'react';
import { NavLink, useNavigate } from 'react-router-dom';
import { USERS_ADMIN } from '../../auth/permissions';
import { Logo } from '../../components/Logo';
import { createConsolidation } from '../../services/api/consolidations';
import { getConsolidationsListThunk } from '../../store/slices/consolidations/thunks';
import { useAppDispatch } from '../../store/store';
import { quarterLabel } from '../../utils/labels';
import { NewConsolidationModal } from '../NewConsoleModal/NewConsoleModal';
import styles from './styles.module.css';
type CollapsedIconProps = {
icon: ReactNode;
onClick?: () => void;
title: string;
to: string | null;
cn?: string;
};
function CollapsedIcon({ icon, onClick, title, to, cn = '' }: CollapsedIconProps) {
if (to === null) {
return (
{icon}
);
}
return (
cn || `${styles.iconBtn} ${isActive ? styles.iconBtnActive : styles.iconBtnNav}`}>
{icon}
);
}
type NavItem = {
link: string;
label: string;
icon?: ReactNode;
/** Право из `/me`, без которого пункт не показывается; нет — пункт виден всем. */
permission?: string;
};
type Group = {
title: string;
key: string;
children: NavItem[];
};
const config: Group[] = [
{
title: 'Отчётность',
key: 'reporting',
children: [
{
link: '/groups',
label: 'Группы компаний',
},
{
link: '/groups/monozaemchiki',
label: 'Монозаемщики',
},
],
},
{
title: 'Справочники',
key: 'catalogues',
children: [
{
link: '/catalogue/groups',
icon: ,
label: 'ГК и организации',
},
{
link: '/catalogue/jur_l',
icon: ,
label: 'ЮЛ вне ГК',
},
],
},
{
title: 'Документы',
key: 'docs',
children: [
{
link: '/docstorage',
icon: ,
label: 'Единое хранилище',
},
],
},
{
title: 'Система',
key: 'system',
children: [
{
link: '/logging',
icon: ,
label: 'Журнал действий',
},
{
link: '/admin',
icon: ,
label: 'Пользователи и роли',
permission: USERS_ADMIN,
},
],
},
];
function NavLinkStyled({ to, children }: { to: string; children: ReactNode }) {
return (
{
return `${styles.linkBase} ${isActive ? styles.linkActive : ''}`;
}}
to={to}
end>
{children}
);
}
const Section = memo(function Section({ isCollapsed, group }: { isCollapsed: boolean; group: Group }) {
return !isCollapsed ? (
{group.title}
{group.children.map((i) => (
{i.icon}
{i.label}
))}
) : (
<>
{group.children.map((i) => (
))}
>
);
});
export function Sidebar() {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const [modalOpen, setModalOpen] = useState(false);
const [isCollapsed, setIsCollapsed] = useState(false);
return (
{!isCollapsed && }
setIsCollapsed(!isCollapsed)}>
{isCollapsed ? : }
{isCollapsed ? (
}
cn={`${styles.iconBtn} ${styles.iconBtnAction}`}
to={null}
title='Новая консолидация'
onClick={() => {
setModalOpen(true);
}}
/>
) : (
<>
{
setModalOpen(true);
}}>
Новая консолидация
>
)}
{config.map((g) => (
))}
{
setModalOpen(false);
}}
onOk={async (values) => {
const card = await createConsolidation(values);
// перечитываем список: на странице группы он сам не обновится, и новая консолидация не станет текущей
// in_work_only: false — переход ниже открывает список без ?in_work_only (флажок выключен)
await dispatch(getConsolidationsListThunk({ company_group_id: values.company_group_id, in_work_only: false }));
setModalOpen(false);
message.success(`Создана консолидация ${values.year}, ${quarterLabel(values.quarter)}`);
navigate(`/groups/${values.company_group_id}?version=${card.id}`);
}}
/>
);
}