diff --git a/api/app/controllers/appointments_router.py b/api/app/controllers/appointments_router.py index 8a88ae5..1fb9307 100644 --- a/api/app/controllers/appointments_router.py +++ b/api/app/controllers/appointments_router.py @@ -40,7 +40,7 @@ async def get_all_appointments_by_doctor_id( @router.get( "/patient/{patient_id}/", - response_model=AppointmentEntity, + response_model=list[AppointmentEntity], summary="Get all appointments for patient", description="Returns a list of appointments for patient", ) diff --git a/web-app/src/Api/appointmentsApi.js b/web-app/src/Api/appointmentsApi.js index 6a1c6ce..d9990c8 100644 --- a/web-app/src/Api/appointmentsApi.js +++ b/web-app/src/Api/appointmentsApi.js @@ -18,6 +18,11 @@ export const appointmentsApi = createApi({ providesTags: ['Appointment'], refetchOnMountOrArgChange: 5, }), + getByPatientId: builder.query({ + query: (id) => `/appointments/patient/${id}/`, + providesTags: ['Appointment'], + refetchOnMountOrArgChange: 5, + }), createAppointment: builder.mutation({ query: (data) => ({ url: '/appointments/', @@ -39,6 +44,7 @@ export const appointmentsApi = createApi({ export const { useGetAppointmentsQuery, + useGetByPatientIdQuery, useCreateAppointmentMutation, useUpdateAppointmentMutation, } = appointmentsApi; \ No newline at end of file diff --git a/web-app/src/Components/Pages/AppointmentsPage/AppointmentsPage.jsx b/web-app/src/Components/Pages/AppointmentsPage/AppointmentsPage.jsx index f59db6a..6ebed9b 100644 --- a/web-app/src/Components/Pages/AppointmentsPage/AppointmentsPage.jsx +++ b/web-app/src/Components/Pages/AppointmentsPage/AppointmentsPage.jsx @@ -1,18 +1,29 @@ -import { Button, FloatButton, Result, Tabs, Typography } from "antd"; -import { Splitter } from "antd"; -import { CalendarOutlined, TableOutlined, MenuFoldOutlined, MenuUnfoldOutlined, PlusOutlined } from "@ant-design/icons"; +import {Button, FloatButton, List, Result, Space, Typography} from "antd"; +import {Splitter} from "antd"; +import { + CalendarOutlined, + MenuFoldOutlined, + MenuUnfoldOutlined, + PlusOutlined, + ClockCircleOutlined +} from "@ant-design/icons"; import AppointmentsCalendarTab from "./Components/AppointmentCalendarTab/AppointmentsCalendarTab.jsx"; -import AppointmentsTableTab from "./Components/AppointmentTableTab/AppointmentsTableTab.jsx"; import useAppointmentsUI from "./useAppointmentsUI.js"; import useAppointments from "./useAppointments.js"; import dayjs from 'dayjs'; import LoadingIndicator from "../../Widgets/LoadingIndicator.jsx"; import AppointmentFormModal from "./Components/AppointmentFormModal/AppointmentFormModal.jsx"; -import { useDispatch } from "react-redux"; -import { closeModal, openModal } from "../../../Redux/Slices/appointmentsSlice.js"; +import {useDispatch} from "react-redux"; +import { + closeModal, + openModal, + setSelectedAppointment, + setSelectedScheduledAppointment +} from "../../../Redux/Slices/appointmentsSlice.js"; import AppointmentViewModal from "./Components/AppointmentViewModal/AppointmentViewModal.jsx"; import ScheduledAppointmentFormModal from "./Components/ScheduledAppintmentFormModal/ScheduledAppointmentFormModal.jsx"; -import ScheduledAppointmentsViewModal from "./Components/ScheduledAppointmentsViewModal/ScheduledAppointmentsViewModal.jsx"; +import ScheduledAppointmentsViewModal + from "./Components/ScheduledAppointmentsViewModal/ScheduledAppointmentsViewModal.jsx"; import AppointmentsListModal from "./Components/AppointmentsListModal/AppointmentsListModal.jsx"; const AppointmentsPage = () => { @@ -24,20 +35,13 @@ const AppointmentsPage = () => { dispatch(closeModal()); }; - const items = [ - { - key: "1", - label: "Календарь приемов", - children: , - icon: , - }, - { - key: "2", - label: "Таблица приемов", - children: , - icon: , - }, - ]; + const handleEventClick = (event) => { + if (event.appointment_datetime) { + dispatch(setSelectedAppointment(event)); + } else { + dispatch(setSelectedScheduledAppointment(event)); + } + }; if (appointmentsData.isError) return ( { return ( <> {appointmentsData.isLoading ? ( - + ) : ( <> { min="25%" max="90%" > - + {appointmentsPageUI.showSplitterPanel && ( @@ -80,17 +84,53 @@ const AppointmentsPage = () => { Предстоящие события {appointmentsPageUI.upcomingEvents.length ? ( -
    - {appointmentsPageUI.upcomingEvents.map((app) => ( -
  • - {dayjs(app.appointment_datetime || app.scheduled_datetime) - .format('DD.MM.YYYY HH:mm')} - - {app.appointment_datetime ? 'Прием' : 'Запланировано'} -
  • - ))} -
+ + dayjs(a.appointment_datetime || a.scheduled_datetime).diff( + dayjs(b.appointment_datetime || b.scheduled_datetime) + ) + )} + renderItem={(item) => ( + handleEventClick(item)} + style={{ + padding: "12px", + marginBottom: "8px", + borderRadius: "4px", + background: item.appointment_datetime ? "#e6f7ff" : "#f6ffed", + cursor: "pointer", + transition: "background 0.3s", + }} + onMouseEnter={(e) => (e.currentTarget.style.background = item.appointment_datetime ? "#d9efff" : "#efffdb")} + onMouseLeave={(e) => (e.currentTarget.style.background = item.appointment_datetime ? "#e6f7ff" : "#f6ffed")} + > + + + {item.appointment_datetime ? ( + + ) : ( + + )} + + {dayjs(item.appointment_datetime || item.scheduled_datetime).format('DD.MM.YYYY HH:mm')} + + + + {item.appointment_datetime ? 'Прием' : 'Запланировано'} + {item.patient ? ` - ${item.patient.last_name} ${item.patient.first_name}` : ''} + + + Тип: {item.type?.title || 'Не указан'} + + {dayjs(item.appointment_datetime || item.scheduled_datetime).isSame(dayjs(), 'day') && ( + Сегодня + )} + + + )} + /> ) : ( -

Нет предстоящих событий

+ Нет предстоящих событий )} )} @@ -103,7 +143,7 @@ const AppointmentsPage = () => { @@ -57,14 +68,16 @@ const AppointmentFormModal = ({onCancel}) => { {appointmentFormModalUI.selectedPatient.last_name} {appointmentFormModalUI.selectedPatient.first_name} -

Дата рождения: {appointmentFormModalUI.getSelectedPatientBirthdayString()}

-

Email: {appointmentFormModalUI.selectedPatient.email || 'Не указан'}

-

Телефон: {appointmentFormModalUI.selectedPatient.phone || 'Не указан'}

- @@ -78,7 +91,7 @@ const AppointmentFormModal = ({onCancel}) => { allowClear />
- +
); @@ -86,95 +99,107 @@ const AppointmentFormModal = ({onCancel}) => { const AppointmentStep = useMemo(() => { return ( -
- + - - - + {appointmentFormModalData.isLoading ? ( +
+ +
+ ) : ( +
{steps[appointmentFormModalUI.currentStep].content}
+ )} + + {!appointmentFormModalUI.screenXS && ( + + )} + + + + + + + + + ({ + key: appointment.id, + label: `Прием ${dayjs(appointment.appointment_datetime).format("DD.MM.YYYY HH:mm")}`, + children:
, + }))} + /> + + )} ); diff --git a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModal.js b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModal.js index 6cf7647..1c16f19 100644 --- a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModal.js +++ b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModal.js @@ -1,7 +1,10 @@ -import {useGetPatientsQuery} from "../../../../../Api/patientsApi.js"; -import {useGetAppointmentTypesQuery} from "../../../../../Api/appointmentTypesApi.js"; -import {useCreateAppointmentMutation, useUpdateAppointmentMutation} from "../../../../../Api/appointmentsApi.js"; -import {useCancelScheduledAppointmentMutation} from "../../../../../Api/scheduledAppointmentsApi.js"; +import { useGetPatientsQuery } from "../../../../../Api/patientsApi.js"; +import { useGetAppointmentTypesQuery } from "../../../../../Api/appointmentTypesApi.js"; +import { + useCreateAppointmentMutation, + useGetByPatientIdQuery, +} from "../../../../../Api/appointmentsApi.js"; +import { useCancelScheduledAppointmentMutation } from "../../../../../Api/scheduledAppointmentsApi.js"; const useAppointmentFormModal = () => { const { @@ -19,7 +22,7 @@ const useAppointmentFormModal = () => { pollingInterval: 20000, }); - const [createAppointment, {isLoading: isCreating, isError: isErrorCreating}] = useCreateAppointmentMutation(); + const [createAppointment, { isLoading: isCreating, isError: isErrorCreating }] = useCreateAppointmentMutation(); const [cancelAppointment] = useCancelScheduledAppointmentMutation(); return { @@ -27,6 +30,7 @@ const useAppointmentFormModal = () => { appointmentTypes, createAppointment, cancelAppointment, + useGetByPatientIdQuery, isLoading: isLoadingPatients || isLoadingAppointmentTypes || isCreating, isError: isErrorPatients || isErrorAppointmentTypes || isErrorCreating, }; diff --git a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModalUI.js b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModalUI.js index 8b8a74f..9c60a02 100644 --- a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModalUI.js +++ b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentFormModal/useAppointmentFormModalUI.js @@ -1,16 +1,16 @@ -import {Form, notification} from "antd"; -import {useDispatch, useSelector} from "react-redux"; -import {closeModal, setSelectedScheduledAppointment} from "../../../../../Redux/Slices/appointmentsSlice.js"; -import {useEffect, useMemo, useState} from "react"; +import { Form, notification } from "antd"; +import { useDispatch, useSelector } from "react-redux"; +import { closeModal, setSelectedScheduledAppointment } from "../../../../../Redux/Slices/appointmentsSlice.js"; +import { useEffect, useMemo, useState } from "react"; import dayjs from "dayjs"; -import {useGetAppointmentsQuery} from "../../../../../Api/appointmentsApi.js"; -import {Grid} from "antd"; +import { useGetAppointmentsQuery } from "../../../../../Api/appointmentsApi.js"; +import { Grid } from "antd"; -const {useBreakpoint} = Grid; +const { useBreakpoint } = Grid; -const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancelAppointment) => { +const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancelAppointment, useGetByPatientIdQuery) => { const dispatch = useDispatch(); - const {modalVisible, scheduledData} = useSelector(state => state.appointmentsUI); + const { modalVisible, scheduledData } = useSelector((state) => state.appointmentsUI); const [form] = Form.useForm(); const screens = useBreakpoint(); @@ -19,31 +19,54 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel const [appointmentDate, setAppointmentDate] = useState(dayjs(new Date())); const [searchPatientString, setSearchPatientString] = useState(""); const [formValues, setFormValues] = useState({}); - const [results, setResults] = useState(''); + const [results, setResults] = useState(""); + const [isDrawerVisible, setIsDrawerVisible] = useState(false); + const [searchPreviousAppointments, setSearchPreviousAppointments] = useState(""); - const {data: appointments = []} = useGetAppointmentsQuery(undefined, { + const { data: appointments = [] } = useGetAppointmentsQuery(undefined, { pollingInterval: 20000, }); - const blockStepStyle = {marginBottom: 16}; - const searchInputStyle = {marginBottom: 16}; - const chooseContainerStyle = {maxHeight: 400, overflowY: "auto"}; - const loadingContainerStyle = {display: "flex", justifyContent: "center", alignItems: "center", height: 200}; - const stepsContentStyle = {marginBottom: 16}; - const stepsIndicatorStyle = {marginBottom: 16}; - const footerRowStyle = {marginTop: 16}; - const footerButtonStyle = {marginRight: 8}; + const { + data: previousAppointments = [], + isLoading: isLoadingPreviousAppointments, + isError: isErrorPreviousAppointments, + } = useGetByPatientIdQuery(selectedPatient?.id, { + pollingInterval: 20000, + skip: !selectedPatient, + }); + + const blockStepStyle = { marginBottom: 16 }; + const searchInputStyle = { marginBottom: 16 }; + const chooseContainerStyle = { maxHeight: 400, overflowY: "auto" }; + const loadingContainerStyle = { display: "flex", justifyContent: "center", alignItems: "center", height: 200 }; + const stepsContentStyle = { marginBottom: 16 }; + const stepsIndicatorStyle = { marginBottom: 16 }; + const footerRowStyle = { marginTop: 16 }; + const footerButtonStyle = { marginRight: 8 }; const screenXS = !screens.sm; const direction = screenXS ? "vertical" : "horizontal"; - const filteredPatients = useMemo(() => patients.filter((patient) => { - const searchLower = searchPatientString.toLowerCase(); + const filteredPatients = useMemo( + () => + patients.filter((patient) => { + const searchLower = searchPatientString.toLowerCase(); + return Object.values(patient) + .filter((value) => typeof value === "string") + .some((value) => value.toLowerCase().includes(searchLower)); + }), + [patients, searchPatientString] + ); - return Object.values(patient) - .filter(value => typeof value === "string") - .some(value => value.toLowerCase().includes(searchLower)); - }), [patients, searchPatientString]); + const filteredPreviousAppointments = useMemo( + () => + previousAppointments.filter((appointment) => { + const searchLower = searchPreviousAppointments.toLowerCase(); + return appointment.results?.toLowerCase().includes(searchLower); + }), + [previousAppointments, searchPreviousAppointments] + ); useEffect(() => { if (modalVisible) { @@ -52,9 +75,11 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel setCurrentStep(0); setSearchPatientString(""); setFormValues({}); + setIsDrawerVisible(false); + setSearchPreviousAppointments(""); if (scheduledData) { - const patient = patients.find(p => p.id === scheduledData.patient_id); + const patient = patients.find((p) => p.id === scheduledData.patient_id); if (patient) { setSelectedPatient(patient); setCurrentStep(1); // Skip to appointment details step @@ -80,33 +105,46 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel setSearchPatientString(e.target.value); }; + const handleSetSearchPreviousAppointments = (e) => { + setSearchPreviousAppointments(e.target.value); + }; + const getDateString = (date) => { - return date ? dayjs(date).format('DD.MM.YYYY') : 'Не указано'; + return date ? dayjs(date).format("DD.MM.YYYY") : "Не указано"; }; const getSelectedPatientBirthdayString = () => { - return selectedPatient ? getDateString(selectedPatient.birthday) : 'Не выбран'; + return selectedPatient ? getDateString(selectedPatient.birthday) : "Не выбран"; }; const resetPatient = () => { setSelectedPatient(null); - form.setFieldsValue({patient_id: undefined}); + form.setFieldsValue({ patient_id: undefined }); }; const handleSetAppointmentDate = (date) => setAppointmentDate(date); - const modalWidth = useMemo(() => screenXS ? 700 : "90%", [screenXS]); + const modalWidth = useMemo(() => (screenXS ? 700 : "90%"), [screenXS]); + + const showDrawer = () => { + setIsDrawerVisible(true); + }; + + const closeDrawer = () => { + setIsDrawerVisible(false); + setSearchPreviousAppointments(""); // Reset search on close + }; const handleClickNextButton = async () => { if (currentStep === 0) { if (!selectedPatient) { notification.error({ - message: 'Ошибка', - description: 'Пожалуйста, выберите пациента.', - placement: 'topRight', + message: "Ошибка", + description: "Пожалуйста, выберите пациента.", + placement: "topRight", }); return; } - form.setFieldsValue({patient_id: selectedPatient.id}); + form.setFieldsValue({ patient_id: selectedPatient.id }); setCurrentStep(1); } else if (currentStep === 1) { try { @@ -115,9 +153,9 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel setCurrentStep(2); } catch (error) { notification.error({ - message: 'Ошибка валидации', - description: error.message || 'Пожалуйста, заполните все обязательные поля.', - placement: 'topRight', + message: "Ошибка валидации", + description: error.message || "Пожалуйста, заполните все обязательные поля.", + placement: "topRight", }); } } else if (currentStep === 2) { @@ -136,15 +174,15 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel const values = formValues; const appointmentTime = values.appointment_datetime; - const hasConflict = appointments.some(app => - dayjs(app.appointment_datetime).isSame(appointmentTime, 'minute') + const hasConflict = appointments.some((app) => + dayjs(app.appointment_datetime).isSame(appointmentTime, "minute") ); if (hasConflict) { notification.error({ - message: 'Конфликт времени', - description: 'Выбранное время уже занято другим приемом.', - placement: 'topRight', + message: "Конфликт времени", + description: "Выбранное время уже занято другим приемом.", + placement: "topRight", }); return; } @@ -165,9 +203,9 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel } notification.success({ - message: 'Прием создан', - description: 'Прием успешно создан.', - placement: 'topRight', + message: "Прием создан", + description: "Прием успешно создан.", + placement: "topRight", }); dispatch(closeModal()); @@ -177,9 +215,9 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel setFormValues({}); } catch (error) { notification.error({ - message: 'Ошибка', - description: error.data?.message || 'Не удалось сохранить прием.', - placement: 'topRight', + message: "Ошибка", + description: error.data?.message || "Не удалось сохранить прием.", + placement: "topRight", }); } }; @@ -189,10 +227,10 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel await cancelAppointment(selectedScheduledAppointmentId); } catch (error) { notification.error({ - message: 'Ошибка', - description: error.data?.message || 'Не удалось отменить прием.', - placement: 'topRight', - }) + message: "Ошибка", + description: error.data?.message || "Не удалось отменить прием.", + placement: "topRight", + }); } }; @@ -202,12 +240,13 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel setCurrentStep(0); setSearchPatientString(""); setFormValues({}); + setIsDrawerVisible(false); onCancel(); }; const disableBackButton = currentStep === 0; const disableNextButton = currentStep === 0 && !selectedPatient; - const nextButtonText = currentStep === 2 ? 'Создать' : 'Далее'; + const nextButtonText = currentStep === 2 ? "Создать" : "Далее"; return { form, @@ -221,6 +260,8 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel setResults, handleSetSearchPatientString, filteredPatients, + filteredPreviousAppointments, + handleSetSearchPreviousAppointments, handleOk, handleCancel, resetPatient, @@ -244,6 +285,11 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancel footerButtonStyle, screenXS, direction, + isDrawerVisible, + showDrawer, + closeDrawer, + isLoadingPreviousAppointments, + isErrorPreviousAppointments, }; }; diff --git a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentsListModal/AppointmentsListModal.jsx b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentsListModal/AppointmentsListModal.jsx index 696575b..5efac02 100644 --- a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentsListModal/AppointmentsListModal.jsx +++ b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentsListModal/AppointmentsListModal.jsx @@ -1,5 +1,5 @@ -import { Button, List, Modal, Typography } from "antd"; -import { useDispatch, useSelector } from "react-redux"; +import {Button, Card, List, Modal, Typography} from "antd"; +import {useDispatch, useSelector} from "react-redux"; import dayjs from "dayjs"; import { closeAppointmentsListModal, @@ -9,7 +9,7 @@ import { const AppointmentsListModal = () => { const dispatch = useDispatch(); - const { appointmentsListModalVisible, selectedDateAppointments } = useSelector( + const {appointmentsListModalVisible, selectedDateAppointments} = useSelector( (state) => state.appointmentsUI ); @@ -39,10 +39,18 @@ const AppointmentsListModal = () => { dataSource={selectedDateAppointments} renderItem={(item) => ( handleItemClick(item)} - style={{ cursor: "pointer", padding: "8px 0" }} + style={{cursor: "pointer", padding: "8px 0"}} > -
+ handleItemClick(item)}> + Просмотр приема + + ]} + >

Время:{" "} {item.appointment_datetime @@ -61,14 +69,14 @@ const AppointmentsListModal = () => { ? `${item.patient.last_name} ${item.patient.first_name}` : "Не указан"}

-
+
)} /> ) : (

Нет приемов на эту дату

)} - diff --git a/web-app/src/Components/Pages/AppointmentsPage/useAppointmentsUI.js b/web-app/src/Components/Pages/AppointmentsPage/useAppointmentsUI.js index 71abf7d..1d53c45 100644 --- a/web-app/src/Components/Pages/AppointmentsPage/useAppointmentsUI.js +++ b/web-app/src/Components/Pages/AppointmentsPage/useAppointmentsUI.js @@ -44,7 +44,7 @@ const useAppointmentsUI = (appointments, scheduledAppointments) => { padding: hovered ? "0 20px" : "0", overflow: "hidden", textAlign: "left", - transition: "width 0.8s ease, padding 0.8s ease", + transition: "width 0.3s ease, padding 0.3s ease", borderRadius: "4px 0 0 4px", }; diff --git a/web-app/src/Components/Widgets/CalendarCell.jsx b/web-app/src/Components/Widgets/CalendarCell.jsx index 47ffeec..5e8cdb1 100644 --- a/web-app/src/Components/Widgets/CalendarCell.jsx +++ b/web-app/src/Components/Widgets/CalendarCell.jsx @@ -1,12 +1,11 @@ -import {useEffect, useRef, useState} from "react"; -import {Badge, Col, Tag, Tooltip} from "antd"; +import { useEffect, useRef, useState } from "react"; +import { Badge, Col, Tag, Tooltip } from "antd"; import dayjs from "dayjs"; import PropTypes from "prop-types"; -import {AppointmentPropType} from "../../Types/appointmentPropType.js"; -import {ScheduledAppointmentPropType} from "../../Types/scheduledAppointmentPropType.js"; +import { AppointmentPropType } from "../../Types/appointmentPropType.js"; +import { ScheduledAppointmentPropType } from "../../Types/scheduledAppointmentPropType.js"; - -const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemClick}) => { +const CalendarCell = ({ allAppointments, onCellClick, onItemClick }) => { const containerRef = useRef(null); const [isCompressed, setIsCompressed] = useState(false); const COMPRESSION_THRESHOLD = 70; @@ -28,56 +27,34 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC ref={containerRef} onClick={isCompressed ? onCellClick : undefined} style={{ - height: '100%', - cursor: isCompressed ? 'pointer' : 'default', - position: 'relative', + height: "100%", + cursor: isCompressed ? "pointer" : "default", + position: "relative", }} > {!isCompressed && ( -
    - {appointments.map(app => ( - +
      + {allAppointments.map((app) => ( + { e.stopPropagation(); onItemClick(app); }} - style={{margin: '2px 2px 0 0', cursor: 'pointer', width: "95%", minHeight: 30}} + style={{ margin: "2px 2px 0 0", cursor: "pointer", width: "95%", minHeight: 30 }} > - - - - ))} - {scheduledAppointments.map(app => ( - - - { - e.stopPropagation(); - onItemClick(app); - }} - style={{margin: '2px 2px 0 0', cursor: 'pointer', width: "95%", minHeight: 30}} - > - @@ -86,15 +63,17 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC
    )} {isCompressed && ( -
    - {appointments.length + scheduledAppointments.length > 0 && `+${appointments.length + scheduledAppointments.length}`} +
    + {allAppointments.length > 0 && `+${allAppointments.length}`}
    )}
    @@ -102,8 +81,9 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC }; CalendarCell.propTypes = { - appointments: PropTypes.arrayOf(AppointmentPropType).isRequired, - scheduledAppointments: PropTypes.arrayOf(ScheduledAppointmentPropType).isRequired, + allAppointments: PropTypes.arrayOf( + PropTypes.oneOfType([AppointmentPropType, ScheduledAppointmentPropType]) + ).isRequired, onCellClick: PropTypes.func.isRequired, onItemClick: PropTypes.func.isRequired, }; diff --git a/web-app/src/Redux/Slices/appointmentsSlice.js b/web-app/src/Redux/Slices/appointmentsSlice.js index 380820b..af8b083 100644 --- a/web-app/src/Redux/Slices/appointmentsSlice.js +++ b/web-app/src/Redux/Slices/appointmentsSlice.js @@ -2,7 +2,7 @@ import { createSlice } from '@reduxjs/toolkit'; const initialState = { modalVisible: false, - collapsed: false, + collapsed: true, siderWidth: 300, hovered: false, selectedAppointment: null,