File "ModelsPage.tsx"
Full Path: /var/www/html/gitep_front/src/pages/ModelsPage/ModelsPage.tsx
File size: 12.53 KB
MIME-type: text/x-java
Charset: utf-8
import {Button, Flex, Segmented, Tag, Typography} from 'antd'
import styles from './ModelsPage.module.scss'
import React, {useEffect, useState} from 'react'
import {ModelsTable} from '@/entities/models/ui/ModelsTable/ModelsTable'
import {getModels} from '@/entities/models/api/getModels'
import {useParams} from 'react-router-dom'
import {ModalEditModel} from '@/entities/models/ui/ModelsTable/ModalEditModel/ModalEditModel'
import {getDetailModel} from '@/entities/models/api/getDetailModel'
import {postEditModel} from '@/entities/models/api/postEditModel'
import {useLocation} from 'react-router-dom'
import {updateModel} from '@/shared/model/model/events'
import {$roleStore, $permissionStore} from "@features/roles/store/stores"
import {useUnit} from "effector-react";
import {Helmet} from "react-helmet";
import { DrawerComponent } from "@/shared/ui/DrawerComponent/DrawerComponent";
import { AccountContentDrawer } from "@/entities/models/ui/AccountContentDrawer/AccountContentDrawer"
import { ContragentContentDrawer } from "@/entities/models/ui/ContragentContentDrawer/ContragentContentDrawer";
import { OrganizationContentDrawer } from "@/entities/models/ui/OrganizationContentDrawer/OrganizationContentDrawer";
import File from "@shared/assets/images/icons/file-add.svg?react";
export const ModelsPage = () => {
const roleStore = useUnit($roleStore).role;
const [isOpenEditModal, setIsOpenEditModal] = useState(false);
const [segmentTab, setSegmentTab] = useState("score");
const [activeData, setActiveData] = useState<any>({count: 0, models: []});
const [archiveData, setArchiveData] = useState<any>({count: 0, models: []});
const [cashData, setCashData] = useState<any>({count: 0, models: []});
const [pendingOpenModal, setPendingOpenModal] = useState(false);
const [IsEditablebyRole, setIsEditableByRole] = useState(true);
const [detailDrawerVisible, setDetailDrawerVisible] = useState(false);
const [contragentDrawerVisible, setContragentDrawerVisible] = useState(false);
const [organizationDrawerVisible, setOrganizationDrawerVisible] = useState(false);
const [scoreDetail, setScoreDetail]: any = useState({});
const [contragentDetail, setContragentDetail]: any = useState({});
const [organizationDetail, setOrganizationDetail]: any = useState({});
const [isNew, setIsNew] = useState(false);
useEffect(() => {
setSegmentTab(
roleStore === 'accountant' || roleStore === 'superAdmin'
? 'score'
: 'counterparty'
);
}, []);
useEffect(() => {
setSegmentTab(
roleStore === 'accountant' || roleStore === 'superAdmin'
? 'score'
: 'counterparty'
);
}, [roleStore]);
const [modelInfo, setModelInfo] = useState({
name: "",
description: "",
monthEnd: "",
dayPayment: ""
})
const [modelDetail, setModelDetail]: any = useState({})
const {modelId} = useParams<{ modelId: any }>();
const handleSegmentChange = (value: string) => {
setSegmentTab(value)
};
const getModelPage = async () => {
try {
const res = await getModels(parseInt(modelId), segmentTab);
const model = await getDetailModel(modelId);
setModelDetail(model);
setModelInfo({
name: res.model_data.name || "Название модели",
description: res.model_data.description || "Описание не указано",
monthEnd: res.model_data.month_end || "Не указан",
dayPayment: res.model_data.day_payment || "Не указан"
});
const transformData = (data: any[]) => {
if (!data) return [];
switch (segmentTab) {
case 'integration':
return data.map(inter => ({
id: inter.id,
system: inter.name,
api_key: inter.api_key,
date_refresh: inter.date_refresh,
date_start: inter.date_start,
is_active: inter.is_active,
type: 'integration'
}));
case 'organization':
return data.map(org => ({
id: org.id,
full_name: org.full_name,
short_name: org.short_name,
inn: org.inn,
kpp: org.kpp,
type: 'organization',
...org
}));
case 'counterparty':
return data.map(cp => ({
id: cp.id,
name: cp.name,
inn: cp.inn,
type: 'counterparty',
kpp: cp.kpp,
comment: cp.comment
}));
case 'score':
return data.map(account => ({
id: account.id,
title: account.title,
type: 'score',
...account
}));
default:
return data;
}
};
const idsToRemoveCashFromActive = res.data?.cash?.data?.map(
(item: { id: any }) => item?.id
) || [];
const filteredArrayForActive = res.data.active.data.filter(
(item: { id: any }) => !idsToRemoveCashFromActive.includes(item?.id)
);
setActiveData({
count: (res.data.active.count || 0) - (res.data?.cash?.count || 0),
models: transformData(filteredArrayForActive)
});
setArchiveData({
count: res.data.archived.count || 0,
models: transformData(res.data.archived.data || [])
});
setCashData({
count: res.data?.cash?.count || 0,
models: transformData(res.data?.cash?.data || [])
});
} catch (error) {
console.error('Ошибка при загрузке данных:', error);
setActiveData({ count: 0, models: [] });
setArchiveData({ count: 0, models: [] });
setCashData({ count: 0, models: [] });
}
};
const getSegmentOptions = () => {
const baseOptions = [
{
label: (
<Flex align="center" gap={10}>
Контрагенты
</Flex>
),
value: 'counterparty',
btnName: 'Контрагент',
},
];
if (roleStore === 'accountant' || roleStore === 'superAdmin') {
baseOptions.unshift({
label: (
<Flex align="center" gap={10}>
Счета
</Flex>
),
value: 'score',
btnName: 'Cчет',
});
baseOptions.push({
label: (
<Flex align="center" gap={10}>
Организации
</Flex>
),
value: 'organization',
btnName: 'Организация',
});
}
if (roleStore === 'superAdmin') {
baseOptions.push({
label: (
<Flex align="center" gap={10}>
Интеграции
</Flex>
),
value: 'integration',
btnName: 'интеграции',
});
}
return baseOptions;
};
const segmentOptions = getSegmentOptions();
useEffect(() => {
getModelPage()
}, [segmentTab, modelId])
const onEditModel = () => {
setIsOpenEditModal(true)
}
const location = useLocation();
useEffect(() => {
if (location.state?.editModel) {
setTimeout(() => {
setPendingOpenModal(true);
}, 700);
window.history.replaceState({}, document.title);
}
}, [location.state]);
useEffect(() => {
if (pendingOpenModal && modelDetail && modelDetail.name) {
setIsOpenEditModal(true);
setPendingOpenModal(false);
}
}, [pendingOpenModal, modelDetail]);
const handleSave = async (data: any) => {
try {
await postEditModel(modelId, data);
const model = await getDetailModel(modelId)
await updateModel(model);
await getModelPage();
setIsOpenEditModal(false);
} catch (error) {
console.error(error);
}
};
const handleClose = () => {
setIsOpenEditModal(false);
};
const handleOpenDrawer = () => {
if(segmentTab === 'score') {
setDetailDrawerVisible(true)
} else if(segmentTab === 'counterparty'){
setContragentDrawerVisible(true)
} else if (segmentTab === 'organization'){
setOrganizationDrawerVisible(true)
}
setIsNew(true);
}
const chooseBtnName = () => {
const rightName = segmentOptions.find((segmentOption)=>{
return segmentOption.value === segmentTab;
})
return rightName?.btnName;
}
return (
<div className={styles.wrapper}>
<Helmet>
<title>Модель | Платежи</title>
</Helmet>
<Flex style={{justifyContent: 'space-between', marginRight: '24px'}}>
<Typography.Text className={styles.title}>{modelInfo.name}</Typography.Text>
{roleStore === "superAdmin" && (
<Button className={styles.editButton} onClick={onEditModel}>Редактировать</Button>
)}
</Flex>
<span className={styles.modelsDescription}>
{modelInfo.description || "Для анализа циклов доходов и расходов, прогноза возврата инвестиций в условиях переменчивого рынка."}
</span>
<Flex className={styles.headerInfo} gap={24}>
<Flex gap={4} align='center'>
<span>Месяц окончания:</span>
<Tag>{modelInfo.monthEnd}</Tag>
</Flex>
<Flex gap={4} align='center'>
<span>День платежа:</span>
<Tag>{modelInfo.dayPayment}</Tag>
</Flex>
</Flex>
<div className={styles.bordered}/>
<Flex justify='flex-start' align='center' gap={'8px'} style={{marginLeft: '24px'}}>
{ segmentTab != 'integration' && (
<Button
size="large"
className={styles.payments_button}
onClick={handleOpenDrawer}
>
<File />
{chooseBtnName()}
</Button>
)}
<Segmented
className={styles.filter}
size="large"
options={segmentOptions}
value={segmentTab}
onChange={handleSegmentChange}
/>
</Flex>
<ModelsTable
active={activeData}
archive={archiveData}
cash={cashData}
type={segmentTab}
modelId={modelId}
updateTable={() => getModelPage()}
roleStore={roleStore}
/>
<DrawerComponent
open={detailDrawerVisible}
title={"Создать новый счет"}
handleClose={() => setDetailDrawerVisible(false)}
content={
scoreDetail && (
<AccountContentDrawer
data={null}
isOpenDrawer={detailDrawerVisible}
onClose={() => setDetailDrawerVisible(false)}
updateTable={() => getModelPage()}
modelId={modelId}
isNew={isNew}
/>
)
}
IsEditablebyRole={IsEditablebyRole}
/>
<DrawerComponent
open={contragentDrawerVisible}
title={"Создать нового контрагента"}
handleClose={() => setContragentDrawerVisible(false)}
IsEditablebyRole={IsEditablebyRole}
content={
contragentDetail && (
<ContragentContentDrawer
data={contragentDetail}
isOpenDrawer={contragentDrawerVisible}
onClose={() => setContragentDrawerVisible(false)}
updateTable={() => getModelPage()}
modelId={modelId}
roleStore={roleStore}
isNew={isNew}
/>
)
}
/>
<DrawerComponent
open={organizationDrawerVisible}
title={"Создать новую организацию"}
handleClose={() => setOrganizationDrawerVisible(false)}
IsEditablebyRole={IsEditablebyRole}
content={
organizationDetail && (
<OrganizationContentDrawer
data={organizationDetail}
isOpenDrawer={organizationDrawerVisible}
onClose={() => setOrganizationDrawerVisible(false)}
updateTable={() => getModelPage()}
modelId={modelId}
isNew={isNew}
/>
)
}
/>
{
isOpenEditModal ? (
<ModalEditModel
onSave={handleSave}
onClose={handleClose}
initialData={{
name: modelDetail.name || '',
description: modelDetail.description || '',
month: modelDetail.month_end || '',
day: modelDetail.day_payment || ''
}}
/>
) : null
}
</div>
)
}