сделал удаление пациента и перенес дейсвтия редактирования в кнопки на карточке

This commit is contained in:
Андрей Дувакин 2025-02-13 20:08:58 +05:00
parent defe869e3e
commit 1c53632382
9 changed files with 103 additions and 25 deletions

View File

@ -37,3 +37,12 @@ async def update_patient(
):
patients_service = PatientsService(db)
return await patients_service.update_patient(patient_id, patient)
@router.delete("/patients/{patient_id}/", response_model=bool)
async def delete_patient(
patient_id: int,
db: AsyncSession = Depends(get_db),
user=Depends(get_current_user)
):
patient_service = PatientsService(db)
return await patient_service.delete_patient(patient_id)

View File

@ -2,6 +2,7 @@ import datetime
from typing import Optional
import jwt
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from app.application.users_repository import UsersRepository
@ -21,7 +22,7 @@ class AuthService:
"user_id": user.id
}
return None
raise HTTPException(status_code=403, detail="Invalid login or password")
@staticmethod
def create_access_token(data: dict) -> str:

View File

@ -1,5 +1,6 @@
from typing import Optional
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from app.application.patients_repository import PatientsRepository
@ -81,4 +82,12 @@ class PatientsService:
correction=patient_model.correction,
)
return None
raise HTTPException(status_code=404, detail="Patient not found")
async def delete_patient(self, patient_id: int) -> Optional[bool]:
result = await self.patient_repository.delete(patient_id) is not None
if not result:
raise HTTPException(status_code=404, detail="Patient not found")
return result

View File

@ -11,7 +11,7 @@ const AddPatient = async (token, patient) => {
});
return response.data;
} catch (error) {
throw new Error(error.response.data.message);
throw new Error(error.message);
}
};

View File

@ -0,0 +1,19 @@
import axios from "axios";
import CONFIG from "../../core/Config.jsx";
const DeletePatient = async (token, patient_id) => {
try {
const response = await axios.delete(`${CONFIG.BASE_URL}/patients/${patient_id}/`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.data;
} catch (error) {
throw new Error(error.message);
}
}
export default DeletePatient;

View File

@ -1,6 +1,7 @@
import axios from "axios";
import CONFIG from "../../core/Config.jsx";
const getAllPatients = async (token) => {
if (!token) {

View File

@ -1,17 +1,43 @@
import { Card } from "antd";
import {Card, Modal} from "antd";
import PropTypes from "prop-types";
import {DeleteOutlined, EditOutlined} from "@ant-design/icons";
const PatientListCard = ({ patient }) => {
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
hoverable
type="inner"
title={`${patient.last_name} ${patient.first_name}`}
style={{ marginBottom: 16, borderRadius: 12 }}
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>
<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>
@ -20,6 +46,7 @@ const PatientListCard = ({ patient }) => {
PatientListCard.propTypes = {
patient: PropTypes.shape({
id: PropTypes.number.isRequired,
last_name: PropTypes.string.isRequired,
first_name: PropTypes.string.isRequired,
patronymic: PropTypes.string,
@ -30,6 +57,8 @@ PatientListCard.propTypes = {
diagnosis: PropTypes.string,
correction: PropTypes.string,
}).isRequired,
handleEditPatient: PropTypes.func.isRequired,
handleDeletePatient: PropTypes.func.isRequired,
};
export default PatientListCard;

View File

@ -26,9 +26,9 @@ const MainLayout = () => {
const menuItems = [
getItem("Главная", "/", <HomeOutlined/>),
getItem("Приёмы", "/appointments", <CalendarOutlined/>),
getItem("Выдачи линз", "/dispensing", <DatabaseOutlined/>),
getItem("Линзы", "/lenses", <FolderViewOutlined/>),
getItem("Пациенты", "/patients", <TeamOutlined/>),
getItem("Выдачи линз", "/dispensing", <DatabaseOutlined/>),
getItem("Рассылки", "/mailing", <MessageOutlined/>),
{type: "divider"},
getItem("Мой профиль", "profile", <UserOutlined/>, [

View File

@ -1,12 +1,13 @@
import {useEffect, useState} from "react";
import {Input, Select, List, FloatButton, Row, Col, message, Spin} from "antd";
import {Input, Select, List, FloatButton, Row, Col, Spin} from "antd";
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 updatePatient from "../api/patients/UpdatePatient.jsx";
import addPatient from "../api/patients/AddPatient.jsx"; // Подключаем модальное окно
import addPatient from "../api/patients/AddPatient.jsx";
import deletePatient from "../api/patients/DeletePatient.jsx"; // Подключаем модальное окно
const {Option} = Select;
@ -65,11 +66,22 @@ const PatientsPage = () => {
setIsModalVisible(true);
};
const handleDeletePatient = async (patient_id) => {
if (!user || !user.token) return;
try {
await deletePatient(user.token, patient_id);
await fetchPatients();
} catch (err) {
setError(err.message);
}
};
const handleCancel = () => {
setIsModalVisible(false);
};
const handleSubmit = async (newPatient) => {
const handleModalPatientSubmit = async (newPatient) => {
if (selectedPatient) {
try {
@ -83,7 +95,6 @@ const PatientsPage = () => {
}
if (!selectedPatient) {
try {
@ -98,6 +109,7 @@ const PatientsPage = () => {
}
setIsModalVisible(false);
await fetchPatients();
};
return (<div style={{padding: 20}}>
@ -127,22 +139,20 @@ const PatientsPage = () => {
<List
grid={{gutter: 16, column: 1}}
dataSource={filteredPatients}
renderItem={(patient) => (<List.Item
onClick={() => {
handleEditPatient(patient);
}}
>
<PatientListCard patient={patient}/>
</List.Item>)}
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);
},
}}
/>
)}
@ -157,7 +167,7 @@ const PatientsPage = () => {
<PatientModal
visible={isModalVisible}
onCancel={handleCancel}
onSubmit={handleSubmit}
onSubmit={handleModalPatientSubmit}
patient={selectedPatient}
/>
</div>);