,
- icon: ,
- }, {
- key: "2",
- label: "Таблица приемов",
- children: ,
- icon: ,
- },];
-
- if (loading) {
- return ()
- }
-
- return (
- <>
-
-
-
-
-
- {!collapsed && !screens.xs && (
-
-
- Предстоящие события
-
- Здесь будут предстоящие приемы...
-
- )}
-
- setHovered(true)}
- onMouseLeave={() => setHovered(false)}
- >
- : }
- style={{
- 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",
- }}
- >
- {hovered ? (collapsed ? "Показать предстоящие события" : "Скрыть предстоящие события") : ""}
-
-
- >
- );
-};
-
-export default AppointmentsLayout;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/AppointmentsCalendarPage.jsx b/web-app/src/Components/Pages/AppointmentsCalendarPage.jsx
deleted file mode 100644
index 54d935f..0000000
--- a/web-app/src/Components/Pages/AppointmentsCalendarPage.jsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import {Calendar, Grid, ConfigProvider, Badge, Modal, Tag, Tooltip} from "antd";
-import {useState} from "react";
-import dayjs from "dayjs";
-import 'dayjs/locale/ru';
-import locale from 'antd/es/locale/ru_RU';
-import updateLocale from 'dayjs/plugin/updateLocale';
-import PropTypes, {arrayOf} from "prop-types";
-import CalendarCell from "../Widgets/CalendarCell.jsx";
-import {AppointmentPropType} from "../../Types/appointmentPropType.js";
-import {ScheduledAppointmentPropType} from "../../Types/scheduledAppointmentPropType.js";
-
-const {useBreakpoint} = Grid;
-
-dayjs.extend(updateLocale);
-dayjs.updateLocale('ru', {
- weekStart: 1
-});
-
-const AppointmentsCalendarPage = ({appointments, scheduledAppointments}) => {
- const screens = useBreakpoint();
- const [selectedDate, setSelectedDate] = useState(dayjs(new Date()));
- const [modalVisible, setModalVisible] = useState(false);
- const [selectedAppointments, setSelectedAppointments] = useState([]);
- const [selectedAppointment, setSelectedAppointment] = useState(null);
-
- const dateCellRender = (value) => {
- const date = value.format('YYYY-MM-DD');
- const appointmentsForDate = appointments.filter(app =>
- dayjs(app.appointment_datetime).format('YYYY-MM-DD') === date
- );
- const scheduledForDate = scheduledAppointments.filter(app =>
- dayjs(app.scheduled_datetime).format('YYYY-MM-DD') === date
- );
-
- return (
- {
- }}
- onItemClick={() => {
- }}
- />
- );
- };
-
- const onSelect = (date) => {
- setSelectedDate(date);
- const selectedDateStr = date.format('YYYY-MM-DD');
- const appointmentsForDate = appointments.filter(app =>
- dayjs(app.appointment_datetime).format('YYYY-MM-DD') === selectedDateStr
- );
- const scheduledForDate = scheduledAppointments.filter(app =>
- dayjs(app.scheduled_datetime).format('YYYY-MM-DD') === selectedDateStr
- );
- setSelectedAppointments([...appointmentsForDate, ...scheduledForDate]);
- setModalVisible(true);
- };
-
- return (
-
-
-
-
-
-
- );
-};
-
-AppointmentsCalendarPage.propTypes = {
- appointments: PropTypes.arrayOf(AppointmentPropType).isRequired,
- scheduledAppointments: PropTypes.arrayOf(ScheduledAppointmentPropType).isRequired,
-};
-
-export default AppointmentsCalendarPage;
\ 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
new file mode 100644
index 0000000..e9b922f
--- /dev/null
+++ b/web-app/src/Components/Pages/AppointmentsPage/AppointmentsPage.jsx
@@ -0,0 +1,76 @@
+import {Button, Tabs, Typography} from "antd";
+import {Splitter} from "antd";
+import {
+ CalendarOutlined, TableOutlined, MenuFoldOutlined, MenuUnfoldOutlined,
+} from "@ant-design/icons";
+import AppointmentsCalendarTab from "./Components/AppointmentCalendarTab/AppointmentsCalendarTab.jsx";
+import AppointmentsTableTab from "./Components/AppointmentTableTab/AppointmentsTableTab.jsx";
+import useAppointmentsUI from "./useAppointmentsUI.js";
+
+
+const AppointmentsPage = () => {
+ const appointmentsPageUI = useAppointmentsUI();
+
+ const items = [{
+ key: "1",
+ label: "Календарь приемов",
+ children: ,
+ icon: ,
+ }, {
+ key: "2",
+ label: "Таблица приемов",
+ children: ,
+ icon: ,
+ },];
+
+ return (
+ <>
+
+
+
+
+
+ {appointmentsPageUI.showSplitterPanel && (
+
+
+ Предстоящие события
+
+ Здесь будут предстоящие приемы...
+
+ )}
+
+
+ : }
+ style={appointmentsPageUI.siderButtonStyle}
+ >
+ {appointmentsPageUI.siderButtonText}
+
+
+ >
+ );
+};
+
+export default AppointmentsPage;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentCalendarTab/AppointmentsCalendarTab.jsx b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentCalendarTab/AppointmentsCalendarTab.jsx
new file mode 100644
index 0000000..bf40a19
--- /dev/null
+++ b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentCalendarTab/AppointmentsCalendarTab.jsx
@@ -0,0 +1,40 @@
+import {Calendar} from "antd";
+import 'dayjs/locale/ru';
+import CalendarCell from "../../../../Widgets/CalendarCell.jsx";
+import useAppointments from "../../useAppointments.js";
+import useAppointmentCalendarUI from "./useAppointmentCalendarUI.js";
+
+
+const AppointmentsCalendarTab = () => {
+ const appointmentsData = useAppointments();
+ const appointmentsCalendarUI = useAppointmentCalendarUI(appointmentsData.appointments, appointmentsData.scheduledAppointments);
+
+ const dateCellRender = (value) => {
+ const appointmentsForDate = appointmentsCalendarUI.getAppointmentsByListAndDate(appointmentsData.appointments, value);
+ const scheduledForDate = appointmentsCalendarUI.getAppointmentsByListAndDate(appointmentsData.scheduledAppointments, value);
+
+ return (
+ {
+ }}
+ onItemClick={() => {
+ }}
+ />
+ );
+ };
+
+ return (
+
+
+
+ );
+};
+
+export default AppointmentsCalendarTab;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentCalendarTab/useAppointmentCalendarUI.js b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentCalendarTab/useAppointmentCalendarUI.js
new file mode 100644
index 0000000..f7edd9c
--- /dev/null
+++ b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentCalendarTab/useAppointmentCalendarUI.js
@@ -0,0 +1,61 @@
+import {useDispatch, useSelector} from "react-redux";
+import dayjs from "dayjs";
+import {
+ openModal,
+ setSelectedAppointments,
+ setSelectedDate
+} from "../../../../../Redux/Slices/appointmentsSlice.js";
+import {Grid} from "antd";
+
+const {useBreakpoint} = Grid;
+
+const useAppointmentCalendarUI = (appointments, scheduledAppointments) => {
+ const dispatch = useDispatch();
+ const {
+ modalVisible,
+ selectedAppointments,
+ selectedAppointment,
+ } = useSelector(state => state.appointmentsUI);
+ const selectedDate = dayjs(useSelector(state => state.appointmentsUI.selectedDate));
+
+
+ const screens = useBreakpoint();
+ const fullScreenCalendar = !screens.xs;
+
+ const calendarContainerStyle = {padding: 20};
+
+ const onSelect = (date) => {
+ const selectedDateStr = date.format('YYYY-MM-DD');
+ dispatch(setSelectedDate(selectedDateStr));
+
+ console.log(appointments)
+ const appointmentsForDate = appointments.filter(app =>
+ dayjs(app.appointment_datetime).format('YYYY-MM-DD') === selectedDateStr
+ );
+ console.log(appointmentsForDate)
+
+ const scheduledForDate = scheduledAppointments.filter(app =>
+ dayjs(app.scheduled_datetime).format('YYYY-MM-DD') === selectedDateStr
+ );
+
+ dispatch(setSelectedAppointments([...appointmentsForDate, ...scheduledForDate]));
+ dispatch(openModal());
+ };
+
+ const getAppointmentsByListAndDate = (list, value) => {
+ const date = value.format('YYYY-MM-DD');
+ return list.filter(app =>
+ dayjs(app.appointment_datetime).format('YYYY-MM-DD') === date
+ );
+ }
+
+ return {
+ selectedDate,
+ fullScreenCalendar,
+ calendarContainerStyle,
+ onSelect,
+ getAppointmentsByListAndDate,
+ };
+};
+
+export default useAppointmentCalendarUI;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/AppointmentsTablePage.jsx b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentTableTab/AppointmentsTableTab.jsx
similarity index 66%
rename from web-app/src/Components/Pages/AppointmentsTablePage.jsx
rename to web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentTableTab/AppointmentsTableTab.jsx
index 1a5a908..5f3ae27 100644
--- a/web-app/src/Components/Pages/AppointmentsTablePage.jsx
+++ b/web-app/src/Components/Pages/AppointmentsPage/Components/AppointmentTableTab/AppointmentsTableTab.jsx
@@ -1,10 +1,8 @@
-import {useAuth} from "../../Hooks/AuthContext.jsx";
+import {useAuth} from "../../../../../Hooks/AuthContext.jsx";
import {useEffect, useState} from "react";
-import getAllAppointments from "../../old_api/appointments/getAllAppointments.js";
-import {notification} from "antd";
-const AppointmentsTablePage = () => {
+const AppointmentsTableTab = () => {
const {api} = useAuth();
const [appointments, setAppointments] = useState([]);
@@ -23,4 +21,4 @@ const AppointmentsTablePage = () => {
);
};
-export default AppointmentsTablePage;
\ No newline at end of file
+export default AppointmentsTableTab;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/AppointmentsPage/useAppointments.js b/web-app/src/Components/Pages/AppointmentsPage/useAppointments.js
new file mode 100644
index 0000000..a0723a5
--- /dev/null
+++ b/web-app/src/Components/Pages/AppointmentsPage/useAppointments.js
@@ -0,0 +1,29 @@
+import {useGetAppointmentsQuery} from "../../../Api/appointmentsApi.js";
+
+
+const useAppointments = () => {
+ const {
+ data: appointments = [],
+ isLoadingAppointments,
+ isErrorAppointments,
+ } = useGetAppointmentsQuery(undefined, {
+ pollingInterval: 20000,
+ });
+
+ const {
+ data: scheduledAppointments = [],
+ isLoadingScheduledAppointments,
+ isErrorScheduledAppointments,
+ } = useGetAppointmentsQuery(undefined, {
+ pollingInterval: 20000,
+ });
+
+ return {
+ appointments,
+ scheduledAppointments,
+ isLoading: isLoadingAppointments || isLoadingScheduledAppointments,
+ isError: isErrorAppointments || isErrorScheduledAppointments,
+ };
+};
+
+export default useAppointments;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/AppointmentsPage/useAppointmentsUI.js b/web-app/src/Components/Pages/AppointmentsPage/useAppointmentsUI.js
new file mode 100644
index 0000000..662b85c
--- /dev/null
+++ b/web-app/src/Components/Pages/AppointmentsPage/useAppointmentsUI.js
@@ -0,0 +1,68 @@
+import {useDispatch, useSelector} from "react-redux";
+import {Grid} from "antd";
+import {setHovered, toggleSider} from "../../../Redux/Slices/appointmentsSlice.js";
+import {useEffect, useMemo} from "react";
+
+const {useBreakpoint} = Grid;
+
+const useAppointmentsUI = () => {
+ const dispatch = useDispatch();
+ const {
+ collapsed,
+ siderWidth,
+ hovered,
+ } = useSelector(state => state.appointmentsUI);
+ const screens = useBreakpoint();
+
+ useEffect(() => {
+ document.title = "Приемы";
+ }, []);
+
+ 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 handleToggleSider = () => dispatch(toggleSider());
+ const handleHoverSider = () => dispatch(setHovered(true));
+ const handleLeaveSider = () => dispatch(setHovered(false));
+
+ const siderButtonText = useMemo(() => hovered ? (collapsed ? "Показать предстоящие события" : "Скрыть предстоящие события") : "", [collapsed, hovered]);
+ const showSplitterPanel = useMemo(() => !collapsed && !screens.xs, [collapsed, screens]);
+
+ return {
+ collapsed,
+ siderWidth,
+ hovered,
+ showSplitterPanel,
+ siderButtonText,
+ splitterStyle,
+ splitterContentPanelStyle,
+ splitterSiderPanelStyle,
+ siderTitleStyle,
+ siderButtonContainerStyle,
+ siderButtonStyle,
+ handleToggleSider,
+ handleHoverSider,
+ handleLeaveSider,
+ };
+};
+
+export default useAppointmentsUI;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/LensIssueFormModal.jsx b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/LensIssueFormModal.jsx
index 9a7b3f7..f9734b7 100644
--- a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/LensIssueFormModal.jsx
+++ b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/LensIssueFormModal.jsx
@@ -2,13 +2,13 @@ import {
Modal, Input, Button, Typography, Collapse, Steps, Row, Alert, Col, DatePicker, Spin
} from "antd";
import PropTypes from "prop-types";
-import useLensIssueFormModal from "./useLensIssueFormModal.js";
-import useLensIssueFormModalUI from "./useLensIssueFormModalUI.js";
+import useLensIssueForm from "./useLensIssueForm.js";
+import useLensIssueFormUI from "./useLensIssueFormUI.js";
import {useMemo} from "react";
const LensIssueFormModal = ({visible, onCancel, onSubmit}) => {
- const lensIssueFormModalData = useLensIssueFormModal();
- const lensIssueFormModalUI = useLensIssueFormModalUI(visible, onCancel, onSubmit, lensIssueFormModalData.patients, lensIssueFormModalData.lenses);
+ const lensIssueFormModalData = useLensIssueForm();
+ const lensIssueFormModalUI = useLensIssueFormUI(visible, onCancel, onSubmit, lensIssueFormModalData.patients, lensIssueFormModalData.lenses);
const patientsItems = lensIssueFormModalUI.filteredPatients.map((patient) => ({
key: patient.id,
@@ -182,7 +182,7 @@ const LensIssueFormModal = ({visible, onCancel, onSubmit}) => {
}, {
title: 'Выбор линзы', content: SelectLensStep,
}, {
- title: 'Подтверждение', content: ,
+ title: 'Подтверждение', content: ConfirmStep,
}];
return (
diff --git a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormModal.js b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueForm.js
similarity index 88%
rename from web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormModal.js
rename to web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueForm.js
index 06cebc4..13eb194 100644
--- a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormModal.js
+++ b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueForm.js
@@ -2,7 +2,7 @@ import {useGetPatientsQuery} from "../../../../../Api/patientsApi.js";
import {useGetNotIssuedLensesQuery} from "../../../../../Api/lensesApi.js";
-const useLensIssueFormModal = () => {
+const useLensIssueForm = () => {
const {data: patients = [], isLoading: isLoadingPatients, isError: isErrorPatients} = useGetPatientsQuery(undefined);
const {data: lenses = [], isLoading: isLoadingLenses, isError: isErrorLenses} = useGetNotIssuedLensesQuery(undefined);
@@ -14,4 +14,4 @@ const useLensIssueFormModal = () => {
};
};
-export default useLensIssueFormModal;
\ No newline at end of file
+export default useLensIssueForm;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormModalUI.js b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormUI.js
similarity index 98%
rename from web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormModalUI.js
rename to web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormUI.js
index 255112d..4474891 100644
--- a/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormModalUI.js
+++ b/web-app/src/Components/Pages/IssuesPage/Components/LensIssueFormModal/useLensIssueFormUI.js
@@ -4,7 +4,7 @@ import {Grid, notification} from "antd";
const {useBreakpoint} = Grid;
-const useLensIssueFormModalUI = (visible, onCancel, onSubmit, patients, lenses) => {
+const useLensIssueFormUI = (visible, onCancel, onSubmit, patients, lenses) => {
const screens = useBreakpoint();
const [searchPatientString, setSearchPatientString] = useState("");
@@ -193,4 +193,4 @@ const useLensIssueFormModalUI = (visible, onCancel, onSubmit, patients, lenses)
};
};
-export default useLensIssueFormModalUI;
\ No newline at end of file
+export default useLensIssueFormUI;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/LensesPage/Components/LensFormModal/LensFormModal.jsx b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/LensFormModal.jsx
similarity index 95%
rename from web-app/src/Components/Pages/LensesPage/Components/LensFormModal/LensFormModal.jsx
rename to web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/LensFormModal.jsx
index 993c616..c289d6f 100644
--- a/web-app/src/Components/Pages/LensesPage/Components/LensFormModal/LensFormModal.jsx
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/LensFormModal.jsx
@@ -1,13 +1,13 @@
import {Col, Form, InputNumber, Modal, Row, Select} from "antd";
import PropTypes from "prop-types";
-import {LensPropType} from "../../../../../Types/lensPropType.js";
-import useLensFormModal from "./useLensFormModal.js";
-import useLensFormModalUI from "./useLensFormModalUI.js";
+import {LensPropType} from "../../../../../../../Types/lensPropType.js";
+import useLensForm from "./useLensForm.js";
+import useLensFormUI from "./useLensFormUI.js";
const LensFormModal = ({visible, onCancel, onSubmit, lens}) => {
- const lensFormData = useLensFormModal();
- const lensFormUI = useLensFormModalUI(lensFormData.lensTypes, visible, onCancel, onSubmit, lens);
+ const lensFormData = useLensForm();
+ const lensFormUI = useLensFormUI(lensFormData.lensTypes, visible, onCancel, onSubmit, lens);
return (
{
+const useLensForm = () => {
const {data: lensTypes = [], isLoading, isError} = useGetLensTypesQuery(undefined);
return {lensTypes, isLoading, isError};
};
-export default useLensFormModal;
\ No newline at end of file
+export default useLensForm;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/LensesPage/Components/LensFormModal/useLensFormModalUI.js b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/useLensFormUI.js
similarity index 89%
rename from web-app/src/Components/Pages/LensesPage/Components/LensFormModal/useLensFormModalUI.js
rename to web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/useLensFormUI.js
index 6047b03..f547eea 100644
--- a/web-app/src/Components/Pages/LensesPage/Components/LensFormModal/useLensFormModalUI.js
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensFormModal/useLensFormUI.js
@@ -2,7 +2,7 @@ import {useEffect} from "react";
import {Form} from "antd";
-const useLensFormModalUI = (lensTypes, visible, onCancel, onSubmit, lens) => {
+const useLensFormUI = (lensTypes, visible, onCancel, onSubmit, lens) => {
const [form] = Form.useForm();
useEffect(() => {
@@ -45,4 +45,4 @@ const useLensFormModalUI = (lensTypes, visible, onCancel, onSubmit, lens) => {
};
};
-export default useLensFormModalUI;
\ No newline at end of file
+export default useLensFormUI;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/LensesPage/Components/LensViewModal/LensViewModal.jsx b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensViewModal/LensViewModal.jsx
similarity index 97%
rename from web-app/src/Components/Pages/LensesPage/Components/LensViewModal/LensViewModal.jsx
rename to web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensViewModal/LensViewModal.jsx
index 022f138..2a45358 100644
--- a/web-app/src/Components/Pages/LensesPage/Components/LensViewModal/LensViewModal.jsx
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/Components/LensViewModal/LensViewModal.jsx
@@ -1,6 +1,6 @@
import {Button, Col, Modal, Row, Typography} from "antd";
import PropTypes from "prop-types";
-import {LensPropType} from "../../../../../Types/lensPropType.js";
+import {LensPropType} from "../../../../../../../Types/lensPropType.js";
const {Text, Title} = Typography;
diff --git a/web-app/src/Components/Pages/LensesPage/LensesPage.jsx b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/LensesTab.jsx
similarity index 98%
rename from web-app/src/Components/Pages/LensesPage/LensesPage.jsx
rename to web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/LensesTab.jsx
index e24305e..35b80ce 100644
--- a/web-app/src/Components/Pages/LensesPage/LensesPage.jsx
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/LensesTab.jsx
@@ -22,10 +22,10 @@ import {
TableOutlined,
BuildOutlined
} from "@ant-design/icons";
-import LensCard from "../../Dummies/LensListCard.jsx";
+import LensCard from "../../../../Dummies/LensListCard.jsx";
import LensFormModal from "./Components/LensFormModal/LensFormModal.jsx";
-import SelectViewMode from "../../Widgets/SelectViewMode.jsx";
-import LoadingIndicator from "../../Widgets/LoadingIndicator.jsx";
+import SelectViewMode from "../../../../Widgets/SelectViewMode.jsx";
+import LoadingIndicator from "../../../../Widgets/LoadingIndicator.jsx";
import useLenses from "./useLenses.js";
import useLensesUI from "./useLensesUI.js";
@@ -33,7 +33,7 @@ const {Option} = Select;
const {useBreakpoint} = Grid;
const {Title} = Typography;
-const LensesPage = () => {
+const LensesTab = () => {
const lensesData = useLenses();
const lensesUI = useLensesUI(lensesData.lenses);
@@ -332,4 +332,4 @@ const LensesPage = () => {
);
};
-export default LensesPage;
\ No newline at end of file
+export default LensesTab;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/LensesPage/useLenses.js b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLenses.js
similarity index 95%
rename from web-app/src/Components/Pages/LensesPage/useLenses.js
rename to web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLenses.js
index bba24f6..a6097cd 100644
--- a/web-app/src/Components/Pages/LensesPage/useLenses.js
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLenses.js
@@ -4,9 +4,9 @@ import {
useDeleteLensMutation,
useGetLensesQuery,
useUpdateLensMutation
-} from "../../../Api/lensesApi.js";
+} from "../../../../../Api/lensesApi.js";
import {notification} from "antd";
-import {closeModal} from "../../../Redux/Slices/lensesSlice.js";
+import {closeModal} from "../../../../../Redux/Slices/lensesSlice.js";
const useLenses = () => {
diff --git a/web-app/src/Components/Pages/LensesPage/useLensesUI.js b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLensesUI.js
similarity index 96%
rename from web-app/src/Components/Pages/LensesPage/useLensesUI.js
rename to web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLensesUI.js
index 9c2ae1e..f9531c1 100644
--- a/web-app/src/Components/Pages/LensesPage/useLensesUI.js
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/LensesTab/useLensesUI.js
@@ -1,5 +1,5 @@
import {useEffect, useMemo} from "react";
-import {getCachedInfo} from "../../../Utils/cachedInfoUtils.js";
+import {getCachedInfo} from "../../../../../Utils/cachedInfoUtils.js";
import {
closeModal,
openModal,
@@ -7,7 +7,7 @@ import {
setSearchParams,
setSearchText, setShowAdvancedSearch,
setViewMode
-} from "../../../Redux/Slices/lensesSlice.js";
+} from "../../../../../Redux/Slices/lensesSlice.js";
import {useDispatch, useSelector} from "react-redux";
diff --git a/web-app/src/Components/Pages/SetsPage/Components/SetFormModal/SetFormModal.jsx b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/SetFormModal.jsx
similarity index 94%
rename from web-app/src/Components/Pages/SetsPage/Components/SetFormModal/SetFormModal.jsx
rename to web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/SetFormModal.jsx
index 85a6eb0..eadbdbb 100644
--- a/web-app/src/Components/Pages/SetsPage/Components/SetFormModal/SetFormModal.jsx
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/SetFormModal.jsx
@@ -1,15 +1,15 @@
import {Modal, Button, Form, Input, Table, InputNumber, Select, Space, Result} from "antd";
import {PlusOutlined, DeleteOutlined} from "@ant-design/icons";
import PropTypes from "prop-types";
-import {SetPropType} from "../../../../../Types/setPropType.js";
-import useSetFormModal from "./useSetFormModal.js";
-import useSetFormModalUI from "./useSetFormModalUI.js";
+import {SetPropType} from "../../../../../../../Types/setPropType.js";
+import useSetForm from "./useSetForm.js";
+import useSetFormUI from "./useSetFormUI.js";
const {Option} = Select;
const SetFormModal = ({visible, onCancel, setData, onSubmit}) => {
- const setFormModalData = useSetFormModal(setData);
- const setFormModalUI = useSetFormModalUI(visible, onCancel, setData, onSubmit, setFormModalData.setContents, setFormModalData.lensTypes);
+ const setFormModalData = useSetForm(setData);
+ const setFormModalUI = useSetFormUI(visible, onCancel, setData, onSubmit, setFormModalData.setContents, setFormModalData.lensTypes);
const columns = [
{
diff --git a/web-app/src/Components/Pages/SetsPage/Components/SetFormModal/useSetFormModal.js b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/useSetForm.js
similarity index 72%
rename from web-app/src/Components/Pages/SetsPage/Components/SetFormModal/useSetFormModal.js
rename to web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/useSetForm.js
index 5f490df..025a3a7 100644
--- a/web-app/src/Components/Pages/SetsPage/Components/SetFormModal/useSetFormModal.js
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/useSetForm.js
@@ -1,8 +1,8 @@
-import {useGetLensTypesQuery} from "../../../../../Api/lensTypesApi.js";
-import {useGetSetContentQuery} from "../../../../../Api/setContentApi.js";
+import {useGetLensTypesQuery} from "../../../../../../../Api/lensTypesApi.js";
+import {useGetSetContentQuery} from "../../../../../../../Api/setContentApi.js";
-const useSetFormModal = (setData) => {
+const useSetForm = (setData) => {
const {data: lensTypes = [], isLoading: isLoadingLensTypes, isError: isErrorLensTypes} =
useGetLensTypesQuery(undefined);
@@ -24,4 +24,4 @@ const useSetFormModal = (setData) => {
};
};
-export default useSetFormModal;
\ No newline at end of file
+export default useSetForm;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/SetsPage/Components/SetFormModal/useSetFormModalUI.js b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/useSetFormUI.js
similarity index 96%
rename from web-app/src/Components/Pages/SetsPage/Components/SetFormModal/useSetFormModalUI.js
rename to web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/useSetFormUI.js
index b79320d..d23a72f 100644
--- a/web-app/src/Components/Pages/SetsPage/Components/SetFormModal/useSetFormModalUI.js
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/Components/SetFormModal/useSetFormUI.js
@@ -2,7 +2,7 @@ import {Form, notification} from "antd";
import {useEffect, useState} from "react";
-const useSetFormModalUI = (visible, onCancel, setData, onSubmit, content, lensTypes) => {
+const useSetFormUI = (visible, onCancel, setData, onSubmit, content, lensTypes) => {
const [form] = Form.useForm();
const [currentContent, setCurrentContent] = useState([]);
@@ -112,4 +112,4 @@ const useSetFormModalUI = (visible, onCancel, setData, onSubmit, content, lensTy
};
};
-export default useSetFormModalUI;
\ No newline at end of file
+export default useSetFormUI;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/SetsPage/SetsPage.jsx b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/SetsTab.jsx
similarity index 93%
rename from web-app/src/Components/Pages/SetsPage/SetsPage.jsx
rename to web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/SetsTab.jsx
index bd1129a..523211c 100644
--- a/web-app/src/Components/Pages/SetsPage/SetsPage.jsx
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/SetsTab.jsx
@@ -1,15 +1,15 @@
import {FloatButton, Input, List, Result, Row, Typography} from "antd";
import {PlusOutlined, SwitcherOutlined} from "@ant-design/icons";
-import SetListCard from "../../Dummies/SetListCard.jsx";
+import SetListCard from "../../../../Dummies/SetListCard.jsx";
import SetFormModal from "./Components/SetFormModal/SetFormModal.jsx";
-import LoadingIndicator from "../../Widgets/LoadingIndicator.jsx";
+import LoadingIndicator from "../../../../Widgets/LoadingIndicator.jsx";
import useSets from "./useSets.js";
import useSetsUI from "./useSetsUI.js";
const {Title} = Typography;
-const SetsPage = () => {
+const SetsTab = () => {
const setsData = useSets();
const setsUI = useSetsUI(setsData.sets);
@@ -79,4 +79,4 @@ const SetsPage = () => {
);
};
-export default SetsPage;
\ No newline at end of file
+export default SetsTab;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/SetsPage/useSets.js b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/useSets.js
similarity index 96%
rename from web-app/src/Components/Pages/SetsPage/useSets.js
rename to web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/useSets.js
index d987d6b..2bdd3e1 100644
--- a/web-app/src/Components/Pages/SetsPage/useSets.js
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/useSets.js
@@ -5,9 +5,9 @@ import {
useDeleteSetMutation,
useGetSetsQuery,
useUpdateSetMutation
-} from "../../../Api/setsApi.js";
-import {closeModal} from "../../../Redux/Slices/setsSlice.js";
-import {useAddSetContentMutation, useUpdateSetContentMutation} from "../../../Api/setContentApi.js";
+} from "../../../../../Api/setsApi.js";
+import {closeModal} from "../../../../../Redux/Slices/setsSlice.js";
+import {useAddSetContentMutation, useUpdateSetContentMutation} from "../../../../../Api/setContentApi.js";
const useSets = () => {
diff --git a/web-app/src/Components/Pages/SetsPage/useSetsUI.js b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/useSetsUI.js
similarity index 97%
rename from web-app/src/Components/Pages/SetsPage/useSetsUI.js
rename to web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/useSetsUI.js
index 1ceab76..8171e60 100644
--- a/web-app/src/Components/Pages/SetsPage/useSetsUI.js
+++ b/web-app/src/Components/Pages/LensesSetsPage/Components/SetsTab/useSetsUI.js
@@ -7,7 +7,7 @@ import {
setCurrentPage,
setPageSize,
setSearchText
-} from "../../../Redux/Slices/setsSlice.js";
+} from "../../../../../Redux/Slices/setsSlice.js";
const useSetsUI = (sets) => {
diff --git a/web-app/src/Components/Layouts/LensesLayout.jsx b/web-app/src/Components/Pages/LensesSetsPage/LensesSetsPage.jsx
similarity index 64%
rename from web-app/src/Components/Layouts/LensesLayout.jsx
rename to web-app/src/Components/Pages/LensesSetsPage/LensesSetsPage.jsx
index 409106f..3dabc51 100644
--- a/web-app/src/Components/Layouts/LensesLayout.jsx
+++ b/web-app/src/Components/Pages/LensesSetsPage/LensesSetsPage.jsx
@@ -1,27 +1,27 @@
import {
Tabs
} from "antd";
-import LensesPage from "../Pages/LensesPage/LensesPage.jsx";
+import LensesTab from "./Components/LensesTab/LensesTab.jsx";
import {FolderViewOutlined, SwitcherOutlined} from "@ant-design/icons";
-import SetsPage from "../Pages/SetsPage/SetsPage.jsx";
+import SetsTab from "./Components/SetsTab/SetsTab.jsx";
const items = [
{
key: '1',
label: 'Линзы',
- children: ,
+ children: ,
icon:
},
{
key: '2',
label: 'Наборы линз',
- children: ,
+ children: ,
icon:
}
]
-const LensesLayout = () => {
+const LensesSetsPage = () => {
return (
{
);
};
-export default LensesLayout;
\ No newline at end of file
+export default LensesSetsPage;
\ No newline at end of file
diff --git a/web-app/src/Components/Pages/LoginPage.jsx b/web-app/src/Components/Pages/LoginPage/LoginPage.jsx
similarity index 97%
rename from web-app/src/Components/Pages/LoginPage.jsx
rename to web-app/src/Components/Pages/LoginPage/LoginPage.jsx
index 6e1cfbc..06ce407 100644
--- a/web-app/src/Components/Pages/LoginPage.jsx
+++ b/web-app/src/Components/Pages/LoginPage/LoginPage.jsx
@@ -1,6 +1,6 @@
import {Form, Input, Button, Row, Col, Typography} from 'antd';
import {useEffect, useState} from 'react';
-import {useAuth} from "../../Hooks/AuthContext.jsx";
+import {useAuth} from "../../../Hooks/AuthContext.jsx";
import {useNavigate} from "react-router-dom";
const {Title} = Typography;
diff --git a/web-app/src/Components/Pages/PatientsPage/Components/PatientFormModal/PatientFormModal.jsx b/web-app/src/Components/Pages/PatientsPage/Components/PatientFormModal/PatientFormModal.jsx
index da93f52..634d9c1 100644
--- a/web-app/src/Components/Pages/PatientsPage/Components/PatientFormModal/PatientFormModal.jsx
+++ b/web-app/src/Components/Pages/PatientsPage/Components/PatientFormModal/PatientFormModal.jsx
@@ -4,12 +4,12 @@ import locale from "antd/es/date-picker/locale/ru_RU";
import {MaskedInput} from "antd-mask-input";
import dayjs from "dayjs";
import {PatientPropType} from "../../../../../Types/patientPropType.js";
-import usePatientFormModalUI from "./usePatientFormModalUI.js";
+import usePatientFormUI from "./usePatientFormUI.js";
const {TextArea} = Input;
const PatientFormModal = ({visible, onCancel, onSubmit, patient}) => {
- const patientFormModalUI = usePatientFormModalUI(visible, onCancel, onSubmit, patient);
+ const patientFormModalUI = usePatientFormUI(visible, onCancel, onSubmit, patient);
return (
{
+const usePatientFormUI = (visible, onCancel, onSubmit, patient) => {
const [form] = Form.useForm();
useEffect(() => {
@@ -65,4 +65,4 @@ const usePatientFormModalUI = (visible, onCancel, onSubmit, patient) => {
}
};
-export default usePatientFormModalUI;
\ No newline at end of file
+export default usePatientFormUI;
\ No newline at end of file
diff --git a/web-app/src/Components/Widgets/CalendarCell.jsx b/web-app/src/Components/Widgets/CalendarCell.jsx
index ec01906..ad8355b 100644
--- a/web-app/src/Components/Widgets/CalendarCell.jsx
+++ b/web-app/src/Components/Widgets/CalendarCell.jsx
@@ -1,5 +1,5 @@
import {useEffect, useRef, useState} from "react";
-import {Badge, Col, Tag, Tooltip, Typography} from "antd";
+import {Badge, Col, Tag, Tooltip} from "antd";
import dayjs from "dayjs";
import PropTypes from "prop-types";
import {AppointmentPropType} from "../../Types/appointmentPropType.js";
@@ -38,6 +38,7 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC
{appointments.map(app => (
@@ -61,6 +62,7 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC
{scheduledAppointments.map(app => (
diff --git a/web-app/src/Redux/Slices/appointmentsSlice.js b/web-app/src/Redux/Slices/appointmentsSlice.js
new file mode 100644
index 0000000..249324c
--- /dev/null
+++ b/web-app/src/Redux/Slices/appointmentsSlice.js
@@ -0,0 +1,57 @@
+import {createSlice} from "@reduxjs/toolkit";
+import dayjs from "dayjs";
+
+
+const initialState = {
+ collapsed: true,
+ siderWidth: 250,
+ hovered: false,
+ selectedDate: dayjs().format('YYYY-MM-DD'),
+ modalVisible: false,
+ selectedAppointments: [],
+ selectedAppointment: null,
+};
+
+const appointmentsSlice = createSlice({
+ name: 'appointmentsUI',
+ initialState,
+ reducers: {
+ toggleSider: (state) => {
+ state.collapsed = !state.collapsed;
+ },
+ setSiderWidth: (state, action) => {
+ state.siderWidth = action.payload;
+ },
+ setHovered: (state, action) => {
+ state.hovered = action.payload;
+ },
+ setSelectedDate: (state, action) => {
+ state.selectedDate = action.payload;
+ },
+ openModal: (state) => {
+ state.modalVisible = true;
+ },
+ closeModal: (state) => {
+ state.modalVisible = false;
+ },
+ setSelectedAppointments: (state, action) => {
+ state.selectedAppointments = action.payload;
+ },
+ setSelectedAppointment: (state, action) => {
+ state.selectedAppointment = action.payload;
+ },
+ }
+});
+
+export const {
+ toggleSider,
+ setSiderWidth,
+ setHovered,
+ setSelectedDate,
+ openModal,
+ closeModal,
+ setSelectedAppointments,
+ setSelectedAppointment,
+} = appointmentsSlice.actions;
+
+export default appointmentsSlice.reducer;
\ No newline at end of file
diff --git a/web-app/src/Redux/store.js b/web-app/src/Redux/store.js
index 257c197..abdf18d 100644
--- a/web-app/src/Redux/store.js
+++ b/web-app/src/Redux/store.js
@@ -9,6 +9,8 @@ import {setContentApi} from "../Api/setContentApi.js";
import {lensIssuesApi} from "../Api/lensIssuesApi.js";
import lensIssuesReducer from "./Slices/lensIssuesSlice.js";
import {lensTypesApi} from "../Api/lensTypesApi.js";
+import {appointmentsApi} from "../Api/appointmentsApi.js";
+import appointmentsReducer from "./Slices/appointmentsSlice.js";
export const store = configureStore({
reducer: {
@@ -27,6 +29,9 @@ export const store = configureStore({
[lensIssuesApi.reducerPath]: lensIssuesApi.reducer,
lensIssuesUI: lensIssuesReducer,
+
+ [appointmentsApi.reducerPath]: appointmentsApi.reducer,
+ appointmentsUI: appointmentsReducer,
},
middleware: (getDefaultMiddleware) => (
getDefaultMiddleware().concat(
@@ -36,8 +41,9 @@ export const store = configureStore({
setContentApi.middleware,
lensTypesApi.middleware,
lensIssuesApi.middleware,
+ appointmentsApi.middleware,
)
- )
+ ),
});
export default store;
\ No newline at end of file
diff --git a/web-app/src/old_api/appointments/getAllAppointments.js b/web-app/src/old_api/appointments/getAllAppointments.js
deleted file mode 100644
index 4ae243f..0000000
--- a/web-app/src/old_api/appointments/getAllAppointments.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const getAllAppointments = async (api) => {
- const response = await api.get(`${CONFIG.BASE_URL}/appointments/`);
- return response.data;
-};
-
-export default getAllAppointments;
\ No newline at end of file
diff --git a/web-app/src/old_api/lens_issues/addLensIssue.js b/web-app/src/old_api/lens_issues/addLensIssue.js
deleted file mode 100644
index f5d2524..0000000
--- a/web-app/src/old_api/lens_issues/addLensIssue.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const AddLensIssue = async (api, lens_issue) => {
- const response = await api.post(`${CONFIG.BASE_URL}/lens_issues/`, lens_issue);
- return response.data;
-};
-
-export default AddLensIssue;
\ No newline at end of file
diff --git a/web-app/src/old_api/lens_issues/getAllLensIssues.js b/web-app/src/old_api/lens_issues/getAllLensIssues.js
deleted file mode 100644
index 7bf884d..0000000
--- a/web-app/src/old_api/lens_issues/getAllLensIssues.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const GetAllLensIssues = async (api) => {
- const response = await api.get(`${CONFIG.BASE_URL}/lens_issues/`);
- return response.data;
-};
-
-export default GetAllLensIssues;
\ No newline at end of file
diff --git a/web-app/src/old_api/lens_types/getAllLensTypes.js b/web-app/src/old_api/lens_types/getAllLensTypes.js
deleted file mode 100644
index 8755872..0000000
--- a/web-app/src/old_api/lens_types/getAllLensTypes.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const getAllLensTypes = async (api) => {
- const response = await api.get(`${CONFIG.BASE_URL}/lens_types/`);
- return response.data;
-};
-
-export default getAllLensTypes;
\ No newline at end of file
diff --git a/web-app/src/old_api/lenses/getNotIssuedLenses.js b/web-app/src/old_api/lenses/getNotIssuedLenses.js
deleted file mode 100644
index e8ab429..0000000
--- a/web-app/src/old_api/lenses/getNotIssuedLenses.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const getNotIssuedLenses = async (api) => {
- const response = await api.get(`${CONFIG.BASE_URL}/lenses/not_issued/`);
- return response.data;
-};
-
-export default getNotIssuedLenses;
\ No newline at end of file
diff --git a/web-app/src/old_api/patients/getAllPatients.js b/web-app/src/old_api/patients/getAllPatients.js
deleted file mode 100644
index 44c8970..0000000
--- a/web-app/src/old_api/patients/getAllPatients.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const getAllPatients = async (api) => {
- const response = await api.get(`${CONFIG.BASE_URL}/patients/`);
- return response.data;
-};
-
-export default getAllPatients;
\ No newline at end of file
diff --git a/web-app/src/old_api/scheduled_appointments/getAllScheduledAppointments.js b/web-app/src/old_api/scheduled_appointments/getAllScheduledAppointments.js
deleted file mode 100644
index 8fdbd58..0000000
--- a/web-app/src/old_api/scheduled_appointments/getAllScheduledAppointments.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const getAllScheduledAppointments = async (api) => {
- const response = await api.get(`${CONFIG.BASE_URL}/scheduled_appointments/`);
- return response.data;
-};
-
-export default getAllScheduledAppointments;
\ No newline at end of file
diff --git a/web-app/src/old_api/set_content/getSetContentBySetId.js b/web-app/src/old_api/set_content/getSetContentBySetId.js
deleted file mode 100644
index 6fa7b2b..0000000
--- a/web-app/src/old_api/set_content/getSetContentBySetId.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import CONFIG from "../../Core/сonfig.js";
-
-const getSetContentBySetId = async (api, set_id) => {
- const response = await api.get(`${CONFIG.BASE_URL}/set_content/${set_id}/`);
- return response.data;
-};
-
-export default getSetContentBySetId;
\ No newline at end of file