import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { NameTask, TaskInfoContainer } from '../../components/common/SwitchFormTask/SwitchFormTask.style';
import { Box, CircularProgress, Stack } from '@mui/material';
import { toast } from 'react-toastify';
import { DictVspApi } from '../../api/dict-vsp';
import { SspApi } from '../../api/ssp';
import { useAuth } from '../../app/context/AuthProvider';
import { BackButton } from '../../components/common/Buttons/BackButton';
import { HeaderPortal } from '../../components/common/HeaderPortal';
import { ROLES_NAME_ID } from '../../constants/constants';
import { PageContainer } from '../../components/common/PageContainer';
import DictVspFilters from './components/DictVspFilters';
import DictVspModals from './components/DictVspModals';
import TableDictVsp from './components/TableDictVsp';
import { buildVspListParams, vspMatchesStatus } from './utils/vspListParams';
const DictVspInfo = () => {
const portalContent = (
Справочник
);
return {portalContent};
};
function DictVspPage() {
const [isLoading, setIsLoading] = useState(true);
const [dictVspData, setDictVspData] = useState([]);
const [ssps, setSsps] = useState([]);
const [selectedSsp, setSelectedSsp] = useState(null);
// AURORA-1883: статус ВСП и период закрытия; список ВСП перезагружается с сервера при их смене.
const [status, setStatus] = useState('active');
const [closeDates, setCloseDates] = useState({ closeDateStart: '', closeDateEnd: '' });
const [isListLoading, setIsListLoading] = useState(true);
const listRequestRef = useRef(0);
const { user } = useAuth();
const modalsRef = useRef(null);
const listFilter = useMemo(() => ({ status, ...closeDates }), [status, closeDates]);
const loadVspList = useCallback(async () => {
if (!user) return;
const requestId = ++listRequestRef.current;
setIsListLoading(true);
try {
const vspResponse = await DictVspApi.get(buildVspListParams(listFilter));
if (requestId !== listRequestRef.current) return;
if (!vspResponse.success) {
toast.error('Ошибка загрузки справочника');
return;
}
setDictVspData(vspResponse.result || []);
} catch (error) {
if (requestId !== listRequestRef.current) return;
toast.error(error.response?.data?.message || 'Ошибка загрузки справочника');
} finally {
if (requestId === listRequestRef.current) setIsListLoading(false);
}
}, [user, listFilter]);
useEffect(() => {
loadVspList();
}, [loadVspList]);
const loadData = useCallback(async () => {
if (!user) return;
setIsLoading(true);
try {
const isAdmin = user.role_id === ROLES_NAME_ID.admin;
const sspResponse = isAdmin ? await SspApi.getAll({ is_active: true }) : null;
if (isAdmin) {
if (!sspResponse.success) {
toast.error('Ошибка загрузки списка ССП');
return;
}
setSsps(sspResponse.result);
} else {
setSsps(user.org_units ?? []);
}
} catch (error) {
console.error('Error loading data:', error);
toast.error(error.response?.data?.message || 'Ошибка загрузки данных');
} finally {
setIsLoading(false);
}
}, [user]);
useEffect(() => {
loadData();
}, [loadData]);
const handleAdd = useCallback(
async (formData) => {
try {
const response = await DictVspApi.create(formData);
if (response.success) {
toast.success('ВСП успешно создан');
if (vspMatchesStatus(response.result, status)) {
setDictVspData((prev) => [...prev, response.result]);
}
} else {
toast.error(response.message || 'Ошибка создания ВСП');
}
} catch (error) {
console.error('Error adding VSP:', error);
toast.error(error.response?.data?.message || 'Ошибка создания ВСП');
throw error;
}
},
[status],
);
const handleEdit = useCallback(
async (formData) => {
try {
const response = await DictVspApi.update(formData.id, formData);
if (response.success) {
toast.success('ВСП успешно обновлен');
// AURORA-1883: ВСП, переставший подходить под статус (например, закрыт в «Действующих»), уходит из списка.
setDictVspData((prev) => {
const rest = prev.filter((v) => v.id !== formData.id);
return vspMatchesStatus(response.result, status) ? [...rest, response.result] : rest;
});
} else {
toast.error(response.message || 'Ошибка обновления ВСП');
}
} catch (error) {
console.error('Error editing VSP:', error);
toast.error(error.response?.data?.message || 'Ошибка обновления ВСП');
throw error;
}
},
[status],
);
const handleDelete = useCallback(async (vspId) => {
try {
const response = await DictVspApi.delete(vspId);
if (response.success) {
toast.success('ВСП успешно удален');
setDictVspData((prev) => [...prev.filter((v) => v.id !== vspId)]);
} else {
toast.error(response.message || 'Ошибка удаления ВСП');
}
} catch (error) {
console.error('Error deleting VSP:', error);
toast.error(error.response?.data?.message || 'Ошибка удаления ВСП');
throw error;
}
}, []);
const handleAddClick = useCallback(() => modalsRef.current?.openAdd(), []);
const handleEditClick = useCallback((item) => modalsRef.current?.openEdit(item), []);
const handleExportClick = useCallback(() => modalsRef.current?.openExport(), []);
if (isLoading) {
return (
<>
>
);
}
return (
<>
{/* */}
>
);
}
export default DictVspPage;