проверка работы gitea

This commit is contained in:
Андрей Дувакин 2025-05-13 14:14:51 +05:00
parent c320437b00
commit 0a14842120
49 changed files with 483 additions and 398 deletions

View File

@ -1,4 +1,3 @@
from logging.config import fileConfig from logging.config import fileConfig
from alembic import context from alembic import context
@ -22,7 +21,6 @@ def get_url():
async def run_migrations_online(): async def run_migrations_online():
connectable = create_async_engine(get_url(), poolclass=pool.NullPool, future=True) connectable = create_async_engine(get_url(), poolclass=pool.NullPool, future=True)
async with connectable.connect() as connection: async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations) await connection.run_sync(do_run_migrations)

View File

@ -6,7 +6,7 @@ from pydantic import BaseModel
class RegisterEntity(BaseModel): class RegisterEntity(BaseModel):
first_name: str first_name: str
last_name: str last_name: str
patronymic: Optional[str] patronymic: Optional[str] = None
role_id: int role_id: int
login: str login: str
password: str password: str

View File

@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, VARCHAR from sqlalchemy import Column, VARCHAR
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from app.domain.models.base import BaseModel from app.domain.models.base import BaseModel

View File

@ -1,4 +1,5 @@
import re import re
from typing import Optional
from fastapi import HTTPException, status from fastapi import HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
@ -12,18 +13,18 @@ from app.domain.models import User
class UsersService: class UsersService:
def __init__(self, db: AsyncSession): def __init__(self, db: AsyncSession):
self.user_repository = UsersRepository(db) self.users_repository = UsersRepository(db)
self.role_repository = RolesRepository(db) self.roles_repository = RolesRepository(db)
async def register_user(self, register_entity: RegisterEntity) -> UserEntity: async def register_user(self, register_entity: RegisterEntity) -> Optional[UserEntity]:
role = await self.role_repository.get_by_id(register_entity.role_id) role = await self.roles_repository.get_by_id(register_entity.role_id)
if not role: if not role:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail='The role with this ID was not found' detail='The role with this ID was not found'
) )
user = await self.user_repository.get_by_login(register_entity.login) user = await self.users_repository.get_by_login(register_entity.login)
if user: if user:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
@ -45,7 +46,7 @@ class UsersService:
) )
user_model.set_password(register_entity.password) user_model.set_password(register_entity.password)
created_user = await self.user_repository.create(user_model) created_user = await self.users_repository.create(user_model)
return UserEntity( return UserEntity(
id=created_user.id, id=created_user.id,

View File

@ -0,0 +1,27 @@
import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/query/react";
import CONFIG from "../Core/сonfig.js";
export const appointmentsApi = createApi({
reducerPath: 'appointmentsApi',
baseQuery: fetchBaseQuery({
baseUrl: CONFIG.BASE_URL,
prepareHeaders: (headers) => {
const token = localStorage.getItem('access_token');
if (token) headers.set('Authorization', `Bearer ${token}`);
return headers;
}
}),
tagTypes: ['Appointment'],
endpoints: (builder) => ({
getAppointments: builder.query({
query: () => '/appointments/',
providesTags: ['Appointment'],
refetchOnMountOrArgChange: 5
}),
}),
});
export const {
useGetAppointmentsQuery,
} = appointmentsApi;

View File

@ -0,0 +1,25 @@
import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/query/react";
import CONFIG from "../Core/сonfig.js";
export const scheduledAppointmentsApi = createApi({
reducerPath: 'scheduledAppointmentsApi',
baseQuery: fetchBaseQuery({
baseUrl: CONFIG.BASE_URL,
prepareHeaders: (headers) => {
const token = localStorage.getItem('access_token');
if (token) headers.set('Authorization', `Bearer ${token}`);
return headers;
}
}),
tagTypes: ['ScheduledAppointment'],
endpoints: (builder) => ({
getScheduledAppointments: builder.query({
query: () => `/scheduledAppointments`,
}),
}),
});
export const {
useGetScheduledAppointmentsQuery,
} = scheduledAppointmentsApi;

View File

@ -4,12 +4,19 @@ import {AuthProvider} from "../Hooks/AuthContext.jsx";
import "/src/Styles/app.css"; import "/src/Styles/app.css";
import {Provider} from "react-redux"; import {Provider} from "react-redux";
import store from "../Redux/store.js"; import store from "../Redux/store.js";
import dayjs from "dayjs";
import locale from 'antd/locale/ru_RU';
import {ConfigProvider} from "antd";
dayjs.locale('ru');
const App = () => ( const App = () => (
<Provider store={store}> <Provider store={store}>
<Router> <Router>
<AuthProvider> <AuthProvider>
<ConfigProvider locale={locale}>
<AppRouter/> <AppRouter/>
</ConfigProvider>
</AuthProvider> </AuthProvider>
</Router> </Router>
</Provider> </Provider>

View File

@ -1,12 +1,12 @@
import {Routes, Route, Navigate} from "react-router-dom"; import {Routes, Route, Navigate} from "react-router-dom";
import PrivateRoute from "../Components/PrivateRoute.jsx"; import PrivateRoute from "./PrivateRoute.jsx";
import LoginPage from "../Components/Pages/LoginPage.jsx"; import LoginPage from "../Components/Pages/LoginPage/LoginPage.jsx";
import MainLayout from "../Components/Layouts/MainLayout.jsx"; import MainLayout from "../Components/Layouts/MainLayout.jsx";
import PatientsPage from "../Components/Pages/PatientsPage/PatientsPage.jsx"; import PatientsPage from "../Components/Pages/PatientsPage/PatientsPage.jsx";
import HomePage from "../Components/Pages/HomePage.jsx"; import HomePage from "../Components/Pages/HomePage.jsx";
import LensesLayout from "../Components/Layouts/LensesLayout.jsx"; import LensesSetsPage from "../Components/Pages/LensesSetsPage/LensesSetsPage.jsx";
import IssuesPage from "../Components/Pages/IssuesPage/IssuesPage.jsx"; import IssuesPage from "../Components/Pages/IssuesPage/IssuesPage.jsx";
import AppointmentsLayout from "../Components/Layouts/AppointmentsLayout.jsx"; import AppointmentsPage from "../Components/Pages/AppointmentsPage/AppointmentsPage.jsx";
const AppRouter = () => ( const AppRouter = () => (
@ -16,9 +16,9 @@ const AppRouter = () => (
<Route element={<PrivateRoute/>}> <Route element={<PrivateRoute/>}>
<Route element={<MainLayout/>}> <Route element={<MainLayout/>}>
<Route path={"/Patients"} element={<PatientsPage/>}/> <Route path={"/Patients"} element={<PatientsPage/>}/>
<Route path={"/Lenses"} element={<LensesLayout/>}/> <Route path={"/Lenses"} element={<LensesSetsPage/>}/>
<Route path={"/issues"} element={<IssuesPage/>}/> <Route path={"/issues"} element={<IssuesPage/>}/>
<Route path={"/Appointments"} element={<AppointmentsLayout/>}/> <Route path={"/Appointments"} element={<AppointmentsPage/>}/>
<Route path={"/"} element={<HomePage/>}/> <Route path={"/"} element={<HomePage/>}/>
</Route> </Route>
</Route> </Route>

View File

@ -2,7 +2,7 @@ import {Card, Popconfirm, Tooltip} from "antd";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {DeleteOutlined, EditOutlined, EyeOutlined} from "@ant-design/icons"; import {DeleteOutlined, EditOutlined, EyeOutlined} from "@ant-design/icons";
import {useState} from "react"; import {useState} from "react";
import LensViewModal from "../Pages/LensesPage/Components/LensViewModal/LensViewModal.jsx"; import LensViewModal from "../Pages/LensesSetsPage/Components/LensesTab/Components/LensViewModal/LensViewModal.jsx";
import {LensPropType} from "../../Types/lensPropType.js"; import {LensPropType} from "../../Types/lensPropType.js";
const LensListCard = ({lens, handleEditLens, handleDeleteLens}) => { const LensListCard = ({lens, handleEditLens, handleDeleteLens}) => {

View File

@ -1,166 +0,0 @@
import {useEffect, useState} from "react";
import {Button, Grid, Tabs, Typography} from "antd";
import {Splitter} from "antd";
import {
CalendarOutlined, TableOutlined, MenuFoldOutlined, MenuUnfoldOutlined,
} from "@ant-design/icons";
import AppointmentsCalendarPage from "../Pages/AppointmentsCalendarPage.jsx";
import AppointmentsTablePage from "../Pages/AppointmentsTablePage.jsx";
import getAllAppointments from "../../old_api/appointments/getAllAppointments.js";
import getAllScheduledAppointments from "../../old_api/scheduled_appointments/getAllScheduledAppointments.js";
import {useAuth} from "../../Hooks/AuthContext.jsx";
import LoadingIndicator from "../Widgets/LoadingIndicator.jsx";
import {cacheInfo, getCachedInfo, getCacheTimestamp} from "../../Utils/cachedInfoUtils.js";
const {useBreakpoint} = Grid;
const AppointmentsLayout = () => {
const [collapsed, setCollapsed] = useState(true);
const [siderWidth, setSiderWidth] = useState(250);
const [hovered, setHovered] = useState(false);
const screens = useBreakpoint();
const {api} = useAuth();
const [loading, setLoading] = useState(true);
const [appointments, setAppointments] = useState([]);
const [scheduledAppointments, setScheduledAppointments] = useState([]);
const toggleSider = () => setCollapsed(!collapsed);
useEffect(() => {
loadDataWithCache();
}, []);
useEffect(() => {
const interval = setInterval(loadData, 5000);
return () => clearInterval(interval);
}, []);
const loadData = async () => {
await fetchAppointments();
await fetchScheduledAppointments();
setLoading(false);
};
const loadDataWithCache = async () => {
await fetchAppointmentsWithCache();
await fetchScheduledAppointmentsWithCache();
};
const fetchAppointmentsWithCache = async () => {
const cachedData = getCachedInfo("appointmentsData");
const cacheTimestamp = getCacheTimestamp("appointmentsData");
if (cachedData && cacheTimestamp && (Date.now() - cacheTimestamp) < 60 * 1000) {
setAppointments(cachedData);
return;
}
await fetchAppointments();
};
const fetchAppointments = async () => {
const data = await getAllAppointments(api);
setAppointments(data);
cacheInfo("appointmentsData", data);
};
const fetchScheduledAppointmentsWithCache = async () => {
const cachedData = getCachedInfo("scheduledAppointmentsData");
const cacheTimestamp = getCacheTimestamp("scheduledAppointmentsData");
if (cachedData && cacheTimestamp && (Date.now() - cacheTimestamp) < 60 * 1000) {
setScheduledAppointments(cachedData);
return;
}
await fetchScheduledAppointments();
};
const fetchScheduledAppointments = async () => {
const data = await getAllScheduledAppointments(api);
setScheduledAppointments(data);
cacheInfo("scheduledAppointmentsData", data);
};
const items = [{
key: "1",
label: "Календарь приемов",
children: <AppointmentsCalendarPage appointments={appointments} scheduledAppointments={scheduledAppointments}/>,
icon: <CalendarOutlined/>,
}, {
key: "2",
label: "Таблица приемов",
children: <AppointmentsTablePage/>,
icon: <TableOutlined/>,
},];
if (loading) {
return (<LoadingIndicator/>)
}
return (
<>
<Splitter
style={{flex: 1}}
min={200}
max={400}
initial={siderWidth}
onChange={setSiderWidth}
>
<Splitter.Panel style={{padding: 16}} defaultSize="80%" min="25%" max="90%">
<Tabs defaultActiveKey="1" items={items}/>
</Splitter.Panel>
{!collapsed && !screens.xs && (
<Splitter.Panel
style={{
padding: "16px", borderLeft: "1px solid #ddd", overflowY: "auto",
}}
defaultSize="20%"
min="20%"
max="75%"
>
<Typography.Title level={3} style={{marginBottom: 36}}>
Предстоящие события
</Typography.Title>
<p>Здесь будут предстоящие приемы...</p>
</Splitter.Panel>
)}
</Splitter>
<div
style={{
position: "fixed",
right: 0,
top: "50%",
transform: "translateY(-50%)",
transition: "right 0.3s ease",
zIndex: 1000,
display: screens.xs ? "none" : "block",
}}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
<Button
type="primary"
onClick={toggleSider}
icon={collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
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 ? "Показать предстоящие события" : "Скрыть предстоящие события") : ""}
</Button>
</div>
</>
);
};
export default AppointmentsLayout;

View File

@ -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 (
<CalendarCell
appointments={appointmentsForDate}
scheduledAppointments={scheduledForDate}
onCellClick={() => {
}}
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 (
<ConfigProvider locale={locale}>
<div style={{padding: 20}}>
<Calendar
fullscreen={!screens.xs}
value={selectedDate}
onSelect={onSelect}
cellRender={dateCellRender}
/>
</div>
</ConfigProvider>
);
};
AppointmentsCalendarPage.propTypes = {
appointments: PropTypes.arrayOf(AppointmentPropType).isRequired,
scheduledAppointments: PropTypes.arrayOf(ScheduledAppointmentPropType).isRequired,
};
export default AppointmentsCalendarPage;

View File

@ -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: <AppointmentsCalendarTab/>,
icon: <CalendarOutlined/>,
}, {
key: "2",
label: "Таблица приемов",
children: <AppointmentsTableTab/>,
icon: <TableOutlined/>,
},];
return (
<>
<Splitter
style={appointmentsPageUI.splitterStyle}
min={200}
max={400}
initial={appointmentsPageUI.siderWidth}
onChange={appointmentsPageUI.setSiderWidth}
>
<Splitter.Panel
style={appointmentsPageUI.splitterContentPanelStyle}
defaultSize="80%"
min="25%"
max="90%"
>
<Tabs defaultActiveKey="1" items={items}/>
</Splitter.Panel>
{appointmentsPageUI.showSplitterPanel && (
<Splitter.Panel
style={appointmentsPageUI.splitterSiderPanelStyle}
defaultSize="20%"
min="20%"
max="75%"
>
<Typography.Title level={3} style={appointmentsPageUI.siderTitleStyle}>
Предстоящие события
</Typography.Title>
<p>Здесь будут предстоящие приемы...</p>
</Splitter.Panel>
)}
</Splitter>
<div
style={appointmentsPageUI.siderButtonContainerStyle}
onMouseEnter={appointmentsPageUI.handleHoverSider}
onMouseLeave={appointmentsPageUI.handleLeaveSider}
>
<Button
type="primary"
onClick={appointmentsPageUI.handleToggleSider}
icon={appointmentsPageUI.collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
style={appointmentsPageUI.siderButtonStyle}
>
{appointmentsPageUI.siderButtonText}
</Button>
</div>
</>
);
};
export default AppointmentsPage;

View File

@ -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 (
<CalendarCell
appointments={appointmentsForDate}
scheduledAppointments={scheduledForDate}
onCellClick={() => {
}}
onItemClick={() => {
}}
/>
);
};
return (
<div style={appointmentsCalendarUI.calendarContainerStyle}>
<Calendar
fullscreen={appointmentsCalendarUI.fullScreenCalendar}
value={appointmentsCalendarUI.selectedDate}
onSelect={appointmentsCalendarUI.onSelect}
cellRender={dateCellRender}
/>
</div>
);
};
export default AppointmentsCalendarTab;

View File

@ -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;

View File

@ -1,10 +1,8 @@
import {useAuth} from "../../Hooks/AuthContext.jsx"; import {useAuth} from "../../../../../Hooks/AuthContext.jsx";
import {useEffect, useState} from "react"; 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 {api} = useAuth();
const [appointments, setAppointments] = useState([]); const [appointments, setAppointments] = useState([]);
@ -23,4 +21,4 @@ const AppointmentsTablePage = () => {
); );
}; };
export default AppointmentsTablePage; export default AppointmentsTableTab;

View File

@ -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;

View File

@ -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;

View File

@ -2,13 +2,13 @@ import {
Modal, Input, Button, Typography, Collapse, Steps, Row, Alert, Col, DatePicker, Spin Modal, Input, Button, Typography, Collapse, Steps, Row, Alert, Col, DatePicker, Spin
} from "antd"; } from "antd";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import useLensIssueFormModal from "./useLensIssueFormModal.js"; import useLensIssueForm from "./useLensIssueForm.js";
import useLensIssueFormModalUI from "./useLensIssueFormModalUI.js"; import useLensIssueFormUI from "./useLensIssueFormUI.js";
import {useMemo} from "react"; import {useMemo} from "react";
const LensIssueFormModal = ({visible, onCancel, onSubmit}) => { const LensIssueFormModal = ({visible, onCancel, onSubmit}) => {
const lensIssueFormModalData = useLensIssueFormModal(); const lensIssueFormModalData = useLensIssueForm();
const lensIssueFormModalUI = useLensIssueFormModalUI(visible, onCancel, onSubmit, lensIssueFormModalData.patients, lensIssueFormModalData.lenses); const lensIssueFormModalUI = useLensIssueFormUI(visible, onCancel, onSubmit, lensIssueFormModalData.patients, lensIssueFormModalData.lenses);
const patientsItems = lensIssueFormModalUI.filteredPatients.map((patient) => ({ const patientsItems = lensIssueFormModalUI.filteredPatients.map((patient) => ({
key: patient.id, key: patient.id,
@ -182,7 +182,7 @@ const LensIssueFormModal = ({visible, onCancel, onSubmit}) => {
}, { }, {
title: 'Выбор линзы', content: SelectLensStep, title: 'Выбор линзы', content: SelectLensStep,
}, { }, {
title: 'Подтверждение', content: <ConfirmStep/>, title: 'Подтверждение', content: ConfirmStep,
}]; }];
return ( return (

View File

@ -2,7 +2,7 @@ import {useGetPatientsQuery} from "../../../../../Api/patientsApi.js";
import {useGetNotIssuedLensesQuery} from "../../../../../Api/lensesApi.js"; import {useGetNotIssuedLensesQuery} from "../../../../../Api/lensesApi.js";
const useLensIssueFormModal = () => { const useLensIssueForm = () => {
const {data: patients = [], isLoading: isLoadingPatients, isError: isErrorPatients} = useGetPatientsQuery(undefined); const {data: patients = [], isLoading: isLoadingPatients, isError: isErrorPatients} = useGetPatientsQuery(undefined);
const {data: lenses = [], isLoading: isLoadingLenses, isError: isErrorLenses} = useGetNotIssuedLensesQuery(undefined); const {data: lenses = [], isLoading: isLoadingLenses, isError: isErrorLenses} = useGetNotIssuedLensesQuery(undefined);
@ -14,4 +14,4 @@ const useLensIssueFormModal = () => {
}; };
}; };
export default useLensIssueFormModal; export default useLensIssueForm;

View File

@ -4,7 +4,7 @@ import {Grid, notification} from "antd";
const {useBreakpoint} = Grid; const {useBreakpoint} = Grid;
const useLensIssueFormModalUI = (visible, onCancel, onSubmit, patients, lenses) => { const useLensIssueFormUI = (visible, onCancel, onSubmit, patients, lenses) => {
const screens = useBreakpoint(); const screens = useBreakpoint();
const [searchPatientString, setSearchPatientString] = useState(""); const [searchPatientString, setSearchPatientString] = useState("");
@ -193,4 +193,4 @@ const useLensIssueFormModalUI = (visible, onCancel, onSubmit, patients, lenses)
}; };
}; };
export default useLensIssueFormModalUI; export default useLensIssueFormUI;

View File

@ -1,13 +1,13 @@
import {Col, Form, InputNumber, Modal, Row, Select} from "antd"; import {Col, Form, InputNumber, Modal, Row, Select} from "antd";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {LensPropType} from "../../../../../Types/lensPropType.js"; import {LensPropType} from "../../../../../../../Types/lensPropType.js";
import useLensFormModal from "./useLensFormModal.js"; import useLensForm from "./useLensForm.js";
import useLensFormModalUI from "./useLensFormModalUI.js"; import useLensFormUI from "./useLensFormUI.js";
const LensFormModal = ({visible, onCancel, onSubmit, lens}) => { const LensFormModal = ({visible, onCancel, onSubmit, lens}) => {
const lensFormData = useLensFormModal(); const lensFormData = useLensForm();
const lensFormUI = useLensFormModalUI(lensFormData.lensTypes, visible, onCancel, onSubmit, lens); const lensFormUI = useLensFormUI(lensFormData.lensTypes, visible, onCancel, onSubmit, lens);
return ( return (
<Modal <Modal

View File

@ -1,10 +1,10 @@
import {useGetLensTypesQuery} from "../../../../../Api/lensTypesApi.js"; import {useGetLensTypesQuery} from "../../../../../../../Api/lensTypesApi.js";
const useLensFormModal = () => { const useLensForm = () => {
const {data: lensTypes = [], isLoading, isError} = useGetLensTypesQuery(undefined); const {data: lensTypes = [], isLoading, isError} = useGetLensTypesQuery(undefined);
return {lensTypes, isLoading, isError}; return {lensTypes, isLoading, isError};
}; };
export default useLensFormModal; export default useLensForm;

View File

@ -2,7 +2,7 @@ import {useEffect} from "react";
import {Form} from "antd"; import {Form} from "antd";
const useLensFormModalUI = (lensTypes, visible, onCancel, onSubmit, lens) => { const useLensFormUI = (lensTypes, visible, onCancel, onSubmit, lens) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
useEffect(() => { useEffect(() => {
@ -45,4 +45,4 @@ const useLensFormModalUI = (lensTypes, visible, onCancel, onSubmit, lens) => {
}; };
}; };
export default useLensFormModalUI; export default useLensFormUI;

View File

@ -1,6 +1,6 @@
import {Button, Col, Modal, Row, Typography} from "antd"; import {Button, Col, Modal, Row, Typography} from "antd";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {LensPropType} from "../../../../../Types/lensPropType.js"; import {LensPropType} from "../../../../../../../Types/lensPropType.js";
const {Text, Title} = Typography; const {Text, Title} = Typography;

View File

@ -22,10 +22,10 @@ import {
TableOutlined, TableOutlined,
BuildOutlined BuildOutlined
} from "@ant-design/icons"; } from "@ant-design/icons";
import LensCard from "../../Dummies/LensListCard.jsx"; import LensCard from "../../../../Dummies/LensListCard.jsx";
import LensFormModal from "./Components/LensFormModal/LensFormModal.jsx"; import LensFormModal from "./Components/LensFormModal/LensFormModal.jsx";
import SelectViewMode from "../../Widgets/SelectViewMode.jsx"; import SelectViewMode from "../../../../Widgets/SelectViewMode.jsx";
import LoadingIndicator from "../../Widgets/LoadingIndicator.jsx"; import LoadingIndicator from "../../../../Widgets/LoadingIndicator.jsx";
import useLenses from "./useLenses.js"; import useLenses from "./useLenses.js";
import useLensesUI from "./useLensesUI.js"; import useLensesUI from "./useLensesUI.js";
@ -33,7 +33,7 @@ const {Option} = Select;
const {useBreakpoint} = Grid; const {useBreakpoint} = Grid;
const {Title} = Typography; const {Title} = Typography;
const LensesPage = () => { const LensesTab = () => {
const lensesData = useLenses(); const lensesData = useLenses();
const lensesUI = useLensesUI(lensesData.lenses); const lensesUI = useLensesUI(lensesData.lenses);
@ -332,4 +332,4 @@ const LensesPage = () => {
); );
}; };
export default LensesPage; export default LensesTab;

View File

@ -4,9 +4,9 @@ import {
useDeleteLensMutation, useDeleteLensMutation,
useGetLensesQuery, useGetLensesQuery,
useUpdateLensMutation useUpdateLensMutation
} from "../../../Api/lensesApi.js"; } from "../../../../../Api/lensesApi.js";
import {notification} from "antd"; import {notification} from "antd";
import {closeModal} from "../../../Redux/Slices/lensesSlice.js"; import {closeModal} from "../../../../../Redux/Slices/lensesSlice.js";
const useLenses = () => { const useLenses = () => {

View File

@ -1,5 +1,5 @@
import {useEffect, useMemo} from "react"; import {useEffect, useMemo} from "react";
import {getCachedInfo} from "../../../Utils/cachedInfoUtils.js"; import {getCachedInfo} from "../../../../../Utils/cachedInfoUtils.js";
import { import {
closeModal, closeModal,
openModal, openModal,
@ -7,7 +7,7 @@ import {
setSearchParams, setSearchParams,
setSearchText, setShowAdvancedSearch, setSearchText, setShowAdvancedSearch,
setViewMode setViewMode
} from "../../../Redux/Slices/lensesSlice.js"; } from "../../../../../Redux/Slices/lensesSlice.js";
import {useDispatch, useSelector} from "react-redux"; import {useDispatch, useSelector} from "react-redux";

View File

@ -1,15 +1,15 @@
import {Modal, Button, Form, Input, Table, InputNumber, Select, Space, Result} from "antd"; import {Modal, Button, Form, Input, Table, InputNumber, Select, Space, Result} from "antd";
import {PlusOutlined, DeleteOutlined} from "@ant-design/icons"; import {PlusOutlined, DeleteOutlined} from "@ant-design/icons";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {SetPropType} from "../../../../../Types/setPropType.js"; import {SetPropType} from "../../../../../../../Types/setPropType.js";
import useSetFormModal from "./useSetFormModal.js"; import useSetForm from "./useSetForm.js";
import useSetFormModalUI from "./useSetFormModalUI.js"; import useSetFormUI from "./useSetFormUI.js";
const {Option} = Select; const {Option} = Select;
const SetFormModal = ({visible, onCancel, setData, onSubmit}) => { const SetFormModal = ({visible, onCancel, setData, onSubmit}) => {
const setFormModalData = useSetFormModal(setData); const setFormModalData = useSetForm(setData);
const setFormModalUI = useSetFormModalUI(visible, onCancel, setData, onSubmit, setFormModalData.setContents, setFormModalData.lensTypes); const setFormModalUI = useSetFormUI(visible, onCancel, setData, onSubmit, setFormModalData.setContents, setFormModalData.lensTypes);
const columns = [ const columns = [
{ {

View File

@ -1,8 +1,8 @@
import {useGetLensTypesQuery} from "../../../../../Api/lensTypesApi.js"; import {useGetLensTypesQuery} from "../../../../../../../Api/lensTypesApi.js";
import {useGetSetContentQuery} from "../../../../../Api/setContentApi.js"; import {useGetSetContentQuery} from "../../../../../../../Api/setContentApi.js";
const useSetFormModal = (setData) => { const useSetForm = (setData) => {
const {data: lensTypes = [], isLoading: isLoadingLensTypes, isError: isErrorLensTypes} = const {data: lensTypes = [], isLoading: isLoadingLensTypes, isError: isErrorLensTypes} =
useGetLensTypesQuery(undefined); useGetLensTypesQuery(undefined);
@ -24,4 +24,4 @@ const useSetFormModal = (setData) => {
}; };
}; };
export default useSetFormModal; export default useSetForm;

View File

@ -2,7 +2,7 @@ import {Form, notification} from "antd";
import {useEffect, useState} from "react"; 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 [form] = Form.useForm();
const [currentContent, setCurrentContent] = useState([]); const [currentContent, setCurrentContent] = useState([]);
@ -112,4 +112,4 @@ const useSetFormModalUI = (visible, onCancel, setData, onSubmit, content, lensTy
}; };
}; };
export default useSetFormModalUI; export default useSetFormUI;

View File

@ -1,15 +1,15 @@
import {FloatButton, Input, List, Result, Row, Typography} from "antd"; import {FloatButton, Input, List, Result, Row, Typography} from "antd";
import {PlusOutlined, SwitcherOutlined} from "@ant-design/icons"; 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 SetFormModal from "./Components/SetFormModal/SetFormModal.jsx";
import LoadingIndicator from "../../Widgets/LoadingIndicator.jsx"; import LoadingIndicator from "../../../../Widgets/LoadingIndicator.jsx";
import useSets from "./useSets.js"; import useSets from "./useSets.js";
import useSetsUI from "./useSetsUI.js"; import useSetsUI from "./useSetsUI.js";
const {Title} = Typography; const {Title} = Typography;
const SetsPage = () => { const SetsTab = () => {
const setsData = useSets(); const setsData = useSets();
const setsUI = useSetsUI(setsData.sets); const setsUI = useSetsUI(setsData.sets);
@ -79,4 +79,4 @@ const SetsPage = () => {
); );
}; };
export default SetsPage; export default SetsTab;

View File

@ -5,9 +5,9 @@ import {
useDeleteSetMutation, useDeleteSetMutation,
useGetSetsQuery, useGetSetsQuery,
useUpdateSetMutation useUpdateSetMutation
} from "../../../Api/setsApi.js"; } from "../../../../../Api/setsApi.js";
import {closeModal} from "../../../Redux/Slices/setsSlice.js"; import {closeModal} from "../../../../../Redux/Slices/setsSlice.js";
import {useAddSetContentMutation, useUpdateSetContentMutation} from "../../../Api/setContentApi.js"; import {useAddSetContentMutation, useUpdateSetContentMutation} from "../../../../../Api/setContentApi.js";
const useSets = () => { const useSets = () => {

View File

@ -7,7 +7,7 @@ import {
setCurrentPage, setCurrentPage,
setPageSize, setPageSize,
setSearchText setSearchText
} from "../../../Redux/Slices/setsSlice.js"; } from "../../../../../Redux/Slices/setsSlice.js";
const useSetsUI = (sets) => { const useSetsUI = (sets) => {

View File

@ -1,27 +1,27 @@
import { import {
Tabs Tabs
} from "antd"; } from "antd";
import LensesPage from "../Pages/LensesPage/LensesPage.jsx"; import LensesTab from "./Components/LensesTab/LensesTab.jsx";
import {FolderViewOutlined, SwitcherOutlined} from "@ant-design/icons"; import {FolderViewOutlined, SwitcherOutlined} from "@ant-design/icons";
import SetsPage from "../Pages/SetsPage/SetsPage.jsx"; import SetsTab from "./Components/SetsTab/SetsTab.jsx";
const items = [ const items = [
{ {
key: '1', key: '1',
label: 'Линзы', label: 'Линзы',
children: <LensesPage/>, children: <LensesTab/>,
icon: <FolderViewOutlined/> icon: <FolderViewOutlined/>
}, },
{ {
key: '2', key: '2',
label: 'Наборы линз', label: 'Наборы линз',
children: <SetsPage/>, children: <SetsTab/>,
icon: <SwitcherOutlined/> icon: <SwitcherOutlined/>
} }
] ]
const LensesLayout = () => { const LensesSetsPage = () => {
return ( return (
<Tabs <Tabs
defaultActiveKey="1" defaultActiveKey="1"
@ -30,4 +30,4 @@ const LensesLayout = () => {
); );
}; };
export default LensesLayout; export default LensesSetsPage;

View File

@ -1,6 +1,6 @@
import {Form, Input, Button, Row, Col, Typography} from 'antd'; import {Form, Input, Button, Row, Col, Typography} from 'antd';
import {useEffect, useState} from 'react'; import {useEffect, useState} from 'react';
import {useAuth} from "../../Hooks/AuthContext.jsx"; import {useAuth} from "../../../Hooks/AuthContext.jsx";
import {useNavigate} from "react-router-dom"; import {useNavigate} from "react-router-dom";
const {Title} = Typography; const {Title} = Typography;

View File

@ -4,12 +4,12 @@ import locale from "antd/es/date-picker/locale/ru_RU";
import {MaskedInput} from "antd-mask-input"; import {MaskedInput} from "antd-mask-input";
import dayjs from "dayjs"; import dayjs from "dayjs";
import {PatientPropType} from "../../../../../Types/patientPropType.js"; import {PatientPropType} from "../../../../../Types/patientPropType.js";
import usePatientFormModalUI from "./usePatientFormModalUI.js"; import usePatientFormUI from "./usePatientFormUI.js";
const {TextArea} = Input; const {TextArea} = Input;
const PatientFormModal = ({visible, onCancel, onSubmit, patient}) => { const PatientFormModal = ({visible, onCancel, onSubmit, patient}) => {
const patientFormModalUI = usePatientFormModalUI(visible, onCancel, onSubmit, patient); const patientFormModalUI = usePatientFormUI(visible, onCancel, onSubmit, patient);
return ( return (
<Modal <Modal

View File

@ -4,7 +4,7 @@ import dayjs from "dayjs";
import validator from "validator"; import validator from "validator";
const usePatientFormModalUI = (visible, onCancel, onSubmit, patient) => { const usePatientFormUI = (visible, onCancel, onSubmit, patient) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
useEffect(() => { useEffect(() => {
@ -65,4 +65,4 @@ const usePatientFormModalUI = (visible, onCancel, onSubmit, patient) => {
} }
}; };
export default usePatientFormModalUI; export default usePatientFormUI;

View File

@ -1,5 +1,5 @@
import {useEffect, useRef, useState} from "react"; 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 dayjs from "dayjs";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {AppointmentPropType} from "../../Types/appointmentPropType.js"; import {AppointmentPropType} from "../../Types/appointmentPropType.js";
@ -38,6 +38,7 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC
{appointments.map(app => ( {appointments.map(app => (
<Col <Col
key={app.id} key={app.id}
style={{overflowX: 'hidden'}}
> >
<Tooltip <Tooltip
title={`Прошедший прием: ${dayjs(app.appointment_datetime).format('HH:mm')}`} title={`Прошедший прием: ${dayjs(app.appointment_datetime).format('HH:mm')}`}
@ -48,11 +49,11 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC
e.stopPropagation(); e.stopPropagation();
onItemClick(app); onItemClick(app);
}} }}
style={{margin: '2px 0', cursor: 'pointer'}} style={{margin: '2px 2px 0 0', cursor: 'pointer', width: "95%", minHeight: 30}}
> >
<Badge <Badge
status="success" status="success"
text={dayjs(app.appointment_datetime).format('HH:mm')} text={dayjs(app.scheduled_datetime).format('HH:mm') + ` ${app.patient.last_name} ${app.patient.first_name} `}
/> />
</Tag> </Tag>
</Tooltip> </Tooltip>
@ -61,6 +62,7 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC
{scheduledAppointments.map(app => ( {scheduledAppointments.map(app => (
<Col <Col
key={app.id} key={app.id}
style={{overflowX: 'hidden'}}
> >
<Tooltip <Tooltip
title={`Запланированный прием: ${dayjs(app.scheduled_datetime).format('HH:mm')}`} title={`Запланированный прием: ${dayjs(app.scheduled_datetime).format('HH:mm')}`}
@ -71,11 +73,11 @@ const CalendarCell = ({appointments, scheduledAppointments, onCellClick, onItemC
e.stopPropagation(); e.stopPropagation();
onItemClick(app); onItemClick(app);
}} }}
style={{margin: '2px 0', cursor: 'pointer'}} style={{margin: '2px 2px 0 0', cursor: 'pointer', width: "95%", minHeight: 30}}
> >
<Badge <Badge
status="processing" status="processing"
text={dayjs(app.scheduled_datetime).format('HH:mm')} text={dayjs(app.scheduled_datetime).format('HH:mm') + ` ${app.patient.last_name} ${app.patient.first_name}`}
/> />
</Tag> </Tag>
</Tooltip> </Tooltip>

View File

@ -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;

View File

@ -9,6 +9,8 @@ import {setContentApi} from "../Api/setContentApi.js";
import {lensIssuesApi} from "../Api/lensIssuesApi.js"; import {lensIssuesApi} from "../Api/lensIssuesApi.js";
import lensIssuesReducer from "./Slices/lensIssuesSlice.js"; import lensIssuesReducer from "./Slices/lensIssuesSlice.js";
import {lensTypesApi} from "../Api/lensTypesApi.js"; import {lensTypesApi} from "../Api/lensTypesApi.js";
import {appointmentsApi} from "../Api/appointmentsApi.js";
import appointmentsReducer from "./Slices/appointmentsSlice.js";
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
@ -27,6 +29,9 @@ export const store = configureStore({
[lensIssuesApi.reducerPath]: lensIssuesApi.reducer, [lensIssuesApi.reducerPath]: lensIssuesApi.reducer,
lensIssuesUI: lensIssuesReducer, lensIssuesUI: lensIssuesReducer,
[appointmentsApi.reducerPath]: appointmentsApi.reducer,
appointmentsUI: appointmentsReducer,
}, },
middleware: (getDefaultMiddleware) => ( middleware: (getDefaultMiddleware) => (
getDefaultMiddleware().concat( getDefaultMiddleware().concat(
@ -36,8 +41,9 @@ export const store = configureStore({
setContentApi.middleware, setContentApi.middleware,
lensTypesApi.middleware, lensTypesApi.middleware,
lensIssuesApi.middleware, lensIssuesApi.middleware,
appointmentsApi.middleware,
) )
) ),
}); });
export default store; export default store;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;