сделал просмотр информации о пациенте

This commit is contained in:
Андрей Дувакин 2025-02-18 10:54:20 +05:00
parent e87baafae9
commit 2f39baa8d3
8 changed files with 190 additions and 73 deletions

View File

@ -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";

View File

@ -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 (
<Card
type="inner"
title={`${patient.last_name} ${patient.first_name}`}
actions={[
<EditOutlined
onClick={() => {
handleEditPatient(patient);
}}
key={"editPatient"}
/>,
<DeleteOutlined
onClick={deletePatientConfirm}
key={"deletePatient"}
style={{color: "red"}}
/>
]}
>
<p><strong>📅 Дата рождения:</strong> {birthday.toLocaleString('ru-RU', {
month: 'long',
day: 'numeric',
year: 'numeric'
})}</p>
{patient.phone && <p><strong>📞 Телефон:</strong> {patient.phone}</p>}
{patient.email && <p><strong> Email:</strong> {patient.email}</p>}
</Card>
);
};
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;

View File

@ -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;

View File

@ -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 = [
<Tooltip title="Просмотр пациента" key={"viewPatient"}>
<EyeOutlined
onClick={handleViewPatient}
/>
</Tooltip>,
<Tooltip title="Редактирование пациента" key={"editPatient"}>
<EditOutlined
onClick={() => {
handleEditPatient(patient);
}}
/>
</Tooltip>,
<Tooltip title="Удаление пациента" key={"deletePatient"}>
<DeleteOutlined
onClick={deletePatientConfirm}
style={{color: "red"}}
/>
</Tooltip>,
];
return (
<>
<Card
type="inner"
title={`${patient.last_name} ${patient.first_name}`}
actions={actions}
>
<p><strong>📅 Дата рождения:</strong> {birthday.toLocaleString('ru-RU', {
month: 'long',
day: 'numeric',
year: 'numeric'
})}</p>
{patient.phone && <p><strong>📞 Телефон:</strong> {patient.phone}</p>}
{patient.email && <p><strong> Email:</strong> {patient.email}</p>}
</Card>
{showModalInfo && (
<PatientViewModal
visible={showModalInfo}
onCancel={() => 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;

View File

@ -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 (
<Modal
title="Просмотр пациента"
open={visible}
onCancel={onCancel}
footer={
<Button onClick={onCancel} type="primary">
Закрыть
</Button>
}
>
<Row gutter={24}>
<Col xs={24} md={12}>
<div style={{ marginBottom: 12 }}>
<Title level={5}>👤 ФИО</Title>
<Text>{`${patient.last_name} ${patient.first_name} ${patient.patronymic || ''}`}</Text>
</div>
<div style={{ marginBottom: 12 }}>
<Title level={5}>🎂 Дата рождения</Title>
<Text>
{new Date(patient.birthday).toLocaleDateString('ru-RU', {
day: 'numeric',
month: 'long',
year: 'numeric',
})}
</Text>
</div>
</Col>
<Col xs={24} md={12}>
<div style={{ marginBottom: 12 }}>
<Title level={5}>📞 Телефон</Title>
<Text>{patient.phone || 'Не указан'}</Text>
</div>
<div style={{ marginBottom: 12 }}>
<Title level={5}> Email</Title>
<Text>{patient.email || 'Не указан'}</Text>
</div>
<div style={{ marginBottom: 12 }}>
<Title level={5}>🏠 Адрес</Title>
<Text>{patient.address || 'Не указан'}</Text>
</div>
</Col>
</Row>
<Divider />
<div style={{ marginBottom: 12 }}>
<Title level={5}>🩺 Диагноз</Title>
<Text>{patient.diagnosis || 'Не указан'}</Text>
</div>
<div style={{ marginBottom: 12 }}>
<Title level={5}>👓 Коррекция</Title>
<Text>{patient.correction || 'Не указ'}</Text>
</div>
</Modal>
);
};
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;

View File

@ -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();

View File

@ -4,6 +4,7 @@
const LensPage = () => {
return (
<>
</>
)
}

View File

@ -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}
/>
<PatientModal
<PatientFormModal
visible={isModalVisible}
onCancel={handleCancel}
onSubmit={handleModalPatientSubmit}