245 lines
8.2 KiB
JavaScript
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; |