diff --git a/web-app/src/components/lenses/LensFormModal.jsx b/web-app/src/components/lenses/LensFormModal.jsx index b8a5508..992e28f 100644 --- a/web-app/src/components/lenses/LensFormModal.jsx +++ b/web-app/src/components/lenses/LensFormModal.jsx @@ -191,7 +191,7 @@ LensFormModal.propTypes = { visible: PropTypes.bool.isRequired, onCancel: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired, - lens: LensPropType.isRequired, + lens: LensPropType, } export default LensFormModal; \ No newline at end of file diff --git a/web-app/src/components/sets/SetFormModal.jsx b/web-app/src/components/sets/SetFormModal.jsx index 9a38c4b..0d54dd4 100644 --- a/web-app/src/components/sets/SetFormModal.jsx +++ b/web-app/src/components/sets/SetFormModal.jsx @@ -1,7 +1,6 @@ import {useState, useEffect} from "react"; import {Modal, Button, Form, Input, Table, InputNumber, Select, Space, notification} from "antd"; import {PlusOutlined, DeleteOutlined} from "@ant-design/icons"; -import axios from "axios"; import getAllLensTypes from "../../api/lens_types/getAllLensTypes.js"; import {useAuth} from "../../AuthContext.jsx"; import PropTypes from "prop-types"; @@ -29,7 +28,6 @@ const SetFormModal = ({visible, onCancel, setData, onSubmit}) => { fetchSetContents(); }, [setData, form]); - const fetchSetContents = async () => { if (!setData) return; @@ -96,7 +94,8 @@ const SetFormModal = ({visible, onCancel, setData, onSubmit}) => { const handleSubmit = () => { form.validateFields().then(values => { if (!validateContent()) return; - onSubmit({...values}, content); + const sanitizedContent = content.map(({id, ...rest}) => rest); + onSubmit({...values}, sanitizedContent); }); }; @@ -255,7 +254,7 @@ SetFormModal.propTypes = { visible: PropTypes.bool.isRequired, onCancel: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired, - setData: SetPropType.isRequired, + setData: SetPropType, } export default SetFormModal; \ No newline at end of file diff --git a/web-app/src/hooks/useLenses.js b/web-app/src/hooks/data/useLenses.js similarity index 94% rename from web-app/src/hooks/useLenses.js rename to web-app/src/hooks/data/useLenses.js index 6737292..02373d4 100644 --- a/web-app/src/hooks/useLenses.js +++ b/web-app/src/hooks/data/useLenses.js @@ -4,11 +4,9 @@ import { useDeleteLensMutation, useGetLensesQuery, useUpdateLensMutation -} from "../redux/services/lensesApi.js"; -import { - closeModal -} from "../redux/slices/lensesSlice.js"; +} from "../../redux/services/lensesApi.js"; import {notification} from "antd"; +import {closeModal} from "../../redux/slices/lensesSlice.js"; const useLenses = () => { @@ -44,6 +42,8 @@ const useLenses = () => { }; const handleModalSubmit = async (lensData) => { + dispatch(closeModal()); + try { if (selectedLens) { await updateLens({id: selectedLens.id, ...lensData}).unwrap(); @@ -60,7 +60,6 @@ const useLenses = () => { placement: "topRight", }); } - dispatch(closeModal()); } catch (error) { notification.error({ message: "Ошибка", diff --git a/web-app/src/hooks/usePatients.js b/web-app/src/hooks/data/usePatients.js similarity index 93% rename from web-app/src/hooks/usePatients.js rename to web-app/src/hooks/data/usePatients.js index 4241df0..94cc87a 100644 --- a/web-app/src/hooks/usePatients.js +++ b/web-app/src/hooks/data/usePatients.js @@ -5,10 +5,8 @@ import { useDeletePatientMutation, useGetPatientsQuery, useUpdatePatientMutation -} from "../redux/services/patientsApi"; -import { - closeModal, -} from "../redux/slices/patientsSlice"; +} from "../../redux/services/patientsApi.js"; +import {closeModal} from "../../redux/slices/patientsSlice.js"; const usePatients = () => { const dispatch = useDispatch(); @@ -41,6 +39,8 @@ const usePatients = () => { }; const handleModalSubmit = async (patientData) => { + dispatch(closeModal()); + try { if (selectedPatient) { await updatePatient({ id: selectedPatient.id, ...patientData }).unwrap(); @@ -57,7 +57,6 @@ const usePatients = () => { placement: "topRight", }); } - dispatch(closeModal()); } catch (error) { notification.error({ message: "Ошибка", @@ -76,4 +75,4 @@ const usePatients = () => { }; }; -export default usePatients; +export default usePatients; \ No newline at end of file diff --git a/web-app/src/hooks/data/useSets.js b/web-app/src/hooks/data/useSets.js new file mode 100644 index 0000000..fc9996b --- /dev/null +++ b/web-app/src/hooks/data/useSets.js @@ -0,0 +1,118 @@ +import {useDispatch, useSelector} from "react-redux"; +import {notification} from "antd"; +import { + useAddSetMutation, useAppendLensesFromSetMutation, + useDeleteSetMutation, + useGetSetsQuery, + useUpdateSetMutation +} from "../../redux/services/setsApi.js"; +import {closeModal} from "../../redux/slices/setsSlice.js"; +import {useAddSetContentMutation, useUpdateSetContentMutation} from "../../redux/services/setContentApi.js"; + + +const useSets = () => { + const dispatch = useDispatch(); + const { + selectedSet, + } = useSelector(state => state.setsUI); + + const {data: sets = [], isLoading, isError} = useGetSetsQuery({ + pollingInterval: 20000, + }); + const [addSet] = useAddSetMutation(); + const [appendLensFromSet] = useAppendLensesFromSetMutation(); + const [updateSet] = useUpdateSetMutation(); + const [deleteSet] = useDeleteSetMutation(); + + const [setContent] = useAddSetContentMutation(); + const [updateContent] = useUpdateSetContentMutation(); + + const handleDeleteSet = async (setId) => { + try { + await deleteSet(setId).unwrap(); + notification.success({ + message: "Набор удален", + description: "Набор успешно удален.", + placement: "topRight", + }); + } catch (error) { + notification.error({ + message: "Ошибка удаления", + description: error.data?.message || "Не удалось удалить набор", + placement: "topRight", + }); + } + }; + + const handleAppendSet = async (set) => { + try { + await appendLensFromSet(set.id).unwrap(); + notification.success({ + message: "Линзы добавлены", + description: "Линзы успешно добавлены.", + placement: "topRight", + }); + } catch (error) { + notification.error({ + message: "Ошибка добавления", + description: error.data?.message || "Не удалось добавить линзы из набора в общий список", + placement: "topRight", + }); + } + }; + + const handleModalSetSubmit = async (set, content = []) => { + dispatch(closeModal()); + + try { + let refreshedSet; + + if (selectedSet) { + refreshedSet = await updateSet({id: selectedSet.id, ...set}).unwrap(); + notification.success({ + message: "Набор обновлен", + description: "Набор успешно обновлен.", + placement: "topRight", + }); + } else { + refreshedSet = await addSet(set).unwrap(); + notification.success({ + message: "Набор добавлен", + description: "Набор успешно добавлен.", + placement: "topRight", + }); + } + + if (refreshedSet && selectedSet) { + await updateContent({setId: refreshedSet.id, setContent: content}).unwrap(); + } else if (refreshedSet && !selectedSet) { + await setContent({setId: refreshedSet.id, setContent: content}).unwrap(); + } else { + notification.error({ + message: "Ошибка", + description: "Не удалось сохранить содержимое набора", + placement: "topRight", + }); + } + } catch (error) { + notification.error({ + message: "Ошибка добавления", + description: error.data?.message || "Произошла ошибка при сохранении", + placement: "topRight", + }); + } + }; + + return { + sets, + isLoading, + isError, + addSet, + updateSet, + handleDeleteSet, + handleAppendSet, + handleModalSetSubmit, + }; +}; + +export default useSets; \ No newline at end of file diff --git a/web-app/src/hooks/useLensesUI.js b/web-app/src/hooks/ui/useLensesUI.js similarity index 91% rename from web-app/src/hooks/useLensesUI.js rename to web-app/src/hooks/ui/useLensesUI.js index 95c0a2a..d57cb9d 100644 --- a/web-app/src/hooks/useLensesUI.js +++ b/web-app/src/hooks/ui/useLensesUI.js @@ -1,5 +1,5 @@ import {useEffect} from "react"; -import {getCachedInfo} from "../utils/cachedInfoUtils.js"; +import {getCachedInfo} from "../../utils/cachedInfoUtils.js"; import { closeModal, openModal, @@ -7,7 +7,7 @@ import { setSearchParams, setSearchText, setShowAdvancedSearch, setViewMode -} from "../redux/slices/lensesSlice.js"; +} from "../../redux/slices/lensesSlice.js"; import {useDispatch, useSelector} from "react-redux"; @@ -30,6 +30,10 @@ const useLensesUI = (lenses) => { 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 handleCloseModal = () => dispatch(closeModal()); const handleSetCurrentPage = (page) => dispatch(setCurrentPage(page)); @@ -101,6 +105,9 @@ const useLensesUI = (lenses) => { showAdvancedSearch, searchParams, pagination, + containerStyle, + filterBarStyle, + formItemStyle, filteredLenses: filteredLenses.map(lens => ({...lens, key: lens.id})), handleSetSearchText, handleAddLens, diff --git a/web-app/src/hooks/usePatientsUI.js b/web-app/src/hooks/ui/usePatientsUI.js similarity index 95% rename from web-app/src/hooks/usePatientsUI.js rename to web-app/src/hooks/ui/usePatientsUI.js index 6421c31..8077c01 100644 --- a/web-app/src/hooks/usePatientsUI.js +++ b/web-app/src/hooks/ui/usePatientsUI.js @@ -1,6 +1,7 @@ import { useEffect, useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { + closeModal, openModal, selectPatient, setCurrentPage, @@ -8,9 +9,8 @@ import { setSearchText, setSortOrder, setViewMode -} from "../redux/slices/patientsSlice"; -import { closeModal } from "../redux/slices/lensesSlice"; -import { getCachedInfo } from "../utils/cachedInfoUtils"; +} from "../../redux/slices/patientsSlice.js"; +import { getCachedInfo } from "../../utils/cachedInfoUtils.js"; const usePatientsUI = (patients) => { const dispatch = useDispatch(); diff --git a/web-app/src/hooks/ui/useSetsUI.js b/web-app/src/hooks/ui/useSetsUI.js new file mode 100644 index 0000000..b91f806 --- /dev/null +++ b/web-app/src/hooks/ui/useSetsUI.js @@ -0,0 +1,81 @@ +import {useDispatch, useSelector} from "react-redux"; +import {useEffect} from "react"; +import { + closeModal, + openModal, + selectSet, + setCurrentPage, + setPageSize, + setSearchText +} from "../../redux/slices/setsSlice.js"; + + +const useSetsUI = (sets) => { + const dispatch = useDispatch(); + const { + searchText, + currentPage, + pageSize, + selectedSet, + isModalVisible, + } = useSelector(state => state.setsUI); + + useEffect(() => { + document.title = "Наборы линз"; + }, [dispatch]); + + const containerStyle = { padding: 20 }; + const filterBarStyle = { marginBottom: 20 }; + const formItemStyle = { width: "100%" }; + + const handleSetSearchText = (value) => dispatch(setSearchText(value)); + const handleCloseModal = () => dispatch(closeModal()); + const handleSetCurrentPage = (page) => dispatch(setCurrentPage(page)); + const handleSetPageSize = (size) => dispatch(setPageSize(size)); + + const handleAddSet = () => { + dispatch(selectSet(null)); + dispatch(openModal()); + }; + + const handleEditSet = (set) => { + dispatch(selectSet(set)); + dispatch(openModal()); + }; + + const handlePaginationChange = (page, pageSize) => { + handleSetCurrentPage(page); + handleSetPageSize(pageSize); + }; + + const pagination = { + currentPage: currentPage, + pageSize: pageSize, + showSizeChanger: true, + pageSizeOptions: ["5", "10", "20", "50"], + onChange: (page, newPageSize) => { + handlePaginationChange(page, newPageSize); + }, + }; + + const filteredSets = sets.filter(set => set.title.toLowerCase().includes(searchText.toLowerCase())); + + return { + searchText, + currentPage, + pageSize, + selectedSet, + isModalVisible, + pagination, + filteredSets, + containerStyle, + filterBarStyle, + formItemStyle, + handleSetSearchText, + handleAddSet, + handleEditSet, + handleCloseModal, + }; +}; + +export default useSetsUI; \ No newline at end of file diff --git a/web-app/src/pages/PatientsPage.jsx b/web-app/src/pages/PatientsPage.jsx index 0b31867..71c2ee4 100644 --- a/web-app/src/pages/PatientsPage.jsx +++ b/web-app/src/pages/PatientsPage.jsx @@ -22,8 +22,8 @@ import PatientListCard from "../components/patients/PatientListCard.jsx"; import PatientFormModal from "../components/patients/PatientFormModal.jsx"; import SelectViewMode from "../components/SelectViewMode.jsx"; import LoadingIndicator from "../components/LoadingIndicator.jsx"; -import usePatients from "../hooks/usePatients.js"; -import usePatientsUI from "../hooks/usePatientsUI.js"; +import usePatients from "../hooks/data/usePatients.js"; +import usePatientsUI from "../hooks/ui/usePatientsUI.js"; const {Option} = Select; const {Title} = Typography; diff --git a/web-app/src/pages/lenses_layout/LensesPage.jsx b/web-app/src/pages/lenses_layout/LensesPage.jsx index 7f89929..af68ff7 100644 --- a/web-app/src/pages/lenses_layout/LensesPage.jsx +++ b/web-app/src/pages/lenses_layout/LensesPage.jsx @@ -26,8 +26,8 @@ import LensCard from "../../components/lenses/LensListCard.jsx"; import LensFormModal from "../../components/lenses/LensFormModal.jsx"; import SelectViewMode from "../../components/SelectViewMode.jsx"; import LoadingIndicator from "../../components/LoadingIndicator.jsx"; -import useLenses from "../../hooks/useLenses.js"; -import useLensesUI from "../../hooks/useLensesUI.js"; +import useLenses from "../../hooks/data/useLenses.js"; +import useLensesUI from "../../hooks/ui/useLensesUI.js"; const {Option} = Select; const {useBreakpoint} = Grid; diff --git a/web-app/src/pages/lenses_layout/SetLensesPage.jsx b/web-app/src/pages/lenses_layout/SetLensesPage.jsx index afbaf71..5a125e5 100644 --- a/web-app/src/pages/lenses_layout/SetLensesPage.jsx +++ b/web-app/src/pages/lenses_layout/SetLensesPage.jsx @@ -1,160 +1,31 @@ -import {useAuth} from "../../AuthContext.jsx"; -import {useEffect, useState} from "react"; -import {FloatButton, Input, List, notification, Row, Typography} from "antd"; -import getAllSets from "../../api/sets/getAllSets.js"; +import {FloatButton, Input, List, Row, Typography} from "antd"; import {PlusOutlined, SwitcherOutlined} from "@ant-design/icons"; import SetListCard from "../../components/sets/SetListCard.jsx"; import SetFormModal from "../../components/sets/SetFormModal.jsx"; -import updateSet from "../../api/sets/updateSet.js"; -import addSet from "../../api/sets/addSet.js"; -import deleteSet from "../../api/sets/deleteSet.js"; -import addSetContent from "../../api/set_content/addSetContent.js"; -import updateSetContent from "../../api/set_content/updateSetContent.js"; -import appendLensesFromSet from "../../api/sets/appendLensesFromSet.js"; import LoadingIndicator from "../../components/LoadingIndicator.jsx"; -import {cacheInfo, getCachedInfo, getCacheTimestamp} from "../../utils/cachedInfoUtils.js"; +import useSets from "../../hooks/data/useSets.js"; +import useSetsUI from "../../hooks/ui/useSetsUI.js"; const {Title} = Typography; const SetLensesPage = () => { - const {api} = useAuth(); - - const [current, setCurrent] = useState(1); - const [pageSize, setPageSize] = useState(10); - - const [searchText, setSearchText] = useState(""); - const [sets, setSets] = useState([]); - const [loading, setLoading] = useState(true); - const [isModalVisible, setIsModalVisible] = useState(false); - const [selectedSet, setSelectedSet] = useState(null); - - useEffect(() => { - fetchSetsWithCache(); - }, []); - - useEffect(() => { - if (!isModalVisible) { - const intervalId = setInterval(fetchSets, 5000); - return () => clearInterval(intervalId); - } - }, [isModalVisible]); - - const fetchSetsWithCache = async () => { - const cachedData = getCachedInfo("setsData"); - const cacheTimestamp = getCacheTimestamp("setsData"); - - if (cachedData && cacheTimestamp && (Date.now() - cacheTimestamp) < 60 * 1000) { - setSets(cachedData); - setLoading(false); - } else { - await fetchSets(); - } - }; - - const fetchSets = async () => { - const data = await getAllSets(api); - setSets(data); - setLoading(false); - cacheInfo("setsData", data); - }; - - const filteredSets = sets.filter(set => set.title.toLowerCase().includes(searchText.toLowerCase())); - - const handleAddSet = () => { - setSelectedSet(null); - setIsModalVisible(true); - }; - - const handleEditSet = (set) => { - setSelectedSet(set); - setIsModalVisible(true); - }; - - const handleDeleteSet = async (set_id) => { - await deleteSet(api, set_id); - notification.success({ - message: "Набор удален", - description: "Набор успешно удален.", - placement: "topRight", - }); - await fetchSets(); - }; - - const handleCancel = () => { - setIsModalVisible(false); - }; - - const handleAppendSet = async (set) => { - await appendLensesFromSet(api, set.id); - notification.success({ - message: "Линзы добавлены", - description: "Линзы успешно добавлены.", - placement: "topRight", - }); - }; - - const handleModalSetSubmit = async (set, content = []) => { - setIsModalVisible(false); - - let refreshed_set; - - if (selectedSet) { - refreshed_set = await editCurrentSet(set); - } else { - refreshed_set = await addNewSet(set); - } - - if (refreshed_set && selectedSet) { - await updateContent(content, refreshed_set.id); - } else if (refreshed_set && !selectedSet) { - await setContent(content, refreshed_set.id); - } - - await fetchSets(); - }; - - const setContent = async (content, set_id) => { - await addSetContent(api, content, set_id); - }; - - const updateContent = async (content, set_id) => { - await updateSetContent(api, content, set_id); - }; - - const editCurrentSet = async (set) => { - const refreshed_set = await updateSet(api, selectedSet.id, set); - notification.success({ - message: "Набор обновлен", - description: "Набор успешно обновлен.", - placement: "topRight", - }); - return refreshed_set; - }; - - const addNewSet = async (set) => { - const refreshed_set = await addSet(api, set); - notification.success({ - message: "Набор добавлен", - description: "Набор успешно добавлен.", - placement: "topRight", - }); - return refreshed_set; - }; + const setsData = useSets(); + const setsUI = useSetsUI(setsData.sets); return ( -
+
<SwitcherOutlined/> Наборы линз - + setSearchText(e.target.value)} - style={{width: "100%"}} + onChange={(e) => setsUI.handleSetSearchText(e.target.value)} + style={setsUI.formItemStyle} allowClear /> - {loading ? ( + {setsData.isLoading ? ( ) : ( { xl: 3, xxl: 3, }} - dataSource={filteredSets} + dataSource={setsUI.filteredSets} renderItem={(set) => ( )} - pagination={{ - current, - pageSize, - showSizeChanger: true, - pageSizeOptions: ["5", "10", "20", "50"], - onChange: (page, newPageSize) => { - setCurrent(page); - setPageSize(newPageSize); - }, - }} + pagination={setsUI.pagination} /> )} } type="primary" - style={{position: "fixed", bottom: 40, right: 40}} tooltip="Добавить набор" - onClick={handleAddSet} + onClick={setsUI.handleAddSet} />
); diff --git a/web-app/src/redux/services/patientsApi.js b/web-app/src/redux/services/patientsApi.js index bfa5834..b81dcc5 100644 --- a/web-app/src/redux/services/patientsApi.js +++ b/web-app/src/redux/services/patientsApi.js @@ -1,4 +1,4 @@ -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' +import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react' import CONFIG from "../../core/сonfig.js"; export const patientsApi = createApi({ @@ -27,7 +27,7 @@ export const patientsApi = createApi({ invalidatesTags: ['Patient'] }), updatePatient: builder.mutation({ - query: ({ id, ...patient }) => ({ + query: ({id, ...patient}) => ({ url: `/patients/${id}/`, method: 'PUT', body: patient @@ -48,5 +48,5 @@ export const { useGetPatientsQuery, useAddPatientMutation, useUpdatePatientMutation, - useDeletePatientMutation -} = patientsApi + useDeletePatientMutation, +} = patientsApi; diff --git a/web-app/src/redux/services/setContentApi.js b/web-app/src/redux/services/setContentApi.js new file mode 100644 index 0000000..b5e66a0 --- /dev/null +++ b/web-app/src/redux/services/setContentApi.js @@ -0,0 +1,43 @@ +import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react'; +import CONFIG from "../../core/сonfig.js"; + +export const setContentApi = createApi({ + reducerPath: 'setContentApi', + baseQuery: fetchBaseQuery({ + baseUrl: CONFIG.BASE_URL, + prepareHeaders: (headers) => { + const token = localStorage.getItem('access_token'); + if (token) headers.set('Authorization', `Bearer ${token}`); + return headers; + } + }), + tagTypes: ['SetContent'], + endpoints: (builder) => ({ + getSetContent: builder.query({ + query: (setId) => `/set_content/${setId}`, + providesTags: ['SetContent'], + }), + addSetContent: builder.mutation({ + query: ({setId, setContent}) => ({ + url: `/set_content/${setId}/`, + method: 'POST', + body: setContent + }), + invalidatesTags: ['SetContent'] + }), + updateSetContent: builder.mutation({ + query: ({setId, setContent}) => ({ + url: `/set_content/${setId}/`, + method: 'PUT', + body: setContent + }), + invalidatesTags: ['SetContent'] + }), + }), +}); + +export const { + useGetSetContentQuery, + useAddSetContentMutation, + useUpdateSetContentMutation, +} = setContentApi; \ No newline at end of file diff --git a/web-app/src/redux/services/setsApi.js b/web-app/src/redux/services/setsApi.js new file mode 100644 index 0000000..1ba4e58 --- /dev/null +++ b/web-app/src/redux/services/setsApi.js @@ -0,0 +1,60 @@ +import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react' +import CONFIG from "../../core/сonfig.js"; + +export const setsApi = createApi({ + reducerPath: 'setsApi', + baseQuery: fetchBaseQuery({ + baseUrl: CONFIG.BASE_URL, + prepareHeaders: (headers) => { + const token = localStorage.getItem('access_token'); + if (token) headers.set('Authorization', `Bearer ${token}`); + return headers; + } + }), + tagTypes: ['Set'], + endpoints: (builder) => ({ + getSets: builder.query({ + query: () => '/sets/', + providesTags: ['Set'], + refetchOnMountOrArgChange: 5 + }), + addSet: builder.mutation({ + query: (set) => ({ + url: '/sets/', + method: 'POST', + body: set + }), + invalidatesTags: ['Set'] + }), + updateSet: builder.mutation({ + query: ({id, ...set}) => ({ + url: `/sets/${id}/`, + method: 'PUT', + body: set + }), + invalidatesTags: ['Set'] + }), + deleteSet: builder.mutation({ + query: (id) => ({ + url: `/sets/${id}/`, + method: 'DELETE' + }), + invalidatesTags: ['Set'] + }), + appendLensesFromSet: builder.mutation({ + query: (id) => ({ + url: `/sets/append_lenses/${id}/`, + method: 'POST', + }), + invalidatesTags: ['Set'] + }), + }), +}); + +export const { + useGetSetsQuery, + useAddSetMutation, + useUpdateSetMutation, + useDeleteSetMutation, + useAppendLensesFromSetMutation, +} = setsApi; \ No newline at end of file diff --git a/web-app/src/redux/slices/setsSlice.js b/web-app/src/redux/slices/setsSlice.js new file mode 100644 index 0000000..6efdb0c --- /dev/null +++ b/web-app/src/redux/slices/setsSlice.js @@ -0,0 +1,46 @@ +import {createSlice} from '@reduxjs/toolkit' + +const initialState = { + searchText: '', + currentPage: 1, + pageSize: 10, + selectedSet: null, + isModalVisible: false, +}; + +const setsSlice = createSlice({ + name: 'setsUI', + initialState, + reducers: { + setSearchText: (state, action) => { + state.searchText = action.payload; + }, + setCurrentPage: (state, action) => { + state.currentPage = action.payload; + }, + setPageSize: (state, action) => { + state.pageSize = action.payload; + }, + openModal: (state) => { + state.isModalVisible = true; + }, + closeModal: (state) => { + state.isModalVisible = false; + state.selectedSet = null; + }, + selectSet: (state, action) => { + state.selectedSet = action.payload; + } + } +}); + +export const { + selectSet, + setSearchText, + setCurrentPage, + setPageSize, + openModal, + closeModal +} = setsSlice.actions; + +export default setsSlice.reducer; \ No newline at end of file diff --git a/web-app/src/redux/store.js b/web-app/src/redux/store.js index a42656c..51a4ed8 100644 --- a/web-app/src/redux/store.js +++ b/web-app/src/redux/store.js @@ -2,7 +2,10 @@ import {configureStore} from '@reduxjs/toolkit'; import {patientsApi} from './services/patientsApi.js'; import patientsUIReducer from './slices/patientsSlice.js'; import {lensesApi} from './services/lensesApi.js'; -import lensesReducer from './slices/lensesSlice.js'; +import lensesUIReducer from './slices/lensesSlice.js'; +import {setsApi} from "./services/setsApi.js"; +import setsUIReducer from './slices/setsSlice.js'; +import {setContentApi} from "./services/setContentApi.js"; export const store = configureStore({ reducer: { @@ -10,10 +13,20 @@ export const store = configureStore({ patientsUI: patientsUIReducer, [lensesApi.reducerPath]: lensesApi.reducer, - lensesUI: lensesReducer, + lensesUI: lensesUIReducer, + + [setsApi.reducerPath]: setsApi.reducer, + setsUI: setsUIReducer, + + [setContentApi.reducerPath]: setContentApi.reducer, }, middleware: (getDefaultMiddleware) => ( - getDefaultMiddleware().concat(patientsApi.middleware, lensesApi.middleware) + getDefaultMiddleware().concat( + patientsApi.middleware, + lensesApi.middleware, + setsApi.middleware, + setContentApi.middleware, + ) ) });