diff --git a/web-app/src/AppRouter.jsx b/web-app/src/AppRouter.jsx index befba5f..213efa7 100644 --- a/web-app/src/AppRouter.jsx +++ b/web-app/src/AppRouter.jsx @@ -1,5 +1,5 @@ import {Routes, Route, Navigate} from "react-router-dom"; -import PrivateRoute from "./components/PrivateRoute.jsx"; +import PrivateRoute from "./components/patients/PrivateRoute.jsx"; import LoginPage from "./pages/LoginPage.jsx"; import MainLayout from "./layouts/MainLayout.jsx"; import PatientsPage from "./pages/PatientsPage.jsx"; diff --git a/web-app/src/components/PatientListCard.jsx b/web-app/src/components/PatientListCard.jsx deleted file mode 100644 index ff188b7..0000000 --- a/web-app/src/components/PatientListCard.jsx +++ /dev/null @@ -1,64 +0,0 @@ -import {Card, Modal} from "antd"; -import PropTypes from "prop-types"; -import {DeleteOutlined, EditOutlined} from "@ant-design/icons"; - -const PatientListCard = ({patient, handleEditPatient, handleDeletePatient}) => { - const birthday = new Date(patient.birthday) - - const deletePatientConfirm = () => { - Modal.confirm({ - title: "Удаление пациента", - content: `Вы уверены, что хотите удалить пациента ${patient.last_name} ${patient.first_name}?`, - okText: "Да, удалить", - cancelText: "Отмена", - onOk: () => handleDeletePatient(patient.id), - }); - }; - - return ( - { - handleEditPatient(patient); - }} - key={"editPatient"} - />, - - ]} - > -

📅 Дата рождения: {birthday.toLocaleString('ru-RU', { - month: 'long', - day: 'numeric', - year: 'numeric' - })}

- {patient.phone &&

📞 Телефон: {patient.phone}

} - {patient.email &&

✉️ Email: {patient.email}

} -
- ); -}; - -PatientListCard.propTypes = { - patient: PropTypes.shape({ - id: PropTypes.number.isRequired, - last_name: PropTypes.string.isRequired, - first_name: PropTypes.string.isRequired, - patronymic: PropTypes.string, - birthday: PropTypes.string.isRequired, - address: PropTypes.string, - email: PropTypes.string, - phone: PropTypes.string, - diagnosis: PropTypes.string, - correction: PropTypes.string, - }).isRequired, - handleEditPatient: PropTypes.func.isRequired, - handleDeletePatient: PropTypes.func.isRequired, -}; - -export default PatientListCard; diff --git a/web-app/src/components/PatientModal.jsx b/web-app/src/components/patients/PatientFormModal.jsx similarity index 97% rename from web-app/src/components/PatientModal.jsx rename to web-app/src/components/patients/PatientFormModal.jsx index 01cdcc4..11f00e3 100644 --- a/web-app/src/components/PatientModal.jsx +++ b/web-app/src/components/patients/PatientFormModal.jsx @@ -8,7 +8,7 @@ import dayjs from "dayjs"; const {TextArea} = Input; -const PatientModal = ({visible, onCancel, onSubmit, patient}) => { +const PatientFormModal = ({visible, onCancel, onSubmit, patient}) => { const [form] = Form.useForm(); useEffect(() => { @@ -128,7 +128,7 @@ const PatientModal = ({visible, onCancel, onSubmit, patient}) => { ); }; -PatientModal.propTypes = { +PatientFormModal.propTypes = { visible: PropTypes.bool.isRequired, onCancel: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired, @@ -145,4 +145,4 @@ PatientModal.propTypes = { }), }; -export default PatientModal; +export default PatientFormModal; diff --git a/web-app/src/components/patients/PatientListCard.jsx b/web-app/src/components/patients/PatientListCard.jsx new file mode 100644 index 0000000..c554af4 --- /dev/null +++ b/web-app/src/components/patients/PatientListCard.jsx @@ -0,0 +1,92 @@ +import {Card, Modal, Tooltip} from "antd"; +import PropTypes from "prop-types"; +import {DeleteOutlined, EditOutlined, EyeOutlined} from "@ant-design/icons"; +import {useState} from "react"; +import PatientViewModal from "./PatientViewModal.jsx"; + +const PatientListCard = ({patient, handleEditPatient, handleDeletePatient}) => { + const [showModalInfo, setShowModalInfo] = useState(false); + + const birthday = new Date(patient.birthday) + + const deletePatientConfirm = () => { + Modal.confirm({ + title: "Удаление пациента", + content: `Вы уверены, что хотите удалить пациента ${patient.last_name} ${patient.first_name}?`, + okText: "Да, удалить", + cancelText: "Отмена", + onOk: () => handleDeletePatient(patient.id), + }); + }; + + const handleViewPatient = () => { + setShowModalInfo(true); + }; + + const actions = [ + + + , + + + { + handleEditPatient(patient); + }} + /> + , + + + , + ]; + + return ( + <> + +

📅 Дата рождения: {birthday.toLocaleString('ru-RU', { + month: 'long', + day: 'numeric', + year: 'numeric' + })}

+ {patient.phone &&

📞 Телефон: {patient.phone}

} + {patient.email &&

✉️ Email: {patient.email}

} +
+ + {showModalInfo && ( + setShowModalInfo(false)} + patient={patient} + /> + )} + + ); +}; + +PatientListCard.propTypes = { + patient: PropTypes.shape({ + id: PropTypes.number.isRequired, + last_name: PropTypes.string.isRequired, + first_name: PropTypes.string.isRequired, + patronymic: PropTypes.string, + birthday: PropTypes.string.isRequired, + address: PropTypes.string, + email: PropTypes.string, + phone: PropTypes.string, + diagnosis: PropTypes.string, + correction: PropTypes.string, + }).isRequired, + handleEditPatient: PropTypes.func.isRequired, + handleDeletePatient: PropTypes.func.isRequired, +}; + +export default PatientListCard; diff --git a/web-app/src/components/patients/PatientViewModal.jsx b/web-app/src/components/patients/PatientViewModal.jsx new file mode 100644 index 0000000..328e007 --- /dev/null +++ b/web-app/src/components/patients/PatientViewModal.jsx @@ -0,0 +1,88 @@ +import {Button, Col, Modal, Row, Typography, Divider} from "antd"; +import PropTypes from "prop-types"; + +const { Text, Title } = Typography; + +const PatientViewModal = ({ visible, onCancel, patient }) => { + if (!patient) return null; + + return ( + + Закрыть + + } + > + + +
+ 👤 ФИО + {`${patient.last_name} ${patient.first_name} ${patient.patronymic || ''}`} +
+ +
+ 🎂 Дата рождения + + {new Date(patient.birthday).toLocaleDateString('ru-RU', { + day: 'numeric', + month: 'long', + year: 'numeric', + })} + +
+ + + +
+ 📞 Телефон + {patient.phone || 'Не указан'} +
+ +
+ ✉️ Email + {patient.email || 'Не указан'} +
+ +
+ 🏠 Адрес + {patient.address || 'Не указан'} +
+ +
+ + + +
+ 🩺 Диагноз + {patient.diagnosis || 'Не указан'} +
+ +
+ 👓 Коррекция + {patient.correction || 'Не указ'} +
+
+ ); +}; + +PatientViewModal.propTypes = { + visible: PropTypes.bool.isRequired, + onCancel: PropTypes.func.isRequired, + patient: PropTypes.shape({ + first_name: PropTypes.string, + last_name: PropTypes.string, + patronymic: PropTypes.string, + birthday: PropTypes.string, + address: PropTypes.string, + email: PropTypes.string, + phone: PropTypes.string, + diagnosis: PropTypes.string, + correction: PropTypes.string, + }), +}; + +export default PatientViewModal; diff --git a/web-app/src/components/PrivateRoute.jsx b/web-app/src/components/patients/PrivateRoute.jsx similarity index 83% rename from web-app/src/components/PrivateRoute.jsx rename to web-app/src/components/patients/PrivateRoute.jsx index e9553ad..792ad81 100644 --- a/web-app/src/components/PrivateRoute.jsx +++ b/web-app/src/components/patients/PrivateRoute.jsx @@ -1,5 +1,5 @@ import {Navigate, Outlet} from "react-router-dom"; -import {useAuth} from "../AuthContext.jsx"; +import {useAuth} from "../../AuthContext.jsx"; const PrivateRoute = () => { const {user} = useAuth(); diff --git a/web-app/src/pages/LensPage.jsx b/web-app/src/pages/LensPage.jsx index 5fb7c2b..90d539f 100644 --- a/web-app/src/pages/LensPage.jsx +++ b/web-app/src/pages/LensPage.jsx @@ -4,6 +4,7 @@ const LensPage = () => { return ( <> + ) } diff --git a/web-app/src/pages/PatientsPage.jsx b/web-app/src/pages/PatientsPage.jsx index ba88d05..941084b 100644 --- a/web-app/src/pages/PatientsPage.jsx +++ b/web-app/src/pages/PatientsPage.jsx @@ -3,8 +3,8 @@ import {Input, Select, List, FloatButton, Row, Col, Spin, notification} from "an import {LoadingOutlined, PlusOutlined} from "@ant-design/icons"; import {useAuth} from "../AuthContext.jsx"; import getAllPatients from "../api/patients/GetAllPatients.jsx"; -import PatientListCard from "../components/PatientListCard.jsx"; -import PatientModal from "../components/PatientModal.jsx"; +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"; @@ -39,7 +39,7 @@ const PatientsPage = () => { const cachedData = localStorage.getItem("patientsData"); const cacheTimestamp = localStorage.getItem("patientsTimestamp"); - if (cachedData && cacheTimestamp && (Date.now() - parseInt(cacheTimestamp)) < 5 * 60 * 1000) { + if (cachedData && cacheTimestamp && (Date.now() - parseInt(cacheTimestamp)) < 60 * 1000) { setPatients(JSON.parse(cachedData)); setLoading(false); return; @@ -221,7 +221,7 @@ const PatientsPage = () => { onClick={handleAddPatient} /> -