сменил расширение с .jsx на .js у файлов не содержащих компоненты. начал внедрять redux
This commit is contained in:
parent
396aee3ab7
commit
3dec01804a
99
web-app/package-lock.json
generated
99
web-app/package-lock.json
generated
@ -11,6 +11,7 @@
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@react-buddy/ide-toolbox": "^2.4.0",
|
||||
"@react-buddy/palette-antd": "^5.3.0",
|
||||
"@reduxjs/toolkit": "^2.6.1",
|
||||
"antd": "^5.23.1",
|
||||
"antd-dayjs-webpack-plugin": "^1.0.6",
|
||||
"antd-mask-input": "^2.0.7",
|
||||
@ -19,6 +20,7 @@
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-router-dom": "^7.1.1",
|
||||
"validator": "^13.12.0"
|
||||
},
|
||||
@ -970,6 +972,30 @@
|
||||
"react": "^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@reduxjs/toolkit": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.1.tgz",
|
||||
"integrity": "sha512-SSlIqZNYhqm/oMkXbtofwZSt9lrncblzo6YcZ9zoX+zLngRBrCOjK4lNLdkNucJF58RHOWrD9txT3bT3piH7Zw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"immer": "^10.0.3",
|
||||
"redux": "^5.0.1",
|
||||
"redux-thunk": "^3.1.0",
|
||||
"reselect": "^5.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
|
||||
"react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.35.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz",
|
||||
@ -1486,14 +1512,14 @@
|
||||
"version": "15.7.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
|
||||
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.3.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
|
||||
"integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
@ -1510,6 +1536,12 @@
|
||||
"@types/react": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/use-sync-external-store": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
|
||||
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vitejs/plugin-react-swc": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.8.0.tgz",
|
||||
@ -3026,6 +3058,16 @@
|
||||
"npm": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/immer": {
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
|
||||
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/immer"
|
||||
}
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||
@ -4609,6 +4651,29 @@
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^18.2.25 || ^19",
|
||||
"react": "^18.0 || ^19",
|
||||
"redux": "^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.3.0.tgz",
|
||||
@ -4649,6 +4714,21 @@
|
||||
"react-dom": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/redux": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
|
||||
"integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"redux": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
@ -4699,6 +4779,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/reselect": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
||||
"integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
@ -5309,6 +5395,15 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-sync-external-store": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
|
||||
"integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "13.12.0",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz",
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@react-buddy/ide-toolbox": "^2.4.0",
|
||||
"@react-buddy/palette-antd": "^5.3.0",
|
||||
"@reduxjs/toolkit": "^2.6.1",
|
||||
"antd": "^5.23.1",
|
||||
"antd-dayjs-webpack-plugin": "^1.0.6",
|
||||
"antd-mask-input": "^2.0.7",
|
||||
@ -21,6 +22,7 @@
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-router-dom": "^7.1.1",
|
||||
"validator": "^13.12.0"
|
||||
},
|
||||
|
||||
@ -2,13 +2,17 @@ import {BrowserRouter as Router} from "react-router-dom";
|
||||
import AppRouter from "./AppRouter.jsx";
|
||||
import {AuthProvider} from "./AuthContext.jsx";
|
||||
import "/src/styles/app.css";
|
||||
import {Provider} from "react-redux";
|
||||
import store from "./redux/store";
|
||||
|
||||
const App = () => (
|
||||
<Router>
|
||||
<AuthProvider>
|
||||
<AppRouter/>
|
||||
</AuthProvider>
|
||||
</Router>
|
||||
<Provider store={store}>
|
||||
<Router>
|
||||
<AuthProvider>
|
||||
<AppRouter/>
|
||||
</AuthProvider>
|
||||
</Router>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {createContext, useState, useContext, useEffect} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import loginUser from "./api/auth/loginRequest.jsx";
|
||||
import loginUser from "./api/auth/loginRequest.js";
|
||||
import {Spin} from "antd";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import createApi from "./core/axiosConfig.jsx";
|
||||
import createApi from "./core/axiosConfig.js";
|
||||
|
||||
const AuthContext = createContext(undefined);
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllAppointments = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/appointments/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const loginUser = async (loginData, api) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/login/`, loginData, {
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const AddLensIssue = async (api, lens_issue) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/lens_issues/`, lens_issue);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const GetAllLensIssues = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/lens_issues/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllLensTypes = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/lens_types/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const addLens = async (api, lens) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/lenses/`, lens);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const deleteLens = async (api, lens_id) => {
|
||||
const response = await api.delete(`${CONFIG.BASE_URL}/lenses/${lens_id}/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllLenses = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/lenses/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getNotIssuedLenses = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/lenses/not_issued/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const updateLens = async (api, lensId, lensData) => {
|
||||
const response = await api.put(`${CONFIG.BASE_URL}/lenses/${lensId}/`, lensData);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const addPatient = async (api, patient) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/patients/`, patient);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const deletePatient = async (api, patient_id) => {
|
||||
const response = await api.delete(`${CONFIG.BASE_URL}/patients/${patient_id}/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllPatients = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/patients/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const updatePatient = async (api, patientId, patientData) => {
|
||||
const response = await api.put(`${CONFIG.BASE_URL}/patients/${patientId}/`, patientData);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllScheduledAppointments = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/scheduled_appointments/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
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);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getSetContentBySetId = async (api, set_id) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/set_content/${set_id}/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
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);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const addSet = async (api, set) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/sets/`, set);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
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}/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const deleteSet = async (api, set_id) => {
|
||||
const response = await api.delete(`${CONFIG.BASE_URL}/sets/${set_id}/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllSets = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/sets/`);
|
||||
@ -1,4 +1,4 @@
|
||||
import CONFIG from "../../core/сonfig.jsx";
|
||||
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);
|
||||
@ -1,8 +1,8 @@
|
||||
import {BuildOutlined, TableOutlined} from "@ant-design/icons";
|
||||
import {Select, Tooltip} from "antd";
|
||||
import PropTypes from "prop-types";
|
||||
import {cacheInfo} from "../utils/cachedInfoUtils.jsx";
|
||||
import {ViewModPropType} from "../types/viewModPropType.jsx";
|
||||
import {cacheInfo} from "../utils/cachedInfoUtils.js";
|
||||
import {ViewModPropType} from "../types/viewModPropType.js";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
|
||||
@ -1,7 +1,22 @@
|
||||
import PropTypes from "prop-types";
|
||||
import {AppointmentPropType} from "../../types/appointmentPropType.js";
|
||||
import {ScheduledAppointmentPropType} from "../../types/scheduledAppointmentPropType.js";
|
||||
import {Modal} from "antd";
|
||||
|
||||
|
||||
const AppointmentCellViewModal = ({visible, onCancel, appointment}) => {
|
||||
return (
|
||||
<Modal
|
||||
open={visible}
|
||||
title={``}
|
||||
>
|
||||
|
||||
</Modal>
|
||||
)
|
||||
};
|
||||
|
||||
const AppointmentCellViewModal = ({appointment}) => {
|
||||
AppointmentCellViewModal.propTypes = {
|
||||
appointment: PropTypes.oneOfType([ScheduledAppointmentPropType, AppointmentPropType]).isRequired,
|
||||
};
|
||||
|
||||
};
|
||||
export default AppointmentCellViewModal;
|
||||
@ -2,8 +2,8 @@ import {useEffect, useRef, useState} from "react";
|
||||
import {Badge, Col, Tag, Tooltip, Typography} from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import PropTypes from "prop-types";
|
||||
import {AppointmentPropType} from "../../types/appointmentPropType.jsx";
|
||||
import {ScheduledAppointmentPropType} from "../../types/scheduledAppointmentPropType.jsx";
|
||||
import {AppointmentPropType} from "../../types/appointmentPropType.js";
|
||||
import {ScheduledAppointmentPropType} from "../../types/scheduledAppointmentPropType.js";
|
||||
|
||||
|
||||
const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemClick}) => {
|
||||
|
||||
@ -3,10 +3,10 @@ import {
|
||||
Modal, Input, Button, notification, Typography, Collapse, Steps, Row, Alert, Col, DatePicker, Spin, Grid
|
||||
} from "antd";
|
||||
import PropTypes from "prop-types";
|
||||
import getAllPatients from "../../api/patients/getAllPatients.jsx";
|
||||
import getAllPatients from "../../api/patients/getAllPatients.js";
|
||||
import {useAuth} from "../../AuthContext.jsx";
|
||||
import dayjs from "dayjs";
|
||||
import getNotIssuedLenses from "../../api/lenses/getNotIssuedLenses.jsx";
|
||||
import getNotIssuedLenses from "../../api/lenses/getNotIssuedLenses.js";
|
||||
|
||||
const {useBreakpoint} = Grid;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {Collapse, Modal} from "antd";
|
||||
import PropTypes from "prop-types";
|
||||
import {LensIssuePropType} from "../../types/lensIssuePropType.jsx";
|
||||
import {LensIssuePropType} from "../../types/lensIssuePropType.js";
|
||||
|
||||
|
||||
const LensIssueViewModal = ({visible, onCancel, lensIssue}) => {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {Col, Form, InputNumber, Modal, notification, Row, Select} from "antd";
|
||||
import {useEffect, useState} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import getAllLensTypes from "../../api/lens_types/getAllLensTypes.jsx";
|
||||
import getAllLensTypes from "../../api/lens_types/getAllLensTypes.js";
|
||||
import {useAuth} from "../../AuthContext.jsx";
|
||||
import {LensPropType} from "../../types/lensPropType.jsx";
|
||||
import {LensPropType} from "../../types/lensPropType.js";
|
||||
|
||||
|
||||
const LensFormModal = ({visible, onCancel, onSubmit, lens}) => {
|
||||
|
||||
@ -3,7 +3,7 @@ import PropTypes from "prop-types";
|
||||
import {DeleteOutlined, EditOutlined, EyeOutlined} from "@ant-design/icons";
|
||||
import {useState} from "react";
|
||||
import LensViewModal from "./LensViewModal.jsx";
|
||||
import {LensPropType} from "../../types/lensPropType.jsx";
|
||||
import {LensPropType} from "../../types/lensPropType.js";
|
||||
|
||||
const LensListCard = ({lens, handleEditLens, handleDeleteLens}) => {
|
||||
const [showModalInfo, setShowModalInfo] = useState(false);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {Button, Col, Modal, Row, Typography} from "antd";
|
||||
import PropTypes from "prop-types";
|
||||
import {LensPropType} from "../../types/lensPropType.jsx";
|
||||
import {LensPropType} from "../../types/lensPropType.js";
|
||||
|
||||
const {Text, Title} = Typography;
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import locale from "antd/es/date-picker/locale/ru_RU";
|
||||
import validator from "validator";
|
||||
import {MaskedInput} from "antd-mask-input";
|
||||
import dayjs from "dayjs";
|
||||
import {PatientPropType} from "../../types/patientPropType.jsx";
|
||||
import {PatientPropType} from "../../types/patientPropType.js";
|
||||
|
||||
const {TextArea} = Input;
|
||||
|
||||
@ -142,7 +142,7 @@ PatientFormModal.propTypes = {
|
||||
visible: PropTypes.bool.isRequired,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
patient: PatientPropType.isRequired,
|
||||
patient: PatientPropType,
|
||||
};
|
||||
|
||||
export default PatientFormModal;
|
||||
|
||||
@ -3,7 +3,7 @@ import PropTypes from "prop-types";
|
||||
import {DeleteOutlined, EditOutlined, EyeOutlined} from "@ant-design/icons";
|
||||
import {useState} from "react";
|
||||
import PatientViewModal from "./PatientViewModal.jsx";
|
||||
import {PatientPropType} from "../../types/patientPropType.jsx";
|
||||
import {PatientPropType} from "../../types/patientPropType.js";
|
||||
|
||||
const PatientListCard = ({patient, handleEditPatient, handleDeletePatient}) => {
|
||||
const [showModalInfo, setShowModalInfo] = useState(false);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {Button, Col, Modal, Row, Typography, Divider} from "antd";
|
||||
import PropTypes from "prop-types";
|
||||
import {PatientPropType} from "../../types/patientPropType.jsx";
|
||||
import {PatientPropType} from "../../types/patientPropType.js";
|
||||
|
||||
const { Text, Title } = Typography;
|
||||
|
||||
|
||||
@ -2,11 +2,11 @@ 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.jsx";
|
||||
import getAllLensTypes from "../../api/lens_types/getAllLensTypes.js";
|
||||
import {useAuth} from "../../AuthContext.jsx";
|
||||
import PropTypes from "prop-types";
|
||||
import getSetContentBySetId from "../../api/set_content/getSetContentBySetId.jsx";
|
||||
import {SetPropType} from "../../types/setPropType.jsx";
|
||||
import getSetContentBySetId from "../../api/set_content/getSetContentBySetId.js";
|
||||
import {SetPropType} from "../../types/setPropType.js";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import PropTypes from "prop-types";
|
||||
import {Card, Modal, Popconfirm, Tooltip} from "antd";
|
||||
import {DeleteOutlined, EditOutlined, PlusOutlined} from "@ant-design/icons";
|
||||
import {SetPropType} from "../../types/setPropType.jsx";
|
||||
import {SetPropType} from "../../types/setPropType.js";
|
||||
|
||||
const SetListCard = ({set, handleEditSet, handleDeleteSet, handleAppendSet}) => {
|
||||
const deleteSet = () => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import axios from "axios";
|
||||
import CONFIG from "./сonfig.jsx";
|
||||
import CONFIG from "./сonfig.js";
|
||||
import {notification} from "antd";
|
||||
|
||||
const createApi = (logoutAndRedirect) => {
|
||||
@ -6,11 +6,11 @@ import {
|
||||
} from "@ant-design/icons";
|
||||
import AppointmentsCalendarPage from "../pages/appointments_layout/AppointmentsCalendarPage.jsx";
|
||||
import AppointmentsTablePage from "../pages/appointments_layout/AppointmentsTablePage.jsx";
|
||||
import getAllAppointments from "../api/appointments/getAllAppointments.jsx";
|
||||
import getAllScheduledAppointments from "../api/scheduled_appointments/getAllScheduledAppointments.jsx";
|
||||
import getAllAppointments from "../api/appointments/getAllAppointments.js";
|
||||
import getAllScheduledAppointments from "../api/scheduled_appointments/getAllScheduledAppointments.js";
|
||||
import {useAuth} from "../AuthContext.jsx";
|
||||
import LoadingIndicator from "../components/LoadingIndicator.jsx";
|
||||
import {cacheInfo, getCachedInfo, getCacheTimestamp} from "../utils/cachedInfoUtils.jsx";
|
||||
import {cacheInfo, getCachedInfo, getCacheTimestamp} from "../utils/cachedInfoUtils.js";
|
||||
|
||||
const {useBreakpoint} = Grid;
|
||||
|
||||
|
||||
@ -5,5 +5,5 @@ import App from './App.jsx'
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App/>
|
||||
</StrictMode>,
|
||||
</StrictMode>
|
||||
)
|
||||
|
||||
@ -11,17 +11,17 @@ import {
|
||||
Typography,
|
||||
Timeline, Grid, Pagination
|
||||
} from "antd";
|
||||
import getAllLensIssues from "../api/lens_issues/getAllLensIssues.jsx";
|
||||
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.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.jsx";
|
||||
import {getCachedInfo, getCacheTimestamp} from "../utils/cachedInfoUtils.js";
|
||||
|
||||
const {Title} = Typography;
|
||||
const {useBreakpoint} = Grid;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {useEffect} from 'react';
|
||||
import {
|
||||
Input,
|
||||
Select,
|
||||
@ -11,7 +11,7 @@ import {
|
||||
Table,
|
||||
Button,
|
||||
Popconfirm,
|
||||
Typography
|
||||
Typography, Result
|
||||
} from "antd";
|
||||
import {
|
||||
BuildOutlined,
|
||||
@ -20,79 +20,109 @@ import {
|
||||
SortDescendingOutlined, TableOutlined,
|
||||
TeamOutlined
|
||||
} from "@ant-design/icons";
|
||||
import {useAuth} from "../AuthContext.jsx";
|
||||
import getAllPatients from "../api/patients/getAllPatients.jsx";
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {
|
||||
useAddPatientMutation,
|
||||
useDeletePatientMutation,
|
||||
useGetPatientsQuery,
|
||||
useUpdatePatientMutation
|
||||
} from "../redux/services/patientsApi.js";
|
||||
import {
|
||||
openModal,
|
||||
selectPatient,
|
||||
setSearchText,
|
||||
setSortOrder,
|
||||
setViewMode,
|
||||
closeModal, setCurrentPage, setPageSize
|
||||
} from "../redux/slices/patientsSlice.js";
|
||||
import PatientListCard from "../components/patients/PatientListCard.jsx";
|
||||
import PatientFormModal from "../components/patients/PatientFormModal.jsx";
|
||||
import updatePatient from "../api/patients/updatePatient.jsx";
|
||||
import addPatient from "../api/patients/addPatient.jsx";
|
||||
import deletePatient from "../api/patients/deletePatient.jsx";
|
||||
import SelectViewMode from "../components/SelectViewMode.jsx";
|
||||
import LoadingIndicator from "../components/LoadingIndicator.jsx";
|
||||
import {cacheInfo, getCachedInfo, getCacheTimestamp} from "../utils/cachedInfoUtils.jsx";
|
||||
import {getCachedInfo} from "../utils/cachedInfoUtils.js";
|
||||
|
||||
const {Option} = Select;
|
||||
const {Title} = Typography
|
||||
|
||||
const PatientsPage = () => {
|
||||
const {api} = useAuth();
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const [sortOrder, setSortOrder] = useState("asc");
|
||||
const [viewMode, setViewMode] = useState("tile");
|
||||
const [patients, setPatients] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [current, setCurrent] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const {
|
||||
searchText,
|
||||
sortOrder,
|
||||
viewMode,
|
||||
selectedPatient,
|
||||
isModalVisible
|
||||
} = useSelector(state => state.patientsUI);
|
||||
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [selectedPatient, setSelectedPatient] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const {data: patients = [], isLoading, isError} = useGetPatientsQuery();
|
||||
const [addPatient] = useAddPatientMutation();
|
||||
const [updatePatient] = useUpdatePatientMutation();
|
||||
const [deletePatient] = useDeletePatientMutation();
|
||||
|
||||
useEffect(() => {
|
||||
fetchPatientsWithCache();
|
||||
fetchViewModeFromCache();
|
||||
document.title = "Пациенты";
|
||||
document.title = "Пациенты"
|
||||
const cachedViewMode = getCachedInfo("viewModePatients");
|
||||
if (cachedViewMode) dispatch(setViewMode(cachedViewMode));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isModalVisible && !selectedPatient) {
|
||||
const intervalId = setInterval(fetchPatients, 5000);
|
||||
return () => clearInterval(intervalId);
|
||||
}
|
||||
}, [isModalVisible, selectedPatient]);
|
||||
|
||||
const fetchPatientsWithCache = async () => {
|
||||
const cachedData = getCachedInfo("patientsData");
|
||||
const cacheTimestamp = getCacheTimestamp("patientsData");
|
||||
|
||||
if (cachedData && cacheTimestamp && (Date.now() - cacheTimestamp) < 60 * 1000) {
|
||||
setPatients(cachedData);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await fetchPatients();
|
||||
const handleAddPatient = () => {
|
||||
dispatch(selectPatient(null));
|
||||
dispatch(openModal());
|
||||
};
|
||||
|
||||
const fetchPatients = async () => {
|
||||
const data = await getAllPatients(api);
|
||||
setPatients(data);
|
||||
|
||||
cacheInfo("patientsData", data);
|
||||
setLoading(false);
|
||||
const handleEditPatient = (patient) => {
|
||||
dispatch(selectPatient(patient));
|
||||
dispatch(openModal());
|
||||
};
|
||||
|
||||
const fetchViewModeFromCache = () => {
|
||||
const cachedViewMode = getCachedInfo("viewModePatients");
|
||||
if (cachedViewMode) {
|
||||
setViewMode(cachedViewMode);
|
||||
const handleDeletePatient = async (patientId) => {
|
||||
try {
|
||||
await deletePatient(patientId).unwrap()
|
||||
notification.success({
|
||||
message: "Пациент удалён",
|
||||
description: "Пациент успешно удалён из базы.",
|
||||
placement: "topRight",
|
||||
});
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: "Ошибка удаления",
|
||||
description: error.data?.message || "Не удалось удалить пациента",
|
||||
placement: "topRight",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleModalPatientSubmit = async (patientData) => {
|
||||
try {
|
||||
if (selectedPatient) {
|
||||
await updatePatient({id: selectedPatient.id, ...patientData}).unwrap()
|
||||
notification.success({
|
||||
message: "Пациент обновлён",
|
||||
description: `Данные пациента ${patientData.first_name} ${patientData.last_name} успешно обновлены.`,
|
||||
placement: "topRight",
|
||||
})
|
||||
} else {
|
||||
await addPatient(patientData).unwrap()
|
||||
notification.success({
|
||||
message: "Пациент добавлен",
|
||||
description: `Пациент ${patientData.first_name} ${patientData.last_name} успешно добавлен.`,
|
||||
placement: "topRight",
|
||||
});
|
||||
}
|
||||
dispatch(closeModal());
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: "Ошибка",
|
||||
description: error.data?.message || "Произошла ошибка при сохранении",
|
||||
placement: "topRight",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const filteredPatients = patients
|
||||
.filter((patient) => {
|
||||
.filter(patient => {
|
||||
const searchLower = searchText.toLowerCase();
|
||||
|
||||
return Object.values(patient)
|
||||
.filter(value => typeof value === "string")
|
||||
.some(value => value.toLowerCase().includes(searchLower));
|
||||
@ -100,96 +130,11 @@ const PatientsPage = () => {
|
||||
.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);
|
||||
return sortOrder === "asc"
|
||||
? fullNameA.localeCompare(fullNameB)
|
||||
: fullNameB.localeCompare(fullNameA);
|
||||
});
|
||||
|
||||
const handleAddPatient = () => {
|
||||
setSelectedPatient(null);
|
||||
setIsModalVisible(true);
|
||||
};
|
||||
|
||||
const handleEditPatient = (patient) => {
|
||||
setSelectedPatient(patient);
|
||||
setIsModalVisible(true);
|
||||
};
|
||||
|
||||
const handleDeletePatient = async (patient_id) => {
|
||||
await deletePatient(api, patient_id);
|
||||
await fetchPatients();
|
||||
notification.success({
|
||||
message: "Пациент удалён",
|
||||
description: "Пациент успешно удалён из базы.",
|
||||
placement: "topRight",
|
||||
});
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setIsModalVisible(false);
|
||||
};
|
||||
|
||||
const handleModalPatientSubmit = async (newPatient) => {
|
||||
setIsModalVisible(false);
|
||||
|
||||
if (selectedPatient) {
|
||||
await editPatient(newPatient);
|
||||
} else {
|
||||
await addNewPatient(newPatient);
|
||||
}
|
||||
await fetchPatients();
|
||||
};
|
||||
|
||||
const editPatient = async (patient) => {
|
||||
await updatePatient(api, selectedPatient.id, patient);
|
||||
notification.success({
|
||||
message: "Пациент обновлён",
|
||||
description: `Данные пациента ${patient.first_name} ${patient.last_name} успешно обновлены.`,
|
||||
placement: "topRight",
|
||||
});
|
||||
};
|
||||
|
||||
const addNewPatient = async (patient) => {
|
||||
await addPatient(api, patient);
|
||||
notification.success({
|
||||
message: "Пациент добавлен",
|
||||
description: `Пациент ${patient.first_name} ${patient.last_name} успешно добавлен.`,
|
||||
placement: "topRight",
|
||||
});
|
||||
};
|
||||
|
||||
const TileView = () => (
|
||||
<List
|
||||
grid={{
|
||||
gutter: 16,
|
||||
xs: 1,
|
||||
sm: 1,
|
||||
md: 2,
|
||||
lg: 2,
|
||||
xl: 3,
|
||||
xxl: 3,
|
||||
}}
|
||||
dataSource={filteredPatients}
|
||||
renderItem={(patient) => (
|
||||
<List.Item>
|
||||
<PatientListCard
|
||||
patient={patient}
|
||||
handleEditPatient={handleEditPatient}
|
||||
handleDeletePatient={handleDeletePatient}
|
||||
/>
|
||||
</List.Item>
|
||||
)}
|
||||
pagination={{
|
||||
current,
|
||||
pageSize,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["5", "10", "20", "50"],
|
||||
onChange: (page, newPageSize) => {
|
||||
setCurrent(page);
|
||||
setPageSize(newPageSize);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const viewModes = [
|
||||
{
|
||||
value: "tile",
|
||||
@ -277,17 +222,61 @@ const PatientsPage = () => {
|
||||
}}
|
||||
showSorterTooltip={false}
|
||||
pagination={{
|
||||
current,
|
||||
pageSize,
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["5", "10", "20", "50"],
|
||||
onChange: (page, newPageSize) => {
|
||||
setCurrent(page);
|
||||
setPageSize(newPageSize);
|
||||
dispatch(setCurrentPage(page));
|
||||
dispatch(setPageSize(newPageSize));
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
const TileView = () => (
|
||||
<List
|
||||
grid={{
|
||||
gutter: 16,
|
||||
xs: 1,
|
||||
sm: 1,
|
||||
md: 2,
|
||||
lg: 2,
|
||||
xl: 3,
|
||||
xxl: 3,
|
||||
}}
|
||||
dataSource={filteredPatients}
|
||||
renderItem={(patient) => (
|
||||
<List.Item>
|
||||
<PatientListCard
|
||||
patient={patient}
|
||||
handleEditPatient={handleEditPatient}
|
||||
handleDeletePatient={handleDeletePatient}
|
||||
/>
|
||||
</List.Item>
|
||||
)}
|
||||
pagination={{
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["5", "10", "20", "50"],
|
||||
onChange: (page, newPageSize) => {
|
||||
dispatch(setCurrentPage(page));
|
||||
dispatch(setPageSize(newPageSize));
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
if (isError) {
|
||||
return (
|
||||
<Result
|
||||
status="error"
|
||||
title="Ошибка"
|
||||
subTitle="Произошла ошибка в работе страницы"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{padding: 20}}>
|
||||
@ -296,7 +285,8 @@ const PatientsPage = () => {
|
||||
<Col xs={24} md={14} sm={10} xl={18} xxl={19}>
|
||||
<Input
|
||||
placeholder="Поиск пациента"
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
value={searchText}
|
||||
onChange={(e) => dispatch(setSearchText(e.target.value))}
|
||||
style={{width: "100%"}}
|
||||
allowClear
|
||||
/>
|
||||
@ -309,7 +299,7 @@ const PatientsPage = () => {
|
||||
>
|
||||
<Select
|
||||
value={sortOrder}
|
||||
onChange={(value) => setSortOrder(value)}
|
||||
onChange={(value) => dispatch(setSortOrder(value))}
|
||||
style={{width: "100%"}}
|
||||
>
|
||||
<Option value="asc"><SortAscendingOutlined/> А-Я</Option>
|
||||
@ -330,7 +320,7 @@ const PatientsPage = () => {
|
||||
}>
|
||||
<SelectViewMode
|
||||
viewMode={viewMode}
|
||||
setViewMode={setViewMode}
|
||||
setViewMode={(value) => dispatch(setViewMode(value))}
|
||||
localStorageKey={"viewModePatients"}
|
||||
toolTipText={"Формат отображения пациентов"}
|
||||
viewModes={viewModes}
|
||||
@ -338,7 +328,7 @@ const PatientsPage = () => {
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{loading ? (
|
||||
{isLoading ? (
|
||||
<LoadingIndicator/>
|
||||
) : viewMode === "tile" ? (
|
||||
<TileView/>
|
||||
@ -356,7 +346,7 @@ const PatientsPage = () => {
|
||||
|
||||
<PatientFormModal
|
||||
visible={isModalVisible}
|
||||
onCancel={handleCancel}
|
||||
onCancel={() => dispatch(closeModal())}
|
||||
onSubmit={handleModalPatientSubmit}
|
||||
patient={selectedPatient}
|
||||
/>
|
||||
@ -364,4 +354,4 @@ const PatientsPage = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PatientsPage;
|
||||
export default PatientsPage;
|
||||
|
||||
@ -6,8 +6,8 @@ import locale from 'antd/es/locale/ru_RU';
|
||||
import updateLocale from 'dayjs/plugin/updateLocale';
|
||||
import PropTypes, {arrayOf} from "prop-types";
|
||||
import CalendarCell from "../../components/appointments/CalendarCell.jsx";
|
||||
import {AppointmentPropType} from "../../types/appointmentPropType.jsx";
|
||||
import {ScheduledAppointmentPropType} from "../../types/scheduledAppointmentPropType.jsx";
|
||||
import {AppointmentPropType} from "../../types/appointmentPropType.js";
|
||||
import {ScheduledAppointmentPropType} from "../../types/scheduledAppointmentPropType.js";
|
||||
|
||||
const {useBreakpoint} = Grid;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {useAuth} from "../../AuthContext.jsx";
|
||||
import {useEffect, useState} from "react";
|
||||
import getAllAppointments from "../../api/appointments/getAllAppointments.jsx";
|
||||
import getAllAppointments from "../../api/appointments/getAllAppointments.js";
|
||||
import {notification} from "antd";
|
||||
|
||||
|
||||
|
||||
@ -25,15 +25,15 @@ import {
|
||||
BuildOutlined
|
||||
} from "@ant-design/icons";
|
||||
import LensCard from "../../components/lenses/LensListCard.jsx";
|
||||
import getAllLenses from "../../api/lenses/getAllLenses.jsx";
|
||||
import addLens from "../../api/lenses/addLens.jsx";
|
||||
import updateLens from "../../api/lenses/updateLens.jsx";
|
||||
import deleteLens from "../../api/lenses/deleteLens.jsx";
|
||||
import getAllLenses from "../../api/lenses/getAllLenses.js";
|
||||
import addLens from "../../api/lenses/addLens.js";
|
||||
import updateLens from "../../api/lenses/updateLens.js";
|
||||
import deleteLens from "../../api/lenses/deleteLens.js";
|
||||
import {useAuth} from "../../AuthContext.jsx";
|
||||
import LensFormModal from "../../components/lenses/LensFormModal.jsx";
|
||||
import SelectViewMode from "../../components/SelectViewMode.jsx";
|
||||
import LoadingIndicator from "../../components/LoadingIndicator.jsx";
|
||||
import {getCachedInfo, getCacheTimestamp} from "../../utils/cachedInfoUtils.jsx";
|
||||
import {getCachedInfo, getCacheTimestamp} from "../../utils/cachedInfoUtils.js";
|
||||
|
||||
const {Option} = Select;
|
||||
const {useBreakpoint} = Grid;
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
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.jsx";
|
||||
import getAllSets from "../../api/sets/getAllSets.js";
|
||||
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.jsx";
|
||||
import addSet from "../../api/sets/addSet.jsx";
|
||||
import deleteSet from "../../api/sets/deleteSet.jsx";
|
||||
import addSetContent from "../../api/set_content/addSetContent.jsx";
|
||||
import updateSetContent from "../../api/set_content/updateSetContent.jsx";
|
||||
import appendLensesFromSet from "../../api/sets/appendLensesFromSet.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.jsx";
|
||||
import {cacheInfo, getCachedInfo, getCacheTimestamp} from "../../utils/cachedInfoUtils.js";
|
||||
|
||||
|
||||
const {Title} = Typography;
|
||||
|
||||
52
web-app/src/redux/services/patientsApi.js
Normal file
52
web-app/src/redux/services/patientsApi.js
Normal file
@ -0,0 +1,52 @@
|
||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
export const patientsApi = createApi({
|
||||
reducerPath: 'patientsApi',
|
||||
baseQuery: fetchBaseQuery({
|
||||
baseUrl: CONFIG.BASE_URL,
|
||||
prepareHeaders: (headers, { getState }) => {
|
||||
const token = localStorage.getItem('access_token')
|
||||
if (token) headers.set('Authorization', `Bearer ${token}`)
|
||||
return headers
|
||||
}
|
||||
}),
|
||||
tagTypes: ['Patient'],
|
||||
endpoints: (builder) => ({
|
||||
getPatients: builder.query({
|
||||
query: () => '/patients/',
|
||||
providesTags: ['Patient'],
|
||||
refetchOnMountOrArgChange: 60
|
||||
}),
|
||||
addPatient: builder.mutation({
|
||||
query: (patient) => ({
|
||||
url: '/patients/',
|
||||
method: 'POST',
|
||||
body: patient
|
||||
}),
|
||||
invalidatesTags: ['Patient']
|
||||
}),
|
||||
updatePatient: builder.mutation({
|
||||
query: ({ id, ...patient }) => ({
|
||||
url: `/patients/${id}/`,
|
||||
method: 'PUT',
|
||||
body: patient
|
||||
}),
|
||||
invalidatesTags: ['Patient']
|
||||
}),
|
||||
deletePatient: builder.mutation({
|
||||
query: (id) => ({
|
||||
url: `/patients/${id}/`,
|
||||
method: 'DELETE'
|
||||
}),
|
||||
invalidatesTags: ['Patient']
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
export const {
|
||||
useGetPatientsQuery,
|
||||
useAddPatientMutation,
|
||||
useUpdatePatientMutation,
|
||||
useDeletePatientMutation
|
||||
} = patientsApi
|
||||
19
web-app/src/redux/slices/appointmentsSlice.js
Normal file
19
web-app/src/redux/slices/appointmentsSlice.js
Normal file
@ -0,0 +1,19 @@
|
||||
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;
|
||||
57
web-app/src/redux/slices/patientsSlice.js
Normal file
57
web-app/src/redux/slices/patientsSlice.js
Normal file
@ -0,0 +1,57 @@
|
||||
import {createSlice} from '@reduxjs/toolkit'
|
||||
|
||||
const initialState = {
|
||||
searchText: '',
|
||||
sortOrder: 'asc',
|
||||
viewMode: 'tile',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
selectedPatient: null,
|
||||
isModalVisible: false
|
||||
}
|
||||
|
||||
const patientsSlice = createSlice({
|
||||
name: 'patientsUI',
|
||||
initialState,
|
||||
reducers: {
|
||||
setSearchText: (state, action) => {
|
||||
state.searchText = action.payload;
|
||||
},
|
||||
setSortOrder: (state, action) => {
|
||||
state.sortOrder = action.payload;
|
||||
},
|
||||
setViewMode: (state, action) => {
|
||||
state.viewMode = action.payload;
|
||||
localStorage.setItem('viewModePatients', 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.selectedPatient = null;
|
||||
},
|
||||
selectPatient: (state, action) => {
|
||||
state.selectedPatient = action.payload;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const {
|
||||
setSearchText,
|
||||
setSortOrder,
|
||||
setViewMode,
|
||||
setCurrentPage,
|
||||
setPageSize,
|
||||
openModal,
|
||||
closeModal,
|
||||
selectPatient
|
||||
} = patientsSlice.actions
|
||||
|
||||
export default patientsSlice.reducer
|
||||
15
web-app/src/redux/store.js
Normal file
15
web-app/src/redux/store.js
Normal file
@ -0,0 +1,15 @@
|
||||
import { configureStore } from '@reduxjs/toolkit'
|
||||
import {patientsApi} from "./services/patientsApi.js";
|
||||
import patientsUIReducer from './slices/patientsSlice.js'
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
[patientsApi.reducerPath]: patientsApi.reducer,
|
||||
patientsUI: patientsUIReducer
|
||||
},
|
||||
middleware: (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware().concat(patientsApi.middleware)
|
||||
})
|
||||
|
||||
|
||||
export default store;
|
||||
@ -1,7 +1,7 @@
|
||||
import PropTypes from "prop-types";
|
||||
import {PatientPropType} from "./patientPropType.jsx";
|
||||
import {UserPropType} from "./userPropType.jsx";
|
||||
import {AppointmentTypePropType} from "./appointmentTypePropType.jsx";
|
||||
import {PatientPropType} from "./patientPropType.js";
|
||||
import {UserPropType} from "./userPropType.js";
|
||||
import {AppointmentTypePropType} from "./appointmentTypePropType.js";
|
||||
|
||||
export const AppointmentPropType = PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
@ -1,7 +1,7 @@
|
||||
import PropTypes from "prop-types";
|
||||
import {PatientPropType} from "./patientPropType.jsx";
|
||||
import {UserPropType} from "./userPropType.jsx";
|
||||
import {LensPropType} from "./lensPropType.jsx";
|
||||
import {PatientPropType} from "./patientPropType.js";
|
||||
import {UserPropType} from "./userPropType.js";
|
||||
import {LensPropType} from "./lensPropType.js";
|
||||
|
||||
export const LensIssuePropType = PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
@ -1,7 +1,7 @@
|
||||
import PropTypes from "prop-types";
|
||||
import {PatientPropType} from "./patientPropType.jsx";
|
||||
import {UserPropType} from "./userPropType.jsx";
|
||||
import {AppointmentTypePropType} from "./appointmentTypePropType.jsx";
|
||||
import {PatientPropType} from "./patientPropType.js";
|
||||
import {UserPropType} from "./userPropType.js";
|
||||
import {AppointmentTypePropType} from "./appointmentTypePropType.js";
|
||||
|
||||
export const ScheduledAppointmentPropType = PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
Loading…
x
Reference in New Issue
Block a user