245 lines
8.2 KiB
JavaScript

import { useEffect, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { notification } from "antd";
import { Grid } from "antd";
import {
useGetAppointmentsQuery,
useGetUpcomingAppointmentsQuery,
} from "../../../Api/appointmentsApi.js";
import { useGetAllPatientsQuery } from "../../../Api/patientsApi.js";
import {
openModal,
openScheduledModal,
setHovered,
setSelectedAppointment,
setSelectedScheduledAppointment,
toggleSider
} from "../../../Redux/Slices/appointmentsSlice.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);
const { useBreakpoint } = Grid;
const useAppointments = () => {
const dispatch = useDispatch();
const { userData } = useSelector(state => state.auth);
const { collapsed, siderWidth, hovered, selectedAppointment } = useSelector(state => state.appointmentsUI);
const screens = useBreakpoint();
const [currentMonth, setCurrentMonth] = useState(dayjs().startOf('month'));
const startDate = currentMonth.startOf('month').format('YYYY-MM-DD');
const endDate = currentMonth.endOf('month').format('YYYY-MM-DD');
const handleMonthChange = (newMonth) => {
setCurrentMonth(dayjs(newMonth).startOf('month'));
};
const {
data: appointments = [],
isLoading: isLoadingAppointments,
isError: isErrorAppointments,
} = useGetAppointmentsQuery({ doctor_id: userData.id, start_date: startDate, end_date: endDate }, {
pollingInterval: 60000,
skip: !userData.id,
});
const {
data: scheduledAppointments = [],
isLoading: isLoadingScheduledAppointments,
isError: isErrorScheduledAppointments,
} = useGetScheduledAppointmentsQuery({ doctor_id: userData.id, start_date: startDate, end_date: endDate }, {
pollingInterval: 60000,
skip: !userData.id,
});
const {
data: patients = [],
isLoading: isLoadingPatients,
isError: isErrorPatients,
} = useGetAllPatientsQuery(undefined, {
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);
const splitterStyle = { flex: 1 };
const splitterContentPanelStyle = { padding: 16 };
const splitterSiderPanelStyle = { padding: "16px", borderLeft: "1px solid #ddd", overflowY: "auto" };
const siderTitleStyle = { marginBottom: 36 };
const siderButtonContainerStyle = {
position: "fixed",
right: 0,
top: "50%",
transform: "translateY(-50%)",
transition: "right 0.3s ease",
zIndex: 1000,
display: screens.xs ? "none" : "block",
};
const siderButtonStyle = {
width: hovered ? 250 : 50,
padding: hovered ? "0 20px" : "0",
overflow: "hidden",
textAlign: "left",
transition: "width 0.3s ease, padding 0.3s ease",
borderRadius: "4px 0 0 4px",
};
const badgeTextStyle = {
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
display: "inline-block",
width: "100%",
};
const handleToggleSider = () => dispatch(toggleSider());
const handleHoverSider = () => dispatch(setHovered(true));
const handleLeaveSider = () => dispatch(setHovered(false));
const handleSetSiderWidth = (width) => setLocalSiderWidth(width);
const handleCancelViewModal = () => {
if (selectedAppointment) {
dispatch(setSelectedAppointment(null));
} else {
dispatch(setSelectedScheduledAppointment(null));
}
};
const handleEventClick = (event) => {
if (event.appointment_datetime) {
dispatch(setSelectedAppointment(event));
} else {
dispatch(setSelectedScheduledAppointment(event));
}
};
const openCreateScheduledAppointmentModal = () => {
dispatch(openScheduledModal());
};
const openCreateAppointmentModal = () => dispatch(openModal());
const siderButtonText = useMemo(() =>
hovered ? (collapsed ? "Показать предстоящие события" : "Скрыть предстоящие события") : "",
[collapsed, hovered]
);
const showSplitterPanel = useMemo(() => !collapsed && !screens.xs, [collapsed, screens]);
const upcomingEvents = useMemo(() =>
[...upcomingAppointments, ...upcomingScheduledAppointments]
.sort((a, b) => dayjs(a.appointment_datetime || a.scheduled_datetime) - dayjs(b.appointment_datetime || b.scheduled_datetime))
.slice(0, 5),
[upcomingAppointments, upcomingScheduledAppointments]
);
useEffect(() => {
document.title = "Приемы";
}, []);
useEffect(() => {
if (isErrorAppointments) {
notification.error({
message: 'Ошибка',
description: 'Ошибка загрузки приемов.',
placement: 'topRight',
});
}
if (isErrorScheduledAppointments) {
notification.error({
message: 'Ошибка',
description: 'Ошибка загрузки запланированных приемов.',
placement: 'topRight',
});
}
if (isErrorPatients) {
notification.error({
message: 'Ошибка',
description: 'Ошибка загрузки пациентов.',
placement: 'topRight',
});
}
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 ||
isLoadingUpcomingAppointments || isLoadingUpcomingScheduledAppointments,
isError: isErrorAppointments || isErrorScheduledAppointments || isErrorPatients ||
isErrorUpcomingAppointments || isErrorUpcomingScheduledAppointments,
collapsed,
siderWidth: localSiderWidth,
hovered,
showSplitterPanel,
siderButtonText,
splitterStyle,
splitterContentPanelStyle,
splitterSiderPanelStyle,
siderTitleStyle,
siderButtonContainerStyle,
siderButtonStyle,
badgeTextStyle,
upcomingEvents,
selectedAppointment,
handleCancelViewModal,
handleToggleSider,
handleHoverSider,
handleLeaveSider,
handleSetSiderWidth,
openCreateScheduledAppointmentModal,
currentMonth,
handleMonthChange,
handleEventClick,
openCreateAppointmentModal,
};
};
export default useAppointments;