From 26484676da318dab868844f3e39168fa8a5eed7c Mon Sep 17 00:00:00 2001 From: andrei Date: Sat, 29 Mar 2025 10:18:19 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B0=D0=BB=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=83?= =?UTF-8?q?=20=D1=81=20=D0=B2=D1=8B=D0=B4=D0=B0=D1=87=D0=B0=D0=BC=D0=B8=20?= =?UTF-8?q?=D0=BB=D0=B8=D0=BD=D0=B7=20=D1=81=20=D0=B8=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC=20?= =?UTF-8?q?redux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-app/src/api/lenses/addLens.js | 8 - web-app/src/api/lenses/deleteLens.js | 8 - web-app/src/api/lenses/getAllLenses.js | 8 - web-app/src/api/lenses/updateLens.js | 8 - web-app/src/api/patients/addPatient.js | 8 - web-app/src/api/patients/deletePatient.js | 8 - web-app/src/api/patients/updatePatient.js | 8 - web-app/src/api/set_content/addSetContent.js | 8 - .../src/api/set_content/updateSetContent.js | 8 - web-app/src/api/sets/addSet.js | 8 - web-app/src/api/sets/appendLensesFromSet.js | 8 - web-app/src/api/sets/deleteSet.js | 8 - web-app/src/api/sets/getAllSets.js | 8 - web-app/src/api/sets/updateSet.js | 8 - .../lens_issues/LensIssueViewModal.jsx | 2 +- web-app/src/hooks/data/useIssues.js | 47 +++++ web-app/src/hooks/ui/useIssuesUI.js | 131 ++++++++++++ web-app/src/hooks/ui/useSetsUI.js | 13 +- web-app/src/pages/IssuesPage.jsx | 198 ++++-------------- web-app/src/redux/services/lensIssuesApi.js | 36 ++++ web-app/src/redux/services/patientsApi.js | 2 +- web-app/src/redux/slices/lensIssuesSlice.js | 64 ++++++ web-app/src/redux/store.js | 6 + 23 files changed, 332 insertions(+), 279 deletions(-) delete mode 100644 web-app/src/api/lenses/addLens.js delete mode 100644 web-app/src/api/lenses/deleteLens.js delete mode 100644 web-app/src/api/lenses/getAllLenses.js delete mode 100644 web-app/src/api/lenses/updateLens.js delete mode 100644 web-app/src/api/patients/addPatient.js delete mode 100644 web-app/src/api/patients/deletePatient.js delete mode 100644 web-app/src/api/patients/updatePatient.js delete mode 100644 web-app/src/api/set_content/addSetContent.js delete mode 100644 web-app/src/api/set_content/updateSetContent.js delete mode 100644 web-app/src/api/sets/addSet.js delete mode 100644 web-app/src/api/sets/appendLensesFromSet.js delete mode 100644 web-app/src/api/sets/deleteSet.js delete mode 100644 web-app/src/api/sets/getAllSets.js delete mode 100644 web-app/src/api/sets/updateSet.js create mode 100644 web-app/src/hooks/data/useIssues.js create mode 100644 web-app/src/hooks/ui/useIssuesUI.js create mode 100644 web-app/src/redux/services/lensIssuesApi.js create mode 100644 web-app/src/redux/slices/lensIssuesSlice.js diff --git a/web-app/src/api/lenses/addLens.js b/web-app/src/api/lenses/addLens.js deleted file mode 100644 index 7d3be02..0000000 --- a/web-app/src/api/lenses/addLens.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const addLens = async (api, lens) => { - const response = await api.post(`${CONFIG.BASE_URL}/lenses/`, lens); - return response.data; -}; - -export default addLens; \ No newline at end of file diff --git a/web-app/src/api/lenses/deleteLens.js b/web-app/src/api/lenses/deleteLens.js deleted file mode 100644 index dcaa41e..0000000 --- a/web-app/src/api/lenses/deleteLens.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const deleteLens = async (api, lens_id) => { - const response = await api.delete(`${CONFIG.BASE_URL}/lenses/${lens_id}/`); - return response.data; -}; - -export default deleteLens; \ No newline at end of file diff --git a/web-app/src/api/lenses/getAllLenses.js b/web-app/src/api/lenses/getAllLenses.js deleted file mode 100644 index 9e0e095..0000000 --- a/web-app/src/api/lenses/getAllLenses.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const getAllLenses = async (api) => { - const response = await api.get(`${CONFIG.BASE_URL}/lenses/`); - return response.data; -}; - -export default getAllLenses; \ No newline at end of file diff --git a/web-app/src/api/lenses/updateLens.js b/web-app/src/api/lenses/updateLens.js deleted file mode 100644 index a0fd1af..0000000 --- a/web-app/src/api/lenses/updateLens.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const updateLens = async (api, lensId, lensData) => { - const response = await api.put(`${CONFIG.BASE_URL}/lenses/${lensId}/`, lensData); - return response.data; -}; - -export default updateLens; \ No newline at end of file diff --git a/web-app/src/api/patients/addPatient.js b/web-app/src/api/patients/addPatient.js deleted file mode 100644 index f0ed081..0000000 --- a/web-app/src/api/patients/addPatient.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const addPatient = async (api, patient) => { - const response = await api.post(`${CONFIG.BASE_URL}/patients/`, patient); - return response.data; -}; - -export default addPatient; \ No newline at end of file diff --git a/web-app/src/api/patients/deletePatient.js b/web-app/src/api/patients/deletePatient.js deleted file mode 100644 index dea07ad..0000000 --- a/web-app/src/api/patients/deletePatient.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const deletePatient = async (api, patient_id) => { - const response = await api.delete(`${CONFIG.BASE_URL}/patients/${patient_id}/`); - return response.data; -}; - -export default deletePatient; \ No newline at end of file diff --git a/web-app/src/api/patients/updatePatient.js b/web-app/src/api/patients/updatePatient.js deleted file mode 100644 index 6040132..0000000 --- a/web-app/src/api/patients/updatePatient.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const updatePatient = async (api, patientId, patientData) => { - const response = await api.put(`${CONFIG.BASE_URL}/patients/${patientId}/`, patientData); - return response.data; -}; - -export default updatePatient; \ No newline at end of file diff --git a/web-app/src/api/set_content/addSetContent.js b/web-app/src/api/set_content/addSetContent.js deleted file mode 100644 index 311b85a..0000000 --- a/web-app/src/api/set_content/addSetContent.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const addSetContent = async (api, set_content, set_id) => { - const response = await api.post(`${CONFIG.BASE_URL}/set_content/${set_id}/`, set_content); - return response.data; -}; - -export default addSetContent; \ No newline at end of file diff --git a/web-app/src/api/set_content/updateSetContent.js b/web-app/src/api/set_content/updateSetContent.js deleted file mode 100644 index b2edc4c..0000000 --- a/web-app/src/api/set_content/updateSetContent.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const updateSetContent = async (api, set_content, set_id) => { - const response = await api.put(`${CONFIG.BASE_URL}/set_content/${set_id}/`, set_content); - return response.data; -}; - -export default updateSetContent; \ No newline at end of file diff --git a/web-app/src/api/sets/addSet.js b/web-app/src/api/sets/addSet.js deleted file mode 100644 index c199d30..0000000 --- a/web-app/src/api/sets/addSet.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const addSet = async (api, set) => { - const response = await api.post(`${CONFIG.BASE_URL}/sets/`, set); - return response.data; -}; - -export default addSet; \ No newline at end of file diff --git a/web-app/src/api/sets/appendLensesFromSet.js b/web-app/src/api/sets/appendLensesFromSet.js deleted file mode 100644 index fc549f9..0000000 --- a/web-app/src/api/sets/appendLensesFromSet.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const appendLensesFromSet = async (api, set_id) => { - const response = await api.post(`${CONFIG.BASE_URL}/sets/append_lenses/${set_id}/`); - return response.data; -}; - -export default appendLensesFromSet; \ No newline at end of file diff --git a/web-app/src/api/sets/deleteSet.js b/web-app/src/api/sets/deleteSet.js deleted file mode 100644 index b983050..0000000 --- a/web-app/src/api/sets/deleteSet.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const deleteSet = async (api, set_id) => { - const response = await api.delete(`${CONFIG.BASE_URL}/sets/${set_id}/`); - return response.data; -}; - -export default deleteSet; \ No newline at end of file diff --git a/web-app/src/api/sets/getAllSets.js b/web-app/src/api/sets/getAllSets.js deleted file mode 100644 index 2e9cb8e..0000000 --- a/web-app/src/api/sets/getAllSets.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const getAllSets = async (api) => { - const response = await api.get(`${CONFIG.BASE_URL}/sets/`); - return response.data; -}; - -export default getAllSets; \ No newline at end of file diff --git a/web-app/src/api/sets/updateSet.js b/web-app/src/api/sets/updateSet.js deleted file mode 100644 index 9855b72..0000000 --- a/web-app/src/api/sets/updateSet.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONFIG from "../../core/сonfig.js"; - -const updateSet = async (api, set_id, set) => { - const response = await api.put(`${CONFIG.BASE_URL}/sets/${set_id}/`, set); - return response.data; -}; - -export default updateSet; \ No newline at end of file diff --git a/web-app/src/components/lens_issues/LensIssueViewModal.jsx b/web-app/src/components/lens_issues/LensIssueViewModal.jsx index e96fdbc..ac0429f 100644 --- a/web-app/src/components/lens_issues/LensIssueViewModal.jsx +++ b/web-app/src/components/lens_issues/LensIssueViewModal.jsx @@ -72,7 +72,7 @@ const LensIssueViewModal = ({visible, onCancel, lensIssue}) => { LensIssueViewModal.propTypes = { visible: PropTypes.bool.isRequired, onCancel: PropTypes.func.isRequired, - lensIssue: LensIssuePropType.isRequired, + lensIssue: LensIssuePropType, }; export default LensIssueViewModal; \ No newline at end of file diff --git a/web-app/src/hooks/data/useIssues.js b/web-app/src/hooks/data/useIssues.js new file mode 100644 index 0000000..0d6f379 --- /dev/null +++ b/web-app/src/hooks/data/useIssues.js @@ -0,0 +1,47 @@ +import {useDispatch, useSelector} from "react-redux"; +import {useAddLensIssuesMutation, useGetLensIssuesQuery} from "../../redux/services/lensIssuesApi.js"; +import {notification} from "antd"; +import {closeModal} from "../../redux/slices/lensIssuesSlice.js"; + + +const useIssues = () => { + const dispatch = useDispatch(); + const { + selectedIssue, + } = useSelector(state => state.lensIssuesUI); + + const {data: issues = [], isLoading, isError, error} = useGetLensIssuesQuery(undefined, { + pollingInterval: 20000, + }); + const [addIssue] = useAddLensIssuesMutation(); + + const handleSubmitFormModal = async (issueDate, patientId, lensId) => { + dispatch(closeModal()); + + try { + await addIssue({issue_date: issueDate, patient_id: patientId, lens_id: lensId}); + notification.success({ + message: "Линза выдана", + description: "Линза успешно выдана пациенту.", + placement: "topRight", + }); + } catch (error) { + notification.error({ + message: "Ошибка выдачи линзы", + description: error.data?.message || "Не удалось выдать линзу пациенту.", + placement: "topRight", + }); + } + }; + + return { + issues, + isLoading, + isError, + error, + selectedIssue, + handleSubmitFormModal, + }; +}; + +export default useIssues; \ No newline at end of file diff --git a/web-app/src/hooks/ui/useIssuesUI.js b/web-app/src/hooks/ui/useIssuesUI.js new file mode 100644 index 0000000..3cc5b97 --- /dev/null +++ b/web-app/src/hooks/ui/useIssuesUI.js @@ -0,0 +1,131 @@ +import {useDispatch, useSelector} from "react-redux"; +import {getCachedInfo} from "../../utils/cachedInfoUtils.js"; +import { + closeModal, + openModal, + selectIssue, + setCurrentPage, + setEndFilterDate, + setPageSize, + setSearchText, + setStartFilterDate, + setViewMode +} from "../../redux/slices/lensIssuesSlice.js"; +import {useEffect, useMemo} from "react"; +import dayjs from "dayjs"; + + +const useIssuesUI = (issues) => { + const dispatch = useDispatch(); + const { + searchText, + currentPage, + pageSize, + selectedIssue, + isModalVisible, + viewMode, + startFilterDate, + endFilterDate, + } = useSelector(state => state.lensIssuesUI); + + useEffect(() => { + document.title = "Выдача линз"; + const cachedViewMode = getCachedInfo("viewModeIssues"); + if (cachedViewMode) dispatch(setViewMode(cachedViewMode)); + }, [dispatch]) + + const startFilterDateConverted = startFilterDate ? dayjs(startFilterDate) : null; + const endFilterDateConverted = endFilterDate ? dayjs(endFilterDate) : null; + const filterDates = [startFilterDateConverted, endFilterDateConverted]; + const isFilterDates = startFilterDate && endFilterDate; + + const handleSetSearchText = (value) => dispatch(setSearchText(value)); + const handleSetViewMode = (mode) => dispatch(setViewMode(mode)); + const handleSetCurrentPage = (page) => dispatch(setCurrentPage(page)); + const handleSetPageSize = (size) => dispatch(setPageSize(size)); + const handleCloseModal = () => dispatch(closeModal()); + const handleSelectIssue = (issue) => dispatch(selectIssue(issue)); + const resetSelectedIssue = () => dispatch(selectIssue(null)); + + const handleAddIssue = () => { + dispatch(selectIssue(null)); + dispatch(openModal()); + }; + + const handlePaginationChange = (page, pageSize) => { + handleSetCurrentPage(page); + handleSetPageSize(pageSize); + }; + + const handleFilterDateChange = (dates) => { + if (dates) { + const [start, end] = dates; + dispatch(setStartFilterDate(start.toISOString())); + dispatch(setEndFilterDate(end.toISOString())); + } + }; + + const handleResetFilterDate = () => { + dispatch(setStartFilterDate(null)); + dispatch(setEndFilterDate(null)); + }; + + const filteredIssues = useMemo(() => { + return issues.filter(issue => { + let dateFilter = true; + + if (startFilterDateConverted && endFilterDateConverted) { + const issueDate = dayjs(issue.issue_date); + + dateFilter = issueDate.isAfter(startFilterDateConverted) && issueDate.isBefore(endFilterDateConverted); + } + + return ( + ( + issue.patient.last_name.toLowerCase().includes(searchText) || + issue.patient.first_name.toLowerCase().includes(searchText) || + issue.doctor.last_name.toLowerCase().includes(searchText) || + issue.doctor.first_name.toLowerCase().includes(searchText) + ) && + dateFilter + ) + }); + }, [issues, searchText, startFilterDateConverted, endFilterDateConverted]); + + const pagination = { + current: currentPage, + pageSize: pageSize, + showSizeChanger: true, + pageSizeOptions: ["5", "10", "20", "50"], + onChange: (page, newPageSize) => { + setCurrentPage(page); + setPageSize(newPageSize); + }, + }; + + return { + filteredIssues, + pagination, + searchText, + selectedIssue, + isModalVisible, + viewMode, + currentPage, + pageSize, + filterDates, + isFilterDates, + handleAddIssue, + handlePaginationChange, + handleSetSearchText, + handleSetViewMode, + handleSetCurrentPage, + handleSetPageSize, + handleCloseModal, + handleFilterDateChange, + resetSelectedIssue, + handleSelectIssue, + handleResetFilterDate, + }; +}; + +export default useIssuesUI; \ No newline at end of file diff --git a/web-app/src/hooks/ui/useSetsUI.js b/web-app/src/hooks/ui/useSetsUI.js index b91f806..7223605 100644 --- a/web-app/src/hooks/ui/useSetsUI.js +++ b/web-app/src/hooks/ui/useSetsUI.js @@ -1,5 +1,5 @@ import {useDispatch, useSelector} from "react-redux"; -import {useEffect} from "react"; +import {useEffect, useMemo} from "react"; import { closeModal, openModal, @@ -24,9 +24,9 @@ const useSetsUI = (sets) => { document.title = "Наборы линз"; }, [dispatch]); - const containerStyle = { padding: 20 }; - const filterBarStyle = { marginBottom: 20 }; - const formItemStyle = { width: "100%" }; + const containerStyle = {padding: 20}; + const filterBarStyle = {marginBottom: 20}; + const formItemStyle = {width: "100%"}; const handleSetSearchText = (value) => dispatch(setSearchText(value)); const handleCloseModal = () => dispatch(closeModal()); @@ -58,7 +58,10 @@ const useSetsUI = (sets) => { }, }; - const filteredSets = sets.filter(set => set.title.toLowerCase().includes(searchText.toLowerCase())); + const filteredSets = useMemo( + () => sets.filter(set => set.title.toLowerCase().includes(searchText.toLowerCase())), + [sets, searchText] + ); return { searchText, diff --git a/web-app/src/pages/IssuesPage.jsx b/web-app/src/pages/IssuesPage.jsx index 13e0507..5a48499 100644 --- a/web-app/src/pages/IssuesPage.jsx +++ b/web-app/src/pages/IssuesPage.jsx @@ -1,5 +1,4 @@ import { - notification, Table, Input, Row, @@ -9,130 +8,28 @@ import { Button, FloatButton, Typography, - Timeline, Grid, Pagination + Timeline, + Grid, + Pagination } from "antd"; -import getAllLensIssues from "../api/lens_issues/getAllLensIssues.js"; -import {useEffect, useState} from "react"; -import {useAuth} from "../AuthContext.jsx"; import {DatabaseOutlined, PlusOutlined, UnorderedListOutlined} from "@ant-design/icons"; import LensIssueViewModal from "../components/lens_issues/LensIssueViewModal.jsx"; import dayjs from "dayjs"; import LensIssueFormModal from "../components/lens_issues/LensIssueFormModal.jsx"; -import addLensIssue from "../api/lens_issues/addLensIssue.js"; import SelectViewMode from "../components/SelectViewMode.jsx"; import LoadingIndicator from "../components/LoadingIndicator.jsx"; -import {getCachedInfo, getCacheTimestamp} from "../utils/cachedInfoUtils.js"; +import useIssues from "../hooks/data/useIssues.js"; +import useIssuesUI from "../hooks/ui/useIssuesUI.js"; const {Title} = Typography; const {useBreakpoint} = Grid; const IssuesPage = () => { - const {api} = useAuth(); + const issuesData = useIssues(); + const issuesUI = useIssuesUI(issuesData.issues); + const screens = useBreakpoint(); - const [loading, setLoading] = useState(true); - const [lensIssues, setLensIssues] = useState([]); - const [searchTerm, setSearchTerm] = useState(""); - const [selectedIssue, setSelectedIssue] = useState(null); - const [isModalVisible, setIsModalVisible] = useState(false); - const [viewMode, setViewMode] = useState("table"); - - const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); - - const [timelinePage, setTimelinePage] = useState(1); - const [timeLinePageSize, setTimeLinePageSize] = useState(10); - - const [startFilterDate, setStartFilterDate] = useState(null); - const [endFilterDate, setEndFilterDate] = useState(null); - - useEffect(() => { - fetchLensIssuesWithCache(); - fetchViewModeFromCache(); - document.title = "Выдача линз"; - }, []); - - useEffect(() => { - if (!isModalVisible) { - const intervalId = setInterval(fetchLensIssues, 5000); - return () => clearInterval(intervalId); - } - }, [isModalVisible]); - - const fetchLensIssuesWithCache = async () => { - const cachedData = getCachedInfo("lensIssuesData"); - const cacheTimestamp = getCacheTimestamp("lensIssuesData"); - - if (cachedData && cacheTimestamp && (Date.now() - cacheTimestamp) < 60 * 1000) { - setLensIssues(JSON.parse(cachedData)); - setLoading(false); - } else { - await fetchLensIssues(); - } - }; - - const fetchViewModeFromCache = () => { - const cachedViewMode = getCachedInfo("viewModeIssues"); - if (cachedViewMode) { - setViewMode(cachedViewMode); - } - }; - - const handleAddIssue = () => { - setSelectedIssue(null); - setIsModalVisible(true); - }; - - const handleCloseViewModal = () => { - setSelectedIssue(null); - }; - - const handleCloseFormModal = () => { - setIsModalVisible(false); - }; - - const handleSubmitFormModal = async (issue_date, patient_id, lens_id) => { - setIsModalVisible(false); - await addLensIssue(api, {issue_date, patient_id, lens_id}); - notification.success({ - message: "Линза выдана", - description: "Линза успешно выдана пациенту.", - placement: "topRight", - }); - await fetchLensIssues(); - }; - - const fetchLensIssues = async () => { - const data = await getAllLensIssues(api); - setLensIssues(data); - setLoading(false); - }; - - const handleSearch = (e) => { - setSearchTerm(e.target.value.toLowerCase()); - }; - - const filteredIssues = lensIssues.filter(issue => { - let dateFilter = true; - - if (startFilterDate && endFilterDate) { - const issueDate = dayjs(issue.issue_date); - - dateFilter = issueDate.isAfter(startFilterDate) && issueDate.isBefore(endFilterDate); - } - - return ( - ( - issue.patient.last_name.toLowerCase().includes(searchTerm) || - issue.patient.first_name.toLowerCase().includes(searchTerm) || - issue.doctor.last_name.toLowerCase().includes(searchTerm) || - issue.doctor.first_name.toLowerCase().includes(searchTerm) - ) && - dateFilter - ) - } - ); - const viewModes = [ { value: "table", @@ -176,7 +73,7 @@ const IssuesPage = () => { title: "Действия", key: "actions", render: (_, issue) => ( - + ), }, ]; @@ -184,23 +81,14 @@ const IssuesPage = () => { const TableView = () => ( { - setCurrentPage(page); - setPageSize(newPageSize); - }, - }} + pagination={issuesUI.pagination} showSorterTooltip={false} /> ); - const timeLineItems = filteredIssues.map(issue => ({ + const timeLineItems = issuesUI.filteredIssues.map(issue => ({ label: dayjs(issue.issue_date).format("DD.MM.YYYY"), children: ( { issuesUI.handleSetSearchText(e.target.value)} style={{width: "100%"}} allowClear /> { style={{width: "100%"}} placeholder={["Дата начала", "Дата окончания"]} format="DD.MM.YYYY" - value={[startFilterDate, endFilterDate]} - onChange={(dates) => { - setStartFilterDate(dates[0]); - setEndFilterDate(dates[1]); - }} + value={issuesUI.isFilterDates && issuesUI.filterDates} + onChange={issuesUI.handleFilterDateChange} /> - {startFilterDate && endFilterDate && ( + {issuesUI.isFilterDates && ( - {loading ? ( + {issuesData.isLoading ? ( - ) : viewMode === "table" ? ( + ) : issuesUI.viewMode === "table" ? ( ) : ( @@ -337,21 +216,20 @@ const IssuesPage = () => { } type={"primary"} - style={{position: "fixed", bottom: 40, right: 40}} - onClick={handleAddIssue} + onClick={issuesUI.handleAddIssue} tooltip={"Добавить выдачу линзы"} /> ); diff --git a/web-app/src/redux/services/lensIssuesApi.js b/web-app/src/redux/services/lensIssuesApi.js new file mode 100644 index 0000000..f6718f0 --- /dev/null +++ b/web-app/src/redux/services/lensIssuesApi.js @@ -0,0 +1,36 @@ +import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/query/react"; +import CONFIG from "../../core/сonfig.js"; + + +export const lensIssuesApi = createApi({ + reducerPath: 'lensIssuesApi', + baseQuery: fetchBaseQuery({ + baseUrl: CONFIG.BASE_URL, + prepareHeaders: (headers) => { + const token = localStorage.getItem('access_token'); + if (token) headers.set('Authorization', `Bearer ${token}`); + return headers; + } + }), + tagTypes: ['LensIssues'], + endpoints: (builder) => ({ + getLensIssues: builder.query({ + query: () => '/lens_issues/', + providesTags: ['LensIssues'], + refetchOnMountOrArgChange: 5 + }), + addLensIssues: builder.mutation({ + query: (lensIssues) => ({ + url: `/lens_issues/`, + method: 'POST', + body: lensIssues + }), + invalidatesTags: ['LensIssues'] + }), + }), +}); + +export const { + useGetLensIssuesQuery, + useAddLensIssuesMutation +} = lensIssuesApi; \ No newline at end of file diff --git a/web-app/src/redux/services/patientsApi.js b/web-app/src/redux/services/patientsApi.js index b81dcc5..00eba9d 100644 --- a/web-app/src/redux/services/patientsApi.js +++ b/web-app/src/redux/services/patientsApi.js @@ -49,4 +49,4 @@ export const { useAddPatientMutation, useUpdatePatientMutation, useDeletePatientMutation, -} = patientsApi; +} = patientsApi; \ No newline at end of file diff --git a/web-app/src/redux/slices/lensIssuesSlice.js b/web-app/src/redux/slices/lensIssuesSlice.js new file mode 100644 index 0000000..4bb1461 --- /dev/null +++ b/web-app/src/redux/slices/lensIssuesSlice.js @@ -0,0 +1,64 @@ +import {createSlice} from "@reduxjs/toolkit"; +import {cacheInfo} from "../../utils/cachedInfoUtils.js"; +import dayjs from "dayjs"; + +const initialState = { + searchText: '', + currentPage: 1, + pageSize: 10, + selectedIssue: null, + isModalVisible: false, + viewMode: 'table', + startFilterDate: null, + endFilterDate: null, +}; + +const lensIssuesSlice = createSlice({ + name: 'setIssuesUI', + initialState, + reducers: { + setSearchText: (state, action) => { + state.searchText = action.payload; + }, + setCurrentPage: (state, action) => { + state.currentPage = action.payload; + }, + setPageSize: (state, action) => { + state.pageSize = action.payload; + }, + selectIssue: (state, action) => { + state.selectedIssue = action.payload; + }, + openModal: (state) => { + state.isModalVisible = true; + }, + closeModal: (state) => { + state.isModalVisible = false; + state.selectedIssue = null; + }, + setViewMode: (state, action) => { + state.viewMode = action.payload; + cacheInfo("viewModeIssues", action.payload); + }, + setStartFilterDate: (state, action) => { + state.startFilterDate = action.payload; + }, + setEndFilterDate: (state, action) => { + state.endFilterDate = action.payload; + }, + }, +}); + +export const { + setSearchText, + setCurrentPage, + setPageSize, + selectIssue, + openModal, + closeModal, + setViewMode, + setStartFilterDate, + setEndFilterDate, +} = lensIssuesSlice.actions; + +export default lensIssuesSlice.reducer; \ No newline at end of file diff --git a/web-app/src/redux/store.js b/web-app/src/redux/store.js index 51a4ed8..ceb0918 100644 --- a/web-app/src/redux/store.js +++ b/web-app/src/redux/store.js @@ -6,6 +6,8 @@ import lensesUIReducer from './slices/lensesSlice.js'; import {setsApi} from "./services/setsApi.js"; import setsUIReducer from './slices/setsSlice.js'; import {setContentApi} from "./services/setContentApi.js"; +import {lensIssuesApi} from "./services/lensIssuesApi.js"; +import lensIssuesReducer from "./slices/lensIssuesSlice.js"; export const store = configureStore({ reducer: { @@ -19,6 +21,9 @@ export const store = configureStore({ setsUI: setsUIReducer, [setContentApi.reducerPath]: setContentApi.reducer, + + [lensIssuesApi.reducerPath]: lensIssuesApi.reducer, + lensIssuesUI: lensIssuesReducer, }, middleware: (getDefaultMiddleware) => ( getDefaultMiddleware().concat( @@ -26,6 +31,7 @@ export const store = configureStore({ lensesApi.middleware, setsApi.middleware, setContentApi.middleware, + lensIssuesApi.middleware, ) ) });