для страницы пациентов вынес фнукции связанные с API в отдельный хук, также в UI хук вынес функции и переменные связанные с UI и состояниями

This commit is contained in:
Андрей Дувакин 2025-03-25 11:44:05 +05:00
parent f840a0ab34
commit 793a47a58d
11 changed files with 392 additions and 172 deletions

View File

@ -10,7 +10,6 @@ const PatientListCard = ({patient, handleEditPatient, handleDeletePatient}) => {
const birthday = new Date(patient.birthday) const birthday = new Date(patient.birthday)
const deletePatient = () => { const deletePatient = () => {
handleDeletePatient(patient.id); handleDeletePatient(patient.id);
}; };

View File

@ -0,0 +1,90 @@
import {useDispatch, useSelector} from "react-redux";
import {
useAddLensMutation,
useDeleteLensMutation,
useGetLensesQuery,
useUpdateLensMutation
} from "../redux/services/lensesApi.js";
import {useEffect} from "react";
import {
closeModal,
setViewMode,
} from "../redux/slices/lensesSlice.js";
import {getCachedInfo} from "../utils/cachedInfoUtils.js";
import {notification} from "antd";
const useLenses = () => {
const dispatch = useDispatch();
const {
selectedLens,
} = useSelector(state => state.lensesUI);
const {data: lenses = [], isLoading, isError} = useGetLensesQuery(undefined, {
pollingInterval: 20000,
});
const [addLens] = useAddLensMutation();
const [updateLens] = useUpdateLensMutation();
const [deleteLens] = useDeleteLensMutation();
useEffect(() => {
document.title = "Линзы";
const cachedViewMode = getCachedInfo("viewModeLenses");
if (cachedViewMode) dispatch(setViewMode(cachedViewMode));
}, [dispatch]);
const handleDeleteLens = async (lensId) => {
try {
await deleteLens(lensId).unwrap();
notification.success({
message: "Линза удалена",
description: "Линза успешно удалена.",
placement: "topRight",
});
} catch (error) {
notification.error({
message: "Ошибка удаления",
description: error.data?.message || "Не удалось удалить линзу",
placement: "topRight",
});
}
};
const handleModalSubmit = async (lensData) => {
try {
if (selectedLens) {
await updateLens({id: selectedLens.id, ...lensData}).unwrap();
notification.success({
message: "Линза обновлена",
description: "Линза успешно обновлена.",
placement: "topRight",
});
} else {
await addLens(lensData).unwrap();
notification.success({
message: "Линза добавлена",
description: "Линза успешно добавлена.",
placement: "topRight",
});
}
dispatch(closeModal());
} catch (error) {
notification.error({
message: "Ошибка",
description: error.data?.message || "Произошла ошибка при сохранении",
placement: "topRight",
});
}
};
return {
lenses,
isLoading,
isError,
handleDeleteLens,
handleModalSubmit,
}
};
export default useLenses;

View File

@ -1,4 +1,3 @@
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { notification } from "antd"; import { notification } from "antd";
import { import {
@ -8,25 +7,13 @@ import {
useUpdatePatientMutation useUpdatePatientMutation
} from "../redux/services/patientsApi"; } from "../redux/services/patientsApi";
import { import {
openModal,
closeModal, closeModal,
selectPatient,
setSearchText,
setSortOrder,
setViewMode,
setCurrentPage,
setPageSize
} from "../redux/slices/patientsSlice"; } from "../redux/slices/patientsSlice";
import { getCachedInfo } from "../utils/cachedInfoUtils";
const usePatients = () => { const usePatients = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { const {
searchText,
sortOrder,
viewMode,
selectedPatient, selectedPatient,
isModalVisible
} = useSelector(state => state.patientsUI); } = useSelector(state => state.patientsUI);
const { data: patients = [], isLoading, isError } = useGetPatientsQuery(undefined, { const { data: patients = [], isLoading, isError } = useGetPatientsQuery(undefined, {
@ -36,22 +23,6 @@ const usePatients = () => {
const [updatePatient] = useUpdatePatientMutation(); const [updatePatient] = useUpdatePatientMutation();
const [deletePatient] = useDeletePatientMutation(); const [deletePatient] = useDeletePatientMutation();
useEffect(() => {
document.title = "Пациенты";
const cachedViewMode = getCachedInfo("viewModePatients");
if (cachedViewMode) dispatch(setViewMode(cachedViewMode));
}, [dispatch]);
const handleAddPatient = () => {
dispatch(selectPatient(null));
dispatch(openModal());
};
const handleEditPatient = (patient) => {
dispatch(selectPatient(patient));
dispatch(openModal());
};
const handleDeletePatient = async (patientId) => { const handleDeletePatient = async (patientId) => {
try { try {
await deletePatient(patientId).unwrap(); await deletePatient(patientId).unwrap();
@ -69,7 +40,7 @@ const usePatients = () => {
} }
}; };
const handleModalPatientSubmit = async (patientData) => { const handleModalSubmit = async (patientData) => {
try { try {
if (selectedPatient) { if (selectedPatient) {
await updatePatient({ id: selectedPatient.id, ...patientData }).unwrap(); await updatePatient({ id: selectedPatient.id, ...patientData }).unwrap();
@ -100,20 +71,8 @@ const usePatients = () => {
patients, patients,
isLoading, isLoading,
isError, isError,
searchText,
sortOrder,
viewMode,
isModalVisible,
selectedPatient,
handleAddPatient,
handleEditPatient,
handleDeletePatient, handleDeletePatient,
handleModalPatientSubmit, handleModalSubmit,
setSearchText: (text) => dispatch(setSearchText(text)),
setSortOrder: (order) => dispatch(setSortOrder(order)),
setViewMode: (mode) => dispatch(setViewMode(mode)),
setCurrentPage: (page) => dispatch(setCurrentPage(page)),
setPageSize: (size) => dispatch(setPageSize(size)),
}; };
}; };

View File

@ -0,0 +1,101 @@
import { useEffect, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import {
openModal,
selectPatient,
setCurrentPage,
setPageSize,
setSearchText,
setSortOrder,
setViewMode
} from "../redux/slices/patientsSlice";
import { closeModal } from "../redux/slices/lensesSlice";
import { getCachedInfo } from "../utils/cachedInfoUtils";
import {BuildOutlined, TableOutlined} from "@ant-design/icons";
const usePatientsUI = (patients) => {
const dispatch = useDispatch();
const {
searchText,
sortOrder,
viewMode,
selectedPatient,
isModalVisible,
currentPage,
pageSize,
} = useSelector(state => state.patientsUI);
useEffect(() => {
document.title = "Пациенты";
const cachedViewMode = getCachedInfo("viewModePatients");
if (cachedViewMode) dispatch(setViewMode(cachedViewMode));
}, [dispatch]);
const containerStyle = { padding: 20 };
const filterBarStyle = { marginBottom: 20 };
const formItemStyle = { width: "100%" };
const handleSetSearchText = (value) => dispatch(setSearchText(value));
const handleSetSortOrder = (value) => dispatch(setSortOrder(value));
const handleSetCurrentPage = (page) => dispatch(setCurrentPage(page));
const handleSetPageSize = (size) => dispatch(setPageSize(size));
const handleSetViewMode = (mode) => dispatch(setViewMode(mode));
const handleCloseModal = () => dispatch(closeModal());
const handlePaginationChange = (page, pageSize) => {
handleSetCurrentPage(page);
handleSetPageSize(pageSize);
};
const handleAddPatient = () => {
dispatch(selectPatient(null));
dispatch(openModal());
};
const handleEditPatient = (patient) => {
dispatch(selectPatient(patient));
dispatch(openModal());
};
const filteredPatients = useMemo(() => {
return patients
.filter(patient =>
Object.values(patient)
.filter(value => typeof value === "string")
.some(value => value.toLowerCase().includes(searchText.toLowerCase()))
)
.sort((a, b) => {
const fullNameA = `${a.last_name} ${a.first_name}`;
const fullNameB = `${b.last_name} ${b.first_name}`;
return sortOrder === "asc" ? fullNameA.localeCompare(fullNameB) : fullNameB.localeCompare(fullNameA);
});
}, [patients, searchText, sortOrder]);
const formatDate = (date) => new Date(date).toLocaleDateString();
return {
searchText,
sortOrder,
viewMode,
selectedPatient,
isModalVisible,
currentPage,
pageSize,
containerStyle,
filterBarStyle,
formItemStyle,
filteredPatients: patients.map(p => ({ ...p, key: p.id })),
handleSetSearchText,
handleSetSortOrder,
handleSetViewMode,
handleCloseModal,
handleAddPatient,
handleEditPatient,
formatDate,
handlePaginationChange,
};
};
export default usePatientsUI;

View File

@ -1,4 +1,3 @@
import {useEffect, useMemo} from 'react';
import { import {
Input, Input,
Select, Select,
@ -16,67 +15,23 @@ import {
BuildOutlined, BuildOutlined,
PlusOutlined, PlusOutlined,
SortAscendingOutlined, SortAscendingOutlined,
SortDescendingOutlined, SortDescendingOutlined, TableOutlined,
TableOutlined,
TeamOutlined TeamOutlined
} from "@ant-design/icons"; } from "@ant-design/icons";
import {useDispatch, useSelector} from "react-redux";
import {
setSearchText,
setSortOrder,
setViewMode,
closeModal,
setCurrentPage,
setPageSize
} from "../redux/slices/patientsSlice.js";
import PatientListCard from "../components/patients/PatientListCard.jsx"; import PatientListCard from "../components/patients/PatientListCard.jsx";
import PatientFormModal from "../components/patients/PatientFormModal.jsx"; import PatientFormModal from "../components/patients/PatientFormModal.jsx";
import SelectViewMode from "../components/SelectViewMode.jsx"; import SelectViewMode from "../components/SelectViewMode.jsx";
import LoadingIndicator from "../components/LoadingIndicator.jsx"; import LoadingIndicator from "../components/LoadingIndicator.jsx";
import usePatients from "../hooks/usePatients.js"; import usePatients from "../hooks/usePatients.js";
import usePatientsUI from "../hooks/usePatientsUI.js";
const {Option} = Select; const {Option} = Select;
const {Title} = Typography; const {Title} = Typography;
const PatientsPage = () => { const PatientsPage = () => {
const dispatch = useDispatch(); const patientsData = usePatients();
const {
patients,
isLoading,
isError,
handleAddPatient,
handleEditPatient,
handleDeletePatient,
handleModalPatientSubmit
} = usePatients();
const { const patientsUI = usePatientsUI(patientsData.patients);
searchText,
sortOrder,
viewMode,
selectedPatient,
isModalVisible,
currentPage,
pageSize
} = useSelector(state => state.patientsUI);
useEffect(() => {
document.title = "Пациенты";
}, []);
const filteredPatients = useMemo(() => {
return patients
.filter(patient =>
Object.values(patient)
.filter(value => typeof value === "string")
.some(value => value.toLowerCase().includes(searchText.toLowerCase()))
)
.sort((a, b) => {
const fullNameA = `${a.last_name} ${a.first_name}`;
const fullNameB = `${b.last_name} ${b.first_name}`;
return sortOrder === "asc" ? fullNameA.localeCompare(fullNameB) : fullNameB.localeCompare(fullNameA);
});
}, [patients, searchText, sortOrder]);
const columns = [ const columns = [
{ {
@ -97,41 +52,36 @@ const PatientsPage = () => {
title: "Отчество", title: "Отчество",
dataIndex: "patronymic", dataIndex: "patronymic",
key: "patronymic", key: "patronymic",
sorter: (a, b) => a.patronymic.localeCompare(b.patronymic),
sortDirections: ["ascend", "descend"], sortDirections: ["ascend", "descend"],
}, },
{ {
title: "Дата рождения", title: "Дата рождения",
dataIndex: "birthday", dataIndex: "birthday",
key: "birthday",
sorter: (a, b) => new Date(a.birthday).getTime() - new Date(b.birthday).getTime(), sorter: (a, b) => new Date(a.birthday).getTime() - new Date(b.birthday).getTime(),
sortDirections: ["ascend", "descend"], sortDirections: ["ascend", "descend"],
render: (date) => new Date(date).toLocaleDateString() render: patientsUI.formatDate,
}, },
{ {
title: "Телефон", title: "Телефон",
dataIndex: "phone", dataIndex: "phone",
key: "phone",
}, },
{ {
title: "Email", title: "Email",
dataIndex: "email", dataIndex: "email",
key: "email",
}, },
{ {
title: "Действия", title: "Действия",
key: "actions",
fixed: 'right', fixed: 'right',
render: (_, record) => ( render: (_, record) => (
<Row gutter={[8, 8]}> <Row gutter={[8, 8]}>
<Col xs={24} xl={12}> <Col xs={24} xl={12}>
<Button block onClick={() => handleEditPatient(record)}>Изменить</Button> <Button block onClick={() => patientsUI.handleEditPatient(record)}>Изменить</Button>
</Col> </Col>
<Col xs={24} xl={12}> <Col xs={24} xl={12}>
<Popconfirm <Popconfirm
title="Вы уверены, что хотите удалить пациента?" title="Вы уверены, что хотите удалить пациента?"
onConfirm={() => handleDeletePatient(record.id)} onConfirm={() => patientsData.handleDeletePatient(record.id)}
okText="Да, удалить" okText="Да, удалить"
cancelText="Отмена" cancelText="Отмена"
> >
@ -156,31 +106,35 @@ const PatientsPage = () => {
} }
]; ];
if (isError) return <Result status="error" title="Ошибка" subTitle="Произошла ошибка в работе страницы"/>; if (patientsData.isError) return (
<Result
status="error"
title="Ошибка"
subTitle="Произошла ошибка в работе страницы"
/>
);
return ( return (
<div style={{padding: 20}}> <div style={patientsUI.containerStyle}>
<Title level={1}><TeamOutlined/> Пациенты</Title> <Title level={1}><TeamOutlined/> Пациенты</Title>
<Row gutter={[16, 16]} style={{marginBottom: 20}}> <Row gutter={[16, 16]} style={patientsUI.filterBarStyle}>
<Col xs={24} md={14} sm={10} xl={18} xxl={19}> <Col xs={24} md={14} sm={10} xl={18} xxl={19}>
<Input <Input
placeholder="Поиск пациента" placeholder="Поиск пациента"
value={searchText} value={patientsUI.searchText}
onChange={(e) => dispatch(setSearchText(e.target.value))} onChange={(e) => patientsUI.handleSetSearchText(e.target.value)}
style={{width: "100%"}} style={patientsUI.formItemStyle}
allowClear allowClear
/> />
</Col> </Col>
{viewMode === "tile" && ( {patientsUI.viewMode === "tile" && (
<Col xs={24} md={5} sm={6} xl={3} xxl={2}> <Col xs={24} md={5} sm={6} xl={3} xxl={2}>
<Tooltip <Tooltip title={"Сортировка пациентов"}>
title={"Сортировка пациентов"}
>
<Select <Select
value={sortOrder} value={patientsUI.sortOrder}
onChange={(value) => dispatch(setSortOrder(value))} onChange={patientsUI.handleSetSortOrder}
style={{width: "100%"}} style={patientsUI.formItemStyle}
> >
<Option value="asc"><SortAscendingOutlined/> А-Я</Option> <Option value="asc"><SortAscendingOutlined/> А-Я</Option>
<Option value="desc"><SortDescendingOutlined/> Я-А</Option> <Option value="desc"><SortDescendingOutlined/> Я-А</Option>
@ -189,18 +143,13 @@ const PatientsPage = () => {
</Col> </Col>
)} )}
<Col xs={24} md={ <Col xs={24} md={patientsUI.viewMode === "tile" ? 5 : 10}
viewMode === "tile" ? 5 : 10 sm={patientsUI.viewMode === "tile" ? 8 : 14}
} sm={ xl={patientsUI.viewMode === "tile" ? 3 : 5}
viewMode === "tile" ? 8 : 14 xxl={patientsUI.viewMode === "tile" ? 3 : 5}>
} xl={
viewMode === "tile" ? 3 : 5
} xxl={
viewMode === "tile" ? 3 : 5
}>
<SelectViewMode <SelectViewMode
viewMode={viewMode} viewMode={patientsUI.viewMode}
setViewMode={value => dispatch(setViewMode(value))} setViewMode={patientsUI.handleSetViewMode}
localStorageKey={"viewModePatients"} localStorageKey={"viewModePatients"}
toolTipText={"Формат отображения пациентов"} toolTipText={"Формат отображения пациентов"}
viewModes={viewModes} viewModes={viewModes}
@ -208,48 +157,61 @@ const PatientsPage = () => {
</Col> </Col>
</Row> </Row>
{isLoading ? <LoadingIndicator/> : viewMode === "tile" ? ( {patientsData.isLoading ? <LoadingIndicator/> : patientsUI.viewMode === "tile" ? (
<List <List
grid={{gutter: 16, column: 3}} grid={{gutter: 16, column: 3}}
dataSource={filteredPatients} dataSource={patientsUI.filteredPatients}
renderItem={patient => ( renderItem={patient => (
<List.Item> <List.Item>
<PatientListCard <PatientListCard
patient={patient} patient={patient}
handleEditPatient={handleEditPatient} handleEditPatient={patientsUI.handleEditPatient}
handleDeletePatient={handleDeletePatient} handleDeletePatient={patientsData.handleDeletePatient}
/> />
</List.Item> </List.Item>
)} )}
pagination={{ pagination={{
current: currentPage, pageSize, onChange: (p, s) => { currentPage: patientsUI.currentPage,
dispatch(setCurrentPage(p)); pageSize: patientsUI.pageSize,
dispatch(setPageSize(s)); showSizeChanger: true,
} pageSizeOptions: ["5", "10", "20", "50"],
onChange: (page, newPageSize) => {
patientsUI.handlePaginationChange(page, newPageSize);
},
}} }}
/> />
) : ( ) : (
<Table <Table
columns={columns} columns={columns}
dataSource={filteredPatients.map(p => ({...p, key: p.id}))} dataSource={patientsUI.filteredPatients}
pagination={{ pagination={{
current: currentPage, pageSize, onChange: (p, s) => { currentPage: patientsUI.currentPage,
dispatch(setCurrentPage(p)); pageSize: patientsUI.pageSize,
dispatch(setPageSize(s)); showSizeChanger: true,
} pageSizeOptions: ["5", "10", "20", "50"],
onChange: (page, newPageSize) => {
patientsUI.handlePaginationChange(page, newPageSize);
},
}} }}
/> />
)} )}
<FloatButton icon={<PlusOutlined/>} type="primary" onClick={handleAddPatient} tooltip="Добавить пациента"/> <FloatButton
icon={<PlusOutlined/>}
type="primary"
onClick={patientsUI.handleAddPatient}
tooltip="Добавить пациента"
/>
<PatientFormModal <PatientFormModal
visible={isModalVisible} visible={patientsUI.isModalVisible}
onCancel={() => dispatch(closeModal())} onCancel={patientsUI.handleCloseModal}
onSubmit={handleModalPatientSubmit} onSubmit={patientsData.handleModalSubmit}
patient={selectedPatient} patient={patientsUI.selectedPatient}
/> />
</div> </div>
); );
}; };
;
export default PatientsPage; export default PatientsPage;

View File

@ -34,6 +34,9 @@ import LensFormModal from "../../components/lenses/LensFormModal.jsx";
import SelectViewMode from "../../components/SelectViewMode.jsx"; import SelectViewMode from "../../components/SelectViewMode.jsx";
import LoadingIndicator from "../../components/LoadingIndicator.jsx"; import LoadingIndicator from "../../components/LoadingIndicator.jsx";
import {getCachedInfo, getCacheTimestamp} from "../../utils/cachedInfoUtils.js"; import {getCachedInfo, getCacheTimestamp} from "../../utils/cachedInfoUtils.js";
import {useDispatch} from "react-redux";
import useLenses from "../../hooks/useLenses.js";
import {openModal, selectLens} from "../../redux/slices/lensesSlice.js";
const {Option} = Select; const {Option} = Select;
const {useBreakpoint} = Grid; const {useBreakpoint} = Grid;

View File

@ -0,0 +1,53 @@
import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/query/react";
import CONFIG from "../../core/сonfig.js";
export const lensesApi = createApi({
reducerPath: 'lensesApi',
baseQuery: fetchBaseQuery({
baseUrl: CONFIG.BASE_URL,
prepareHeaders: (headers) => {
const token = localStorage.getItem('access_token');
if (token) headers.set('Authorization', `Bearer ${token}`);
return headers;
}
}),
tagTypes: ['Lens'],
endpoints: (builder) => ({
getLenses: builder.query({
query: () => '/lenses/',
providesTags: ['Lens'],
refetchOnMountOrArgChange: 5
}),
addLens: builder.mutation({
query: (lens) => ({
url: '/lenses/',
method: 'POST',
body: lens
}),
invalidatesTags: ['Lens']
}),
updateLens: builder.mutation({
query: ({ id, ...lens }) => ({
url: `/lenses/${id}/`,
method: 'PUT',
body: lens
}),
invalidatesTags: ['Lens']
}),
deleteLens: builder.mutation({
query: (id) => ({
url: `/lenses/${id}/`,
method: 'DELETE'
}),
invalidatesTags: ['Lens']
}),
}),
});
export const {
useGetLensesQuery,
useAddLensMutation,
useUpdateLensMutation,
useDeleteLensMutation,
} = lensesApi;

View File

@ -5,10 +5,10 @@ export const patientsApi = createApi({
reducerPath: 'patientsApi', reducerPath: 'patientsApi',
baseQuery: fetchBaseQuery({ baseQuery: fetchBaseQuery({
baseUrl: CONFIG.BASE_URL, baseUrl: CONFIG.BASE_URL,
prepareHeaders: (headers, { getState }) => { prepareHeaders: (headers) => {
const token = localStorage.getItem('access_token') const token = localStorage.getItem('access_token');
if (token) headers.set('Authorization', `Bearer ${token}`) if (token) headers.set('Authorization', `Bearer ${token}`);
return headers return headers;
} }
}), }),
tagTypes: ['Patient'], tagTypes: ['Patient'],
@ -40,9 +40,9 @@ export const patientsApi = createApi({
method: 'DELETE' method: 'DELETE'
}), }),
invalidatesTags: ['Patient'] invalidatesTags: ['Patient']
}) }),
}) }),
}) });
export const { export const {
useGetPatientsQuery, useGetPatientsQuery,

View File

@ -1,19 +0,0 @@
import {createSlice} from '@reduxjs/toolkit';
const appointmentsSlice = createSlice({
name: 'appointments',
initialState: {
data: [],
status: 'idle',
error: null,
},
reducers: {
setAppointments(state, action) {
state.data = action.payload;
}
}
});
export const {setAppointments} = appointmentsSlice.actions;
export default appointmentsSlice.reducer;

View File

@ -0,0 +1,72 @@
import {createSlice} from '@reduxjs/toolkit'
import {cacheInfo} from "../../utils/cachedInfoUtils.js";
const initialState = {
searchText: '',
viewMode: 'tile',
currentPage: 1,
pageSize: 10,
selectedLens: null,
isModalVisible: false,
showAvancedSearch: false,
searchParams: {
tor: null,
diameter: null,
preset_refraction: null,
periphery_toricity: null,
side: 'all',
issued: false,
trial: null
},
};
const lensesSlice = createSlice({
name: 'lensesUI',
initialState,
reducers: {
setSearchText: (state, action) => {
state.searchText = action.payload;
},
setCurrentPage: (state, action) => {
state.currentPage = action.payload;
},
setPageSize: (state, action) => {
state.pageSize = action.payload;
},
setViewMode: (state, action) => {
state.viewMode = action.payload;
cacheInfo("viewModeLenses", action.payload);
},
openModal: (state) => {
state.isModalVisible = true;
},
closeModal: (state) => {
state.isModalVisible = false;
state.selectedLens = null;
},
selectLens: (state, action) => {
state.selectedLens = action.payload;
},
setSearchParams: (state, action) => {
state.searchParams = action.payload;
},
setShowAdvancedSearch: (state, action) => {
state.showAvancedSearch = action.payload;
},
}
});
export const {
setSearchText,
setCurrentPage,
setPageSize,
setViewMode,
openModal,
closeModal,
selectLens,
setSearchParams,
setShowAdvancedSearch
} = lensesSlice.actions;
export default lensesSlice.reducer;

View File

@ -9,7 +9,7 @@ const initialState = {
pageSize: 10, pageSize: 10,
selectedPatient: null, selectedPatient: null,
isModalVisible: false isModalVisible: false
} };
const patientsSlice = createSlice({ const patientsSlice = createSlice({
name: 'patientsUI', name: 'patientsUI',
@ -53,6 +53,6 @@ export const {
openModal, openModal,
closeModal, closeModal,
selectPatient selectPatient
} = patientsSlice.actions } = patientsSlice.actions;
export default patientsSlice.reducer export default patientsSlice.reducer;