feat: Добавлена поддержка предстоящих приемов
This commit is contained in:
parent
3a22fd05be
commit
c609c6471d
@ -1,5 +1,5 @@
|
||||
from typing import Sequence, Optional
|
||||
from sqlalchemy import select, desc
|
||||
from sqlalchemy import select, desc, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import joinedload
|
||||
from datetime import date
|
||||
@ -27,7 +27,7 @@ class AppointmentsRepository:
|
||||
return result.scalars().all()
|
||||
|
||||
async def get_by_doctor_id(self, doctor_id: int, start_date: date | None = None, end_date: date | None = None) -> \
|
||||
Sequence[Appointment]:
|
||||
Sequence[Appointment]:
|
||||
stmt = (
|
||||
select(Appointment)
|
||||
.options(joinedload(Appointment.type))
|
||||
@ -43,8 +43,22 @@ class AppointmentsRepository:
|
||||
result = await self.db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
async def get_upcoming_by_doctor_id(self, doctor_id: int) -> Sequence[Appointment]:
|
||||
stmt = (
|
||||
select(Appointment)
|
||||
.options(joinedload(Appointment.type))
|
||||
.options(joinedload(Appointment.patient))
|
||||
.options(joinedload(Appointment.doctor))
|
||||
.filter_by(doctor_id=doctor_id)
|
||||
.filter(Appointment.appointment_datetime >= func.now())
|
||||
.order_by(Appointment.appointment_datetime)
|
||||
.limit(5)
|
||||
)
|
||||
result = await self.db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
async def get_by_patient_id(self, patient_id: int, start_date: date | None = None, end_date: date | None = None) -> \
|
||||
Sequence[Appointment]:
|
||||
Sequence[Appointment]:
|
||||
stmt = (
|
||||
select(Appointment)
|
||||
.options(joinedload(Appointment.type))
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
from typing import Sequence
|
||||
from sqlalchemy import select, desc
|
||||
from sqlalchemy import select, desc, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import joinedload
|
||||
from datetime import date
|
||||
@ -29,7 +29,7 @@ class ScheduledAppointmentsRepository:
|
||||
return result.scalars().all()
|
||||
|
||||
async def get_by_doctor_id(self, doctor_id: int, start_date: date | None = None, end_date: date | None = None) -> \
|
||||
Sequence[ScheduledAppointment]:
|
||||
Sequence[ScheduledAppointment]:
|
||||
stmt = (
|
||||
select(ScheduledAppointment)
|
||||
.options(joinedload(ScheduledAppointment.type))
|
||||
@ -45,8 +45,22 @@ class ScheduledAppointmentsRepository:
|
||||
result = await self.db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
async def get_upcoming_by_doctor_id(self, doctor_id: int) -> Sequence[ScheduledAppointment]:
|
||||
stmt = (
|
||||
select(ScheduledAppointment)
|
||||
.options(joinedload(ScheduledAppointment.type))
|
||||
.options(joinedload(ScheduledAppointment.patient))
|
||||
.options(joinedload(ScheduledAppointment.doctor))
|
||||
.filter_by(doctor_id=doctor_id, is_canceled=False)
|
||||
.filter(ScheduledAppointment.scheduled_datetime >= func.now())
|
||||
.order_by(ScheduledAppointment.scheduled_datetime)
|
||||
.limit(5)
|
||||
)
|
||||
result = await self.db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
async def get_by_patient_id(self, patient_id: int, start_date: date | None = None, end_date: date | None = None) -> \
|
||||
Sequence[ScheduledAppointment]:
|
||||
Sequence[ScheduledAppointment]:
|
||||
stmt = (
|
||||
select(ScheduledAppointment)
|
||||
.options(joinedload(ScheduledAppointment.type))
|
||||
|
||||
@ -43,6 +43,21 @@ async def get_all_appointments_by_doctor_id(
|
||||
return await appointments_service.get_appointments_by_doctor_id(doctor_id, start_date=start_date, end_date=end_date)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/doctor/{doctor_id}/upcoming/",
|
||||
response_model=list[AppointmentEntity],
|
||||
summary="Get upcoming appointments for doctor",
|
||||
description="Returns the next 5 upcoming appointments for doctor",
|
||||
)
|
||||
async def get_upcoming_appointments_by_doctor_id(
|
||||
doctor_id: int,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
user=Depends(get_current_user),
|
||||
):
|
||||
appointments_service = AppointmentsService(db)
|
||||
return await appointments_service.get_upcoming_appointments_by_doctor_id(doctor_id)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/patient/{patient_id}/",
|
||||
response_model=list[AppointmentEntity],
|
||||
|
||||
@ -45,6 +45,21 @@ async def get_all_scheduled_appointments_by_doctor_id(
|
||||
end_date=end_date)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/doctor/{doctor_id}/upcoming/",
|
||||
response_model=list[ScheduledAppointmentEntity],
|
||||
summary="Get upcoming scheduled appointments for doctor",
|
||||
description="Returns the next 5 upcoming scheduled appointments for doctor",
|
||||
)
|
||||
async def get_upcoming_scheduled_appointments_by_doctor_id(
|
||||
doctor_id: int,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
user=Depends(get_current_user),
|
||||
):
|
||||
appointments_service = ScheduledAppointmentsService(db)
|
||||
return await appointments_service.get_upcoming_scheduled_appointments_by_doctor_id(doctor_id)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/patient/{patient_id}/",
|
||||
response_model=ScheduledAppointmentEntity,
|
||||
|
||||
@ -39,6 +39,16 @@ class AppointmentsService:
|
||||
end_date=end_date)
|
||||
return [self.model_to_entity(appointment) for appointment in appointments]
|
||||
|
||||
async def get_upcoming_appointments_by_doctor_id(self, doctor_id: int) -> Optional[list[AppointmentEntity]]:
|
||||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||||
if not doctor:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail='Доктор с таким ID не найден',
|
||||
)
|
||||
appointments = await self.appointments_repository.get_upcoming_by_doctor_id(doctor_id)
|
||||
return [self.model_to_entity(appointment) for appointment in appointments]
|
||||
|
||||
async def get_appointments_by_patient_id(self, patient_id: int, start_date: date | None = None,
|
||||
end_date: date | None = None) -> Optional[list[AppointmentEntity]]:
|
||||
patient = await self.patients_repository.get_by_id(patient_id)
|
||||
|
||||
@ -39,6 +39,17 @@ class ScheduledAppointmentsService:
|
||||
end_date=end_date)
|
||||
return [self.model_to_entity(scheduled_appointment) for scheduled_appointment in scheduled_appointments]
|
||||
|
||||
async def get_upcoming_scheduled_appointments_by_doctor_id(self, doctor_id: int) -> Optional[
|
||||
list[ScheduledAppointmentEntity]]:
|
||||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||||
if not doctor:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail='Доктор с таким ID не найден',
|
||||
)
|
||||
scheduled_appointments = await self.scheduled_appointment_repository.get_upcoming_by_doctor_id(doctor_id)
|
||||
return [self.model_to_entity(scheduled_appointment) for scheduled_appointment in scheduled_appointments]
|
||||
|
||||
async def get_scheduled_appointments_by_patient_id(self, patient_id: int, start_date: date | None = None,
|
||||
end_date: date | None = None) -> Optional[
|
||||
list[ScheduledAppointmentEntity]]:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createApi } from "@reduxjs/toolkit/query/react";
|
||||
import { baseQueryWithAuth } from "./baseQuery.js";
|
||||
import {createApi} from "@reduxjs/toolkit/query/react";
|
||||
import {baseQueryWithAuth} from "./baseQuery.js";
|
||||
|
||||
export const appointmentsApi = createApi({
|
||||
reducerPath: 'appointmentsApi',
|
||||
@ -7,13 +7,17 @@ export const appointmentsApi = createApi({
|
||||
tagTypes: ['Appointment'],
|
||||
endpoints: (builder) => ({
|
||||
getAppointments: builder.query({
|
||||
query: ({ doctor_id, start_date, end_date }) => ({
|
||||
query: ({doctor_id, start_date, end_date}) => ({
|
||||
url: `/appointments/doctor/${doctor_id}/`,
|
||||
params: { start_date, end_date },
|
||||
params: {start_date, end_date},
|
||||
}),
|
||||
providesTags: ['Appointment'],
|
||||
refetchOnMountOrArgChange: 5,
|
||||
}),
|
||||
getUpcomingAppointments: builder.query({
|
||||
query: (doctor_id) => `/appointments/doctor/${doctor_id}/upcoming/`,
|
||||
providesTags: ['Appointment'],
|
||||
}),
|
||||
getByPatientId: builder.query({
|
||||
query: (id) => `/appointments/patient/${id}/`,
|
||||
providesTags: ['Appointment'],
|
||||
@ -28,7 +32,7 @@ export const appointmentsApi = createApi({
|
||||
invalidatesTags: ['Appointment'],
|
||||
}),
|
||||
updateAppointment: builder.mutation({
|
||||
query: ({ id, data }) => ({
|
||||
query: ({id, data}) => ({
|
||||
url: `/appointments/${id}/`,
|
||||
method: 'PUT',
|
||||
body: data,
|
||||
@ -40,6 +44,7 @@ export const appointmentsApi = createApi({
|
||||
|
||||
export const {
|
||||
useGetAppointmentsQuery,
|
||||
useGetUpcomingAppointmentsQuery,
|
||||
useGetByPatientIdQuery,
|
||||
useCreateAppointmentMutation,
|
||||
useUpdateAppointmentMutation,
|
||||
|
||||
@ -13,6 +13,10 @@ export const scheduledAppointmentsApi = createApi({
|
||||
}),
|
||||
providesTags: ['ScheduledAppointment'],
|
||||
}),
|
||||
getUpcomingScheduledAppointments: builder.query({
|
||||
query: (doctor_id) => `/scheduled_appointments/doctor/${doctor_id}/upcoming/`,
|
||||
providesTags: ['ScheduledAppointment'],
|
||||
}),
|
||||
createScheduledAppointment: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: '/scheduled_appointments/',
|
||||
@ -41,6 +45,7 @@ export const scheduledAppointmentsApi = createApi({
|
||||
|
||||
export const {
|
||||
useGetScheduledAppointmentsQuery,
|
||||
useGetUpcomingScheduledAppointmentsQuery,
|
||||
useCreateScheduledAppointmentMutation,
|
||||
useUpdateScheduledAppointmentMutation,
|
||||
useCancelScheduledAppointmentMutation,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Badge, Button, FloatButton, List, Result, Row, Space, Tag, Typography} from "antd";
|
||||
import {Splitter} from "antd";
|
||||
import { Badge, Button, FloatButton, List, Result, Row, Space, Tag, Typography } from "antd";
|
||||
import { Splitter } from "antd";
|
||||
import {
|
||||
CalendarOutlined,
|
||||
MenuFoldOutlined,
|
||||
@ -13,14 +13,15 @@ import dayjs from 'dayjs';
|
||||
import LoadingIndicator from "../../Widgets/LoadingIndicator/LoadingIndicator.jsx";
|
||||
import AppointmentFormModal from "../../Dummies/AppointmentFormModal/AppointmentFormModal.jsx";
|
||||
import AppointmentViewModal from "../../Dummies/AppointmentViewModal/AppointmentViewModal.jsx";
|
||||
import ScheduledAppointmentFormModal
|
||||
from "../../Dummies/ScheduledAppintmentFormModal/ScheduledAppointmentFormModal.jsx";
|
||||
import ScheduledAppointmentsViewModal
|
||||
from "../../Widgets/ScheduledAppointmentsViewModal/ScheduledAppointmentsViewModal.jsx";
|
||||
import ScheduledAppointmentFormModal from "../../Dummies/ScheduledAppintmentFormModal/ScheduledAppointmentFormModal.jsx";
|
||||
import ScheduledAppointmentsViewModal from "../../Widgets/ScheduledAppointmentsViewModal/ScheduledAppointmentsViewModal.jsx";
|
||||
import AppointmentsListModal from "./Components/AppointmentsListModal/AppointmentsListModal.jsx";
|
||||
|
||||
const AppointmentsPage = () => {
|
||||
const {
|
||||
patients, // Добавляем
|
||||
appointments, // Добавляем
|
||||
scheduledAppointments, // Добавляем
|
||||
isLoading,
|
||||
isError,
|
||||
collapsed,
|
||||
@ -46,7 +47,6 @@ const AppointmentsPage = () => {
|
||||
openCreateAppointmentModal,
|
||||
} = useAppointments();
|
||||
|
||||
|
||||
if (isError) return (
|
||||
<Result
|
||||
status="error"
|
||||
@ -57,30 +57,20 @@ const AppointmentsPage = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography.Title level={1}><CalendarOutlined/> Приемы</Typography.Title>
|
||||
<Typography.Title level={1}><CalendarOutlined /> Приемы</Typography.Title>
|
||||
{isLoading ? (
|
||||
<LoadingIndicator/>
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<>
|
||||
<Row justify="end" style={{marginBottom: 10, marginRight: "2.4rem"}}>
|
||||
<Row justify="end" style={{ marginBottom: 10, marginRight: "2.4rem" }}>
|
||||
<Space direction={"vertical"}>
|
||||
<Tag color={"blue"} style={{width: "100%"}}>
|
||||
<Tag color={"blue"} style={{ width: "100%" }}>
|
||||
<Badge status={"processing"}
|
||||
text={
|
||||
<span style={badgeTextStyle}>
|
||||
Запланированный прием
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
text={<span style={badgeTextStyle}>Запланированный прием</span>} />
|
||||
</Tag>
|
||||
<Tag color={"green"} style={{width: "100%"}}>
|
||||
<Tag color={"green"} style={{ width: "100%" }}>
|
||||
<Badge status={"success"}
|
||||
text={
|
||||
<span style={badgeTextStyle}>
|
||||
Прошедший прием
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
text={<span style={badgeTextStyle}>Прошедший прием</span>} />
|
||||
</Tag>
|
||||
</Space>
|
||||
</Row>
|
||||
@ -100,9 +90,10 @@ const AppointmentsPage = () => {
|
||||
<AppointmentsCalendarTab
|
||||
currentMonth={currentMonth}
|
||||
onMonthChange={handleMonthChange}
|
||||
appointments={appointments} // Добавляем
|
||||
scheduledAppointments={scheduledAppointments} // Добавляем
|
||||
/>
|
||||
</Splitter.Panel>
|
||||
|
||||
{showSplitterPanel && (
|
||||
<Splitter.Panel
|
||||
style={splitterSiderPanelStyle}
|
||||
@ -118,8 +109,7 @@ const AppointmentsPage = () => {
|
||||
dataSource={upcomingEvents.sort((a, b) =>
|
||||
dayjs(a.appointment_datetime || a.scheduled_datetime).diff(
|
||||
dayjs(b.appointment_datetime || b.scheduled_datetime)
|
||||
)
|
||||
)}
|
||||
))}
|
||||
renderItem={(item) => (
|
||||
<List.Item
|
||||
onClick={() => handleEventClick(item)}
|
||||
@ -137,9 +127,9 @@ const AppointmentsPage = () => {
|
||||
<Space direction="vertical" size={2}>
|
||||
<Space>
|
||||
{item.appointment_datetime ? (
|
||||
<ClockCircleOutlined style={{color: "#52c41a"}}/>
|
||||
<ClockCircleOutlined style={{ color: "#52c41a" }} />
|
||||
) : (
|
||||
<CalendarOutlined style={{color: "#1890ff"}}/>
|
||||
<CalendarOutlined style={{ color: "#1890ff" }} />
|
||||
)}
|
||||
<Typography.Text strong>
|
||||
{dayjs(item.appointment_datetime || item.scheduled_datetime).format('DD.MM.YYYY HH:mm')}
|
||||
@ -173,7 +163,7 @@ const AppointmentsPage = () => {
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleToggleSider}
|
||||
icon={collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
|
||||
icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
|
||||
style={siderButtonStyle}
|
||||
>
|
||||
{siderButtonText}
|
||||
@ -183,30 +173,30 @@ const AppointmentsPage = () => {
|
||||
placement={"left"}
|
||||
trigger="hover"
|
||||
type="primary"
|
||||
icon={<PlusOutlined/>}
|
||||
icon={<PlusOutlined />}
|
||||
tooltip="Создать"
|
||||
>
|
||||
<FloatButton
|
||||
icon={<PlusOutlined/>}
|
||||
icon={<PlusOutlined />}
|
||||
onClick={openCreateAppointmentModal}
|
||||
tooltip="Прием"
|
||||
/>
|
||||
<FloatButton
|
||||
icon={<CalendarOutlined/>}
|
||||
icon={<CalendarOutlined />}
|
||||
onClick={openCreateScheduledAppointmentModal}
|
||||
tooltip="Запланированный прием"
|
||||
/>
|
||||
</FloatButton.Group>
|
||||
|
||||
<AppointmentFormModal/>
|
||||
<AppointmentViewModal/>
|
||||
<ScheduledAppointmentFormModal/>
|
||||
<ScheduledAppointmentsViewModal/>
|
||||
<AppointmentsListModal/>
|
||||
<AppointmentFormModal />
|
||||
<AppointmentViewModal />
|
||||
<ScheduledAppointmentFormModal />
|
||||
<ScheduledAppointmentsViewModal />
|
||||
<AppointmentsListModal />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppointmentsPage;
|
||||
export default AppointmentsPage;
|
||||
|
||||
@ -4,6 +4,7 @@ import { notification } from "antd";
|
||||
import { Grid } from "antd";
|
||||
import {
|
||||
useGetAppointmentsQuery,
|
||||
useGetUpcomingAppointmentsQuery,
|
||||
} from "../../../Api/appointmentsApi.js";
|
||||
import { useGetAllPatientsQuery } from "../../../Api/patientsApi.js";
|
||||
import {
|
||||
@ -14,8 +15,17 @@ import {
|
||||
setSelectedScheduledAppointment,
|
||||
toggleSider
|
||||
} from "../../../Redux/Slices/appointmentsSlice.js";
|
||||
import { useGetScheduledAppointmentsQuery } from "../../../Api/scheduledAppointmentsApi.js";
|
||||
import {
|
||||
useGetScheduledAppointmentsQuery,
|
||||
useGetUpcomingScheduledAppointmentsQuery,
|
||||
} from "../../../Api/scheduledAppointmentsApi.js";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import timezone from "dayjs/plugin/timezone";
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
dayjs.tz.setDefault("Europe/Moscow");
|
||||
|
||||
const { useBreakpoint } = Grid;
|
||||
|
||||
@ -25,13 +35,13 @@ const useAppointments = () => {
|
||||
const { collapsed, siderWidth, hovered, selectedAppointment } = useSelector(state => state.appointmentsUI);
|
||||
const screens = useBreakpoint();
|
||||
|
||||
const [currentMonth, setCurrentMonth] = useState(dayjs().startOf('month'));
|
||||
const [currentMonth, setCurrentMonth] = useState(dayjs().tz("Europe/Moscow").startOf('month'));
|
||||
|
||||
const startDate = currentMonth.startOf('month').format('YYYY-MM-DD');
|
||||
const endDate = currentMonth.endOf('month').format('YYYY-MM-DD');
|
||||
const startDate = currentMonth.startOf('month').tz("Europe/Moscow").format('YYYY-MM-DD');
|
||||
const endDate = currentMonth.endOf('month').tz("Europe/Moscow").format('YYYY-MM-DD');
|
||||
|
||||
const handleMonthChange = (newMonth) => {
|
||||
setCurrentMonth(dayjs(newMonth).startOf('month'));
|
||||
setCurrentMonth(dayjs(newMonth).tz("Europe/Moscow").startOf('month'));
|
||||
};
|
||||
|
||||
const {
|
||||
@ -39,7 +49,8 @@ const useAppointments = () => {
|
||||
isLoading: isLoadingAppointments,
|
||||
isError: isErrorAppointments,
|
||||
} = useGetAppointmentsQuery({ doctor_id: userData.id, start_date: startDate, end_date: endDate }, {
|
||||
pollingInterval: 20000,
|
||||
pollingInterval: 60000,
|
||||
skip: !userData.id,
|
||||
});
|
||||
|
||||
const {
|
||||
@ -47,7 +58,8 @@ const useAppointments = () => {
|
||||
isLoading: isLoadingScheduledAppointments,
|
||||
isError: isErrorScheduledAppointments,
|
||||
} = useGetScheduledAppointmentsQuery({ doctor_id: userData.id, start_date: startDate, end_date: endDate }, {
|
||||
pollingInterval: 20000,
|
||||
pollingInterval: 60000,
|
||||
skip: !userData.id,
|
||||
});
|
||||
|
||||
const {
|
||||
@ -55,7 +67,26 @@ const useAppointments = () => {
|
||||
isLoading: isLoadingPatients,
|
||||
isError: isErrorPatients,
|
||||
} = useGetAllPatientsQuery(undefined, {
|
||||
pollingInterval: 20000,
|
||||
pollingInterval: 60000,
|
||||
skip: !userData.id,
|
||||
});
|
||||
|
||||
const {
|
||||
data: upcomingAppointments = [],
|
||||
isLoading: isLoadingUpcomingAppointments,
|
||||
isError: isErrorUpcomingAppointments,
|
||||
} = useGetUpcomingAppointmentsQuery(userData.id, {
|
||||
pollingInterval: 60000,
|
||||
skip: !userData.id,
|
||||
});
|
||||
|
||||
const {
|
||||
data: upcomingScheduledAppointments = [],
|
||||
isLoading: isLoadingUpcomingScheduledAppointments,
|
||||
isError: isErrorUpcomingScheduledAppointments,
|
||||
} = useGetUpcomingScheduledAppointmentsQuery(userData.id, {
|
||||
pollingInterval: 60000,
|
||||
skip: !userData.id,
|
||||
});
|
||||
|
||||
const [localSiderWidth, setLocalSiderWidth] = useState(siderWidth);
|
||||
@ -123,11 +154,10 @@ const useAppointments = () => {
|
||||
const showSplitterPanel = useMemo(() => !collapsed && !screens.xs, [collapsed, screens]);
|
||||
|
||||
const upcomingEvents = useMemo(() =>
|
||||
[...appointments, ...scheduledAppointments]
|
||||
.filter(app => dayjs(app.appointment_datetime || app.scheduled_datetime).isAfter(dayjs()))
|
||||
.sort((a, b) => dayjs(a.appointment_datetime || a.scheduled_datetime) - dayjs(b.appointment_datetime || b.scheduled_datetime))
|
||||
[...upcomingAppointments, ...upcomingScheduledAppointments]
|
||||
.sort((a, b) => dayjs(a.appointment_datetime || a.scheduled_datetime).tz("Europe/Moscow") - dayjs(b.appointment_datetime || b.scheduled_datetime).tz("Europe/Moscow"))
|
||||
.slice(0, 5),
|
||||
[appointments, scheduledAppointments]
|
||||
[upcomingAppointments, upcomingScheduledAppointments]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -156,14 +186,36 @@ const useAppointments = () => {
|
||||
placement: 'topRight',
|
||||
});
|
||||
}
|
||||
}, [isErrorAppointments, isErrorScheduledAppointments, isErrorPatients]);
|
||||
if (isErrorUpcomingAppointments) {
|
||||
notification.error({
|
||||
message: 'Ошибка',
|
||||
description: 'Ошибка загрузки предстоящих приемов.',
|
||||
placement: 'topRight',
|
||||
});
|
||||
}
|
||||
if (isErrorUpcomingScheduledAppointments) {
|
||||
notification.error({
|
||||
message: 'Ошибка',
|
||||
description: 'Ошибка загрузки предстоящих запланированных приемов.',
|
||||
placement: 'topRight',
|
||||
});
|
||||
}
|
||||
}, [
|
||||
isErrorAppointments,
|
||||
isErrorScheduledAppointments,
|
||||
isErrorPatients,
|
||||
isErrorUpcomingAppointments,
|
||||
isErrorUpcomingScheduledAppointments
|
||||
]);
|
||||
|
||||
return {
|
||||
patients,
|
||||
appointments,
|
||||
scheduledAppointments,
|
||||
isLoading: isLoadingAppointments || isLoadingScheduledAppointments || isLoadingPatients,
|
||||
isError: isErrorAppointments || isErrorScheduledAppointments || isErrorPatients,
|
||||
isLoading: isLoadingAppointments || isLoadingScheduledAppointments || isLoadingPatients ||
|
||||
isLoadingUpcomingAppointments || isLoadingUpcomingScheduledAppointments,
|
||||
isError: isErrorAppointments || isErrorScheduledAppointments || isErrorPatients ||
|
||||
isErrorUpcomingAppointments || isErrorUpcomingScheduledAppointments,
|
||||
collapsed,
|
||||
siderWidth: localSiderWidth,
|
||||
hovered,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user