сделал отмену запланированного приема
This commit is contained in:
parent
264ac5063a
commit
d101036445
@ -17,6 +17,7 @@ class ScheduledAppointmentsRepository:
|
|||||||
.options(joinedload(ScheduledAppointment.type))
|
.options(joinedload(ScheduledAppointment.type))
|
||||||
.options(joinedload(ScheduledAppointment.patient))
|
.options(joinedload(ScheduledAppointment.patient))
|
||||||
.options(joinedload(ScheduledAppointment.doctor))
|
.options(joinedload(ScheduledAppointment.doctor))
|
||||||
|
.filter_by(is_canceled=False)
|
||||||
.order_by(desc(ScheduledAppointment.scheduled_datetime))
|
.order_by(desc(ScheduledAppointment.scheduled_datetime))
|
||||||
)
|
)
|
||||||
result = await self.db.execute(stmt)
|
result = await self.db.execute(stmt)
|
||||||
@ -28,7 +29,7 @@ class ScheduledAppointmentsRepository:
|
|||||||
.options(joinedload(ScheduledAppointment.type))
|
.options(joinedload(ScheduledAppointment.type))
|
||||||
.options(joinedload(ScheduledAppointment.patient))
|
.options(joinedload(ScheduledAppointment.patient))
|
||||||
.options(joinedload(ScheduledAppointment.doctor))
|
.options(joinedload(ScheduledAppointment.doctor))
|
||||||
.filter_by(doctor_id=doctor_id)
|
.filter_by(doctor_id=doctor_id, is_canceled=False)
|
||||||
.order_by(desc(ScheduledAppointment.scheduled_datetime))
|
.order_by(desc(ScheduledAppointment.scheduled_datetime))
|
||||||
)
|
)
|
||||||
result = await self.db.execute(stmt)
|
result = await self.db.execute(stmt)
|
||||||
@ -40,7 +41,7 @@ class ScheduledAppointmentsRepository:
|
|||||||
.options(joinedload(ScheduledAppointment.type))
|
.options(joinedload(ScheduledAppointment.type))
|
||||||
.options(joinedload(ScheduledAppointment.patient))
|
.options(joinedload(ScheduledAppointment.patient))
|
||||||
.options(joinedload(ScheduledAppointment.doctor))
|
.options(joinedload(ScheduledAppointment.doctor))
|
||||||
.filter_by(patient_id=patient_id)
|
.filter_by(patient_id=patient_id, is_canceled=False)
|
||||||
.order_by(desc(ScheduledAppointment.scheduled_datetime))
|
.order_by(desc(ScheduledAppointment.scheduled_datetime))
|
||||||
)
|
)
|
||||||
result = await self.db.execute(stmt)
|
result = await self.db.execute(stmt)
|
||||||
@ -52,7 +53,7 @@ class ScheduledAppointmentsRepository:
|
|||||||
.options(joinedload(ScheduledAppointment.type))
|
.options(joinedload(ScheduledAppointment.type))
|
||||||
.options(joinedload(ScheduledAppointment.patient))
|
.options(joinedload(ScheduledAppointment.patient))
|
||||||
.options(joinedload(ScheduledAppointment.doctor))
|
.options(joinedload(ScheduledAppointment.doctor))
|
||||||
.filter_by(id=scheduled_appointment_id)
|
.filter_by(id=scheduled_appointment_id, is_canceled=False)
|
||||||
)
|
)
|
||||||
result = await self.db.execute(stmt)
|
result = await self.db.execute(stmt)
|
||||||
return result.scalars().first()
|
return result.scalars().first()
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
@ -68,6 +70,21 @@ async def create_appointment(
|
|||||||
return await appointment_service.create_scheduled_appointment(appointment, user.id)
|
return await appointment_service.create_scheduled_appointment(appointment, user.id)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post(
|
||||||
|
"/{appointment_id}/cancel/",
|
||||||
|
response_model=Optional[ScheduledAppointmentEntity],
|
||||||
|
summary="Cancel scheduled appointment",
|
||||||
|
description="Cancel scheduled appointment",
|
||||||
|
)
|
||||||
|
async def cancel_appointment(
|
||||||
|
appointment_id: int,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
appointment_service = ScheduledAppointmentsService(db)
|
||||||
|
return await appointment_service.cancel_scheduled_appointment(appointment_id, user.id)
|
||||||
|
|
||||||
|
|
||||||
@router.put(
|
@router.put(
|
||||||
"/{appointment_id}/",
|
"/{appointment_id}/",
|
||||||
response_model=ScheduledAppointmentEntity,
|
response_model=ScheduledAppointmentEntity,
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
"""0004_добавил поле отмены приема
|
||||||
|
|
||||||
|
Revision ID: 69fee5fc14c8
|
||||||
|
Revises: 1e122f5b8727
|
||||||
|
Create Date: 2025-06-01 19:38:02.360583
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = '69fee5fc14c8'
|
||||||
|
down_revision: Union[str, None] = '1e122f5b8727'
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('scheduled_appointments', sa.Column('is_canceled', sa.Boolean(), server_default='false', nullable=False))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('scheduled_appointments', 'is_canceled')
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -11,6 +11,7 @@ from app.domain.entities.user import UserEntity
|
|||||||
class ScheduledAppointmentEntity(BaseModel):
|
class ScheduledAppointmentEntity(BaseModel):
|
||||||
id: Optional[int] = None
|
id: Optional[int] = None
|
||||||
scheduled_datetime: datetime.datetime
|
scheduled_datetime: datetime.datetime
|
||||||
|
is_canceled: bool
|
||||||
|
|
||||||
patient_id: int
|
patient_id: int
|
||||||
doctor_id: Optional[int] = None
|
doctor_id: Optional[int] = None
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from sqlalchemy import Column, Integer, ForeignKey, DateTime
|
from sqlalchemy import Column, Integer, ForeignKey, DateTime, Boolean
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from sqlalchemy.sql import func
|
from sqlalchemy.sql import func
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ class ScheduledAppointment(BaseModel):
|
|||||||
__tablename__ = 'scheduled_appointments'
|
__tablename__ = 'scheduled_appointments'
|
||||||
|
|
||||||
scheduled_datetime = Column(DateTime, nullable=False, server_default=func.now())
|
scheduled_datetime = Column(DateTime, nullable=False, server_default=func.now())
|
||||||
|
is_canceled = Column(Boolean, nullable=False, default=False, server_default='false')
|
||||||
|
|
||||||
patient_id = Column(Integer, ForeignKey('patients.id'), nullable=False)
|
patient_id = Column(Integer, ForeignKey('patients.id'), nullable=False)
|
||||||
doctor_id = Column(Integer, ForeignKey('users.id'), nullable=False)
|
doctor_id = Column(Integer, ForeignKey('users.id'), nullable=False)
|
||||||
|
|||||||
@ -99,6 +99,36 @@ class ScheduledAppointmentsService:
|
|||||||
|
|
||||||
return self.model_to_entity(scheduled_appointment_model)
|
return self.model_to_entity(scheduled_appointment_model)
|
||||||
|
|
||||||
|
async def cancel_scheduled_appointment(self, scheduled_appointment_id: int, doctor_id):
|
||||||
|
scheduled_appointment_model = await self.scheduled_appointment_repository.get_by_id(scheduled_appointment_id)
|
||||||
|
|
||||||
|
if not scheduled_appointment_model:
|
||||||
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Scheduled appointment not found")
|
||||||
|
|
||||||
|
if scheduled_appointment_model.is_canceled:
|
||||||
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Scheduled appointment already cancelled")
|
||||||
|
|
||||||
|
doctor = await self.users_repository.get_by_id(doctor_id)
|
||||||
|
|
||||||
|
if not doctor:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail='The doctor/user with this ID was not found',
|
||||||
|
)
|
||||||
|
|
||||||
|
if scheduled_appointment_model.doctor_id != doctor_id and doctor.role.title != 'Администратор':
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
detail='Permission denied',
|
||||||
|
)
|
||||||
|
|
||||||
|
scheduled_appointment_model.is_canceled = True
|
||||||
|
|
||||||
|
await self.scheduled_appointment_repository.update(scheduled_appointment_model)
|
||||||
|
|
||||||
|
return self.model_to_entity(scheduled_appointment_model)
|
||||||
|
|
||||||
async def update_scheduled_appointment(
|
async def update_scheduled_appointment(
|
||||||
self,
|
self,
|
||||||
scheduled_appointment_id: int,
|
scheduled_appointment_id: int,
|
||||||
@ -137,6 +167,7 @@ class ScheduledAppointmentsService:
|
|||||||
scheduled_appointment_model.patient_id = scheduled_appointment.patient_id
|
scheduled_appointment_model.patient_id = scheduled_appointment.patient_id
|
||||||
scheduled_appointment_model.doctor_id = scheduled_appointment.doctor_id
|
scheduled_appointment_model.doctor_id = scheduled_appointment.doctor_id
|
||||||
scheduled_appointment_model.type_id = scheduled_appointment.type_id
|
scheduled_appointment_model.type_id = scheduled_appointment.type_id
|
||||||
|
scheduled_appointment_model.is_canceled = scheduled_appointment.is_canceled
|
||||||
|
|
||||||
await self.scheduled_appointment_repository.update(scheduled_appointment_model)
|
await self.scheduled_appointment_repository.update(scheduled_appointment_model)
|
||||||
|
|
||||||
@ -149,6 +180,7 @@ class ScheduledAppointmentsService:
|
|||||||
patient_id=scheduled_appointment.patient_id,
|
patient_id=scheduled_appointment.patient_id,
|
||||||
doctor_id=scheduled_appointment.doctor_id,
|
doctor_id=scheduled_appointment.doctor_id,
|
||||||
type_id=scheduled_appointment.type_id,
|
type_id=scheduled_appointment.type_id,
|
||||||
|
is_canceled=scheduled_appointment.is_canceled,
|
||||||
)
|
)
|
||||||
|
|
||||||
if scheduled_appointment.id:
|
if scheduled_appointment.id:
|
||||||
@ -164,6 +196,7 @@ class ScheduledAppointmentsService:
|
|||||||
patient_id=scheduled_appointment.patient_id,
|
patient_id=scheduled_appointment.patient_id,
|
||||||
doctor_id=scheduled_appointment.doctor_id,
|
doctor_id=scheduled_appointment.doctor_id,
|
||||||
type_id=scheduled_appointment.type_id,
|
type_id=scheduled_appointment.type_id,
|
||||||
|
is_canceled=scheduled_appointment.is_canceled,
|
||||||
)
|
)
|
||||||
|
|
||||||
if scheduled_appointment.patient is not None:
|
if scheduled_appointment.patient is not None:
|
||||||
|
|||||||
@ -33,6 +33,13 @@ export const scheduledAppointmentsApi = createApi({
|
|||||||
}),
|
}),
|
||||||
invalidatesTags: ['ScheduledAppointment'],
|
invalidatesTags: ['ScheduledAppointment'],
|
||||||
}),
|
}),
|
||||||
|
cancelScheduledAppointment: builder.mutation({
|
||||||
|
query: (id) => ({
|
||||||
|
url: `/scheduled_appointments/${id}/cancel/`,
|
||||||
|
method: 'POST',
|
||||||
|
}),
|
||||||
|
invalidatesTags: ['ScheduledAppointment'],
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -40,4 +47,5 @@ export const {
|
|||||||
useGetScheduledAppointmentsQuery,
|
useGetScheduledAppointmentsQuery,
|
||||||
useCreateScheduledAppointmentMutation,
|
useCreateScheduledAppointmentMutation,
|
||||||
useUpdateScheduledAppointmentMutation,
|
useUpdateScheduledAppointmentMutation,
|
||||||
|
useCancelScheduledAppointmentMutation,
|
||||||
} = scheduledAppointmentsApi;
|
} = scheduledAppointmentsApi;
|
||||||
@ -15,10 +15,10 @@ const AppRouter = () => (
|
|||||||
|
|
||||||
<Route element={<PrivateRoute/>}>
|
<Route element={<PrivateRoute/>}>
|
||||||
<Route element={<MainLayout/>}>
|
<Route element={<MainLayout/>}>
|
||||||
<Route path={"/Patients"} element={<PatientsPage/>}/>
|
<Route path={"/patients"} element={<PatientsPage/>}/>
|
||||||
<Route path={"/Lenses"} element={<LensesSetsPage/>}/>
|
<Route path={"/lenses"} element={<LensesSetsPage/>}/>
|
||||||
<Route path={"/issues"} element={<IssuesPage/>}/>
|
<Route path={"/issues"} element={<IssuesPage/>}/>
|
||||||
<Route path={"/Appointments"} element={<AppointmentsPage/>}/>
|
<Route path={"/appointments"} element={<AppointmentsPage/>}/>
|
||||||
<Route path={"/"} element={<HomePage/>}/>
|
<Route path={"/"} element={<HomePage/>}/>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const MainLayout = () => {
|
|||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
getItem("Главная", "/", <HomeOutlined/>),
|
getItem("Главная", "/", <HomeOutlined/>),
|
||||||
getItem("Приёмы", "/Appointments", <CalendarOutlined/>),
|
getItem("Приёмы", "/appointments", <CalendarOutlined/>),
|
||||||
getItem("Выдачи линз", "/issues", <DatabaseOutlined/>),
|
getItem("Выдачи линз", "/issues", <DatabaseOutlined/>),
|
||||||
getItem("Линзы и наборы", "/Lenses", <FolderViewOutlined/>),
|
getItem("Линзы и наборы", "/Lenses", <FolderViewOutlined/>),
|
||||||
getItem("Пациенты", "/Patients", <TeamOutlined/>),
|
getItem("Пациенты", "/Patients", <TeamOutlined/>),
|
||||||
|
|||||||
@ -14,6 +14,8 @@ import {closeModal, openModal} from "../../../Redux/Slices/appointmentsSlice.js"
|
|||||||
import AppointmentViewModal
|
import AppointmentViewModal
|
||||||
from "./Components/AppointmentViewModal/AppointmentViewModal.jsx";
|
from "./Components/AppointmentViewModal/AppointmentViewModal.jsx";
|
||||||
import ScheduledAppointmentFormModal from "./Components/ScheduledAppintmentFormModal/ScheduledAppointmentFormModal.jsx";
|
import ScheduledAppointmentFormModal from "./Components/ScheduledAppintmentFormModal/ScheduledAppointmentFormModal.jsx";
|
||||||
|
import ScheduledAppointmentsViewModal
|
||||||
|
from "./Components/ScheduledAppointmentsViewModal/ScheduledAppointmentsViewModal.jsx";
|
||||||
|
|
||||||
const AppointmentsPage = () => {
|
const AppointmentsPage = () => {
|
||||||
const appointmentsData = useAppointments();
|
const appointmentsData = useAppointments();
|
||||||
@ -84,7 +86,6 @@ const AppointmentsPage = () => {
|
|||||||
{appointmentsPageUI.upcomingEvents.map(app => (
|
{appointmentsPageUI.upcomingEvents.map(app => (
|
||||||
<li key={app.id}>
|
<li key={app.id}>
|
||||||
{dayjs(app.appointment_datetime || app.scheduled_datetime)
|
{dayjs(app.appointment_datetime || app.scheduled_datetime)
|
||||||
.tz('Europe/Moscow')
|
|
||||||
.format('DD.MM.YYYY HH:mm')} -
|
.format('DD.MM.YYYY HH:mm')} -
|
||||||
{app.appointment_datetime ? 'Прием' : 'Запланировано'}
|
{app.appointment_datetime ? 'Прием' : 'Запланировано'}
|
||||||
</li>
|
</li>
|
||||||
@ -140,6 +141,7 @@ const AppointmentsPage = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<ScheduledAppointmentFormModal/>
|
<ScheduledAppointmentFormModal/>
|
||||||
|
<ScheduledAppointmentsViewModal/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -38,15 +38,15 @@ const useAppointmentCalendarUI = (appointments, scheduledAppointments) => {
|
|||||||
const calendarContainerStyle = {padding: 20};
|
const calendarContainerStyle = {padding: 20};
|
||||||
|
|
||||||
const onSelect = (date) => {
|
const onSelect = (date) => {
|
||||||
const selectedDateStr = date.tz('Europe/Moscow').format('YYYY-MM-DD');
|
const selectedDateStr = date.format('YYYY-MM-DD');
|
||||||
dispatch(setSelectedDate(selectedDateStr));
|
dispatch(setSelectedDate(selectedDateStr));
|
||||||
|
|
||||||
const appointmentsForDate = appointments.filter(app =>
|
const appointmentsForDate = appointments.filter(app =>
|
||||||
dayjs(app.appointment_datetime).tz('Europe/Moscow').format('YYYY-MM-DD') === selectedDateStr
|
dayjs(app.appointment_datetime).format('YYYY-MM-DD') === selectedDateStr
|
||||||
);
|
);
|
||||||
|
|
||||||
const scheduledForDate = scheduledAppointments.filter(app =>
|
const scheduledForDate = scheduledAppointments.filter(app =>
|
||||||
dayjs(app.scheduled_datetime).tz('Europe/Moscow').format('YYYY-MM-DD') === selectedDateStr
|
dayjs(app.scheduled_datetime).format('YYYY-MM-DD') === selectedDateStr
|
||||||
);
|
);
|
||||||
|
|
||||||
dispatch(setSelectedAppointments([...appointmentsForDate, ...scheduledForDate]));
|
dispatch(setSelectedAppointments([...appointmentsForDate, ...scheduledForDate]));
|
||||||
|
|||||||
@ -0,0 +1,70 @@
|
|||||||
|
import {Button, Modal, Popconfirm, Row, Typography} from "antd";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import useScheduledAppointmentsViewModal from "./useScheduledAppointmentsViewModal.js";
|
||||||
|
import useScheduledAppointmentsViewModalUI from "./useScheduledAppointmentsViewModalUI.js";
|
||||||
|
|
||||||
|
const ScheduledAppointmentsViewModal = () => {
|
||||||
|
const scheduledAppointmentsViewModalData = useScheduledAppointmentsViewModal();
|
||||||
|
const scheduledAppointmentsViewModalUI = useScheduledAppointmentsViewModalUI(scheduledAppointmentsViewModalData.cancelAppointment);
|
||||||
|
|
||||||
|
if (!scheduledAppointmentsViewModalUI.selectedScheduledAppointment) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title="Просмотр запланированного приема"
|
||||||
|
open={true}
|
||||||
|
onCancel={scheduledAppointmentsViewModalUI.onCancel}
|
||||||
|
footer={null}
|
||||||
|
width={scheduledAppointmentsViewModalUI.modalWidth}
|
||||||
|
>
|
||||||
|
<div style={scheduledAppointmentsViewModalUI.blockStyle}>
|
||||||
|
<Typography.Title level={4}>Информация о приеме</Typography.Title>
|
||||||
|
<p>
|
||||||
|
<b>Пациент:</b>{" "}
|
||||||
|
{scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient ? `${scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient.last_name} ${scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient.first_name}` : "Не указан"}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Дата рождения:</b>{" "}
|
||||||
|
{scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient ? scheduledAppointmentsViewModalUI.getDateString(scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient.birthday) : "Не указан"}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Email:</b> {scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient?.email || "Не указан"}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Телефон:</b> {scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient?.phone || "Не указан"}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Тип
|
||||||
|
приема:</b> {scheduledAppointmentsViewModalUI.selectedScheduledAppointment.type?.title || "Не указан"}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Время приема:</b>{" "}
|
||||||
|
{scheduledAppointmentsViewModalUI.selectedScheduledAppointment.scheduled_datetime
|
||||||
|
? dayjs(scheduledAppointmentsViewModalUI.selectedScheduledAppointment.scheduled_datetime).format("DD.MM.YYYY HH:mm")
|
||||||
|
: "Не указано"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Row justify="end" style={{...scheduledAppointmentsViewModalUI.footerRowStyle, gap: 8}}>
|
||||||
|
<Button style={scheduledAppointmentsViewModalUI.footerButtonStyle}
|
||||||
|
onClick={scheduledAppointmentsViewModalUI.onCancel}>
|
||||||
|
Закрыть
|
||||||
|
</Button>
|
||||||
|
<Popconfirm
|
||||||
|
title="Вы уверены, что хотите отменить прием?"
|
||||||
|
onConfirm={scheduledAppointmentsViewModalUI.cancelScheduledAppointment}
|
||||||
|
okText="Да, отменить"
|
||||||
|
cancelText="Отмена"
|
||||||
|
>
|
||||||
|
<Button type={"primary"} danger>
|
||||||
|
Отмена приема
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ScheduledAppointmentsViewModal;
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {useCancelScheduledAppointmentMutation} from "../../../../../Api/scheduledAppointmentsApi.js";
|
||||||
|
|
||||||
|
|
||||||
|
const useScheduledAppointmentsViewModal = () => {
|
||||||
|
const [cancelAppointment] = useCancelScheduledAppointmentMutation();
|
||||||
|
|
||||||
|
return {cancelAppointment};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useScheduledAppointmentsViewModal;
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import {setSelectedScheduledAppointment} from "../../../../../Redux/Slices/appointmentsSlice.js";
|
||||||
|
import {notification} from "antd";
|
||||||
|
|
||||||
|
|
||||||
|
const useScheduledAppointmentsViewModalUI = (cancelAppointment) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
|
||||||
|
const {
|
||||||
|
selectedScheduledAppointment,
|
||||||
|
} = useSelector(state => state.appointmentsUI);
|
||||||
|
|
||||||
|
const blockStyle = {marginBottom: 16};
|
||||||
|
|
||||||
|
const getDateString = (date) => {
|
||||||
|
return date ? dayjs(date).format('DD.MM.YYYY') : 'Не указано';
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
dispatch(setSelectedScheduledAppointment(null));
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelScheduledAppointment = async () => {
|
||||||
|
try {
|
||||||
|
await cancelAppointment(selectedScheduledAppointment.id);
|
||||||
|
notification.success({
|
||||||
|
message: 'Прием отменен',
|
||||||
|
placement: 'topRight',
|
||||||
|
description: 'Прием успешно отменен.',
|
||||||
|
})
|
||||||
|
onCancel();
|
||||||
|
} catch (error) {
|
||||||
|
notification.error({
|
||||||
|
message: 'Ошибка',
|
||||||
|
description: error.data?.message || 'Не удалось отменить прием.',
|
||||||
|
placement: 'topRight',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedScheduledAppointment,
|
||||||
|
blockStyle,
|
||||||
|
getDateString,
|
||||||
|
onCancel,
|
||||||
|
cancelScheduledAppointment,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useScheduledAppointmentsViewModalUI;
|
||||||
@ -1,22 +0,0 @@
|
|||||||
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>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
AppointmentCellViewModal.propTypes = {
|
|
||||||
appointment: PropTypes.oneOfType([ScheduledAppointmentPropType, AppointmentPropType]).isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AppointmentCellViewModal;
|
|
||||||
Loading…
x
Reference in New Issue
Block a user