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;