сделал заготовку для страницы с приемами

This commit is contained in:
Андрей Дувакин 2025-03-16 16:05:27 +05:00
parent 99fbca72fe
commit 42a46af783
11 changed files with 174 additions and 37 deletions

View File

@ -6,7 +6,7 @@ import PatientsPage from "./pages/PatientsPage.jsx";
import HomePage from "./pages/HomePage.jsx";
import LensesLayout from "./layouts/LensesLayout.jsx";
import IssuesPage from "./pages/IssuesPage.jsx";
import AppointmentsPage from "./pages/AppointmentsPage.jsx";
import AppointmentsLayout from "./layouts/AppointmentsLayout.jsx";
const AppRouter = () => (
@ -18,7 +18,7 @@ const AppRouter = () => (
<Route path={"/patients"} element={<PatientsPage/>}/>
<Route path={"/lenses"} element={<LensesLayout/>}/>
<Route path={"/issues"} element={<IssuesPage/>}/>
<Route path={"/appointments"} element={<AppointmentsPage/>}/>
<Route path={"/appointments"} element={<AppointmentsLayout/>}/>
<Route path={"/"} element={<HomePage/>}/>
</Route>
</Route>

View File

@ -0,0 +1,21 @@
import axios from "axios";
import CONFIG from "../../core/Config.jsx";
const getAllAppointments = async (token) => {
try {
const response = await axios.get(`${CONFIG.BASE_URL}/appointments/`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.data;
} catch (error) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь неайден или токен недействителен");
}
throw new Error(error.message);
}
};
export default getAllAppointments;

View File

@ -3,8 +3,6 @@ import {Card, Modal, Popconfirm, Tooltip} from "antd";
import {DeleteOutlined, EditOutlined, PlusOutlined} from "@ant-design/icons";
const SetListCard = ({set, handleEditSet, handleDeleteSet, handleAppendSet}) => {
const deleteSet = () => {
handleDeleteSet(set.id);
};

View File

@ -0,0 +1,34 @@
import {useAuth} from "../AuthContext.jsx";
import {useEffect, useState} from "react";
import getAllAppointments from "../api/appointments/GetAllAppointments.jsx";
import {notification, Tabs} from "antd";
import AppointmentsCalendarPage from "../pages/appointments_layout/AppointmentsCalendarPage.jsx";
import {CalendarOutlined, TableOutlined} from "@ant-design/icons";
import AppointmentsTablePage from "../pages/appointments_layout/AppointmentsTablePage.jsx";
const AppointmentsLayout = () => {
const items = [
{
key: '1',
label: 'Календарь приемов',
children: <AppointmentsCalendarPage/>,
icon: <CalendarOutlined/>,
},
{
key: '2',
label: 'Таблица приемов',
children: <AppointmentsTablePage/>,
icon: <TableOutlined/>,
}
]
return (
<Tabs
defaultActiveKey="1"
items={items}
/>
);
};
export default AppointmentsLayout;

View File

@ -1,9 +1,9 @@
import {
Tabs
} from "antd";
import LensesPage from "../pages/LensesPage.jsx";
import LensesPage from "../pages/lenses_layout/LensesPage.jsx";
import {FolderViewOutlined, SwitcherOutlined} from "@ant-design/icons";
import SetLensesPage from "../pages/SetLensesPage.jsx";
import SetLensesPage from "../pages/lenses_layout/SetLensesPage.jsx";
const items = [

View File

@ -1,11 +0,0 @@
const AppointmentsPage = () => {
return (
<>
</>
)
};
export default AppointmentsPage;

View File

@ -75,8 +75,6 @@ const PatientsPage = () => {
};
const fetchPatients = async () => {
if (!user || !user.token) return;
try {
const data = await getAllPatients(user.token);
setPatients(data);

View File

@ -0,0 +1,25 @@
import {Calendar, Grid} from "antd";
import {useState} from "react";
import dayjs from "dayjs";
const {useBreakpoint} = Grid;
const AppointmentsCalendarPage = () => {
const screens = useBreakpoint();
const [selectedDate, setSelectedDate] = useState(dayjs(
new Date()
));
return (
<div style={{padding: 20}}>
<Calendar
fullscreen={!screens.xs}
value={selectedDate}
onSelect={setSelectedDate}
/>
</div>
);
};
export default AppointmentsCalendarPage;

View File

@ -0,0 +1,72 @@
import {useAuth} from "../../AuthContext.jsx";
import {useEffect, useState} from "react";
import getAllAppointments from "../../api/appointments/GetAllAppointments.jsx";
import {notification} from "antd";
const AppointmentsTablePage = () => {
const {user} = useAuth();
const [appointments, setAppointments] = useState([]);
const [current, setCurrent] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [isModalVisible, setIsModalVisible] = useState(false);
const [selectedAppointment, setSelectedAppointment] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchAppointmentsWithCache();
document.title = "Приемы";
}, []);
useEffect(() => {
if (!isModalVisible && !selectedAppointment) {
const intervalId = setInterval(fetchAppointments, 5000);
return () => clearInterval(intervalId);
}
}, [user, isModalVisible, selectedAppointment]);
const fetchAppointmentsWithCache = async () => {
const cachedData = localStorage.getItem("appointmentsData");
const cacheTimestamp = localStorage.getItem("appointmentsTimestamp");
const currentTime = Date.now();
if (cachedData && currentTime - cacheTimestamp < 60000) {
setAppointments(JSON.parse(cachedData));
setLoading(false);
return;
}
await fetchAppointments();
};
const fetchAppointments = async () => {
try {
const data = await getAllAppointments(user.token);
setAppointments(data);
localStorage.setItem("appointmentsData", JSON.stringify(data));
localStorage.setItem("appointmentsTimestamp", Date.now().toString());
} catch (error) {
console.log(error);
notification.error({
message: "Ошибка загрузки данных",
description: "Проверьте подключение к сети.",
placement: "topRight",
})
}
if (loading) {
setLoading(false);
}
};
return (
<div style={{padding: 20}}>
</div>
);
};
export default AppointmentsTablePage;

View File

@ -26,14 +26,14 @@ import {
TableOutlined,
BuildOutlined
} from "@ant-design/icons";
import LensCard from "../components/lenses/LensListCard.jsx";
import getAllLenses from "../api/lenses/GetAllLenses.jsx";
import addLens from "../api/lenses/AddLens.jsx";
import updateLens from "../api/lenses/UpdateLens.jsx";
import deleteLens from "../api/lenses/DeleteLens.jsx";
import {useAuth} from "../AuthContext.jsx";
import LensFormModal from "../components/lenses/LensFormModal.jsx";
import SelectViewMode from "../components/SelectViewMode.jsx";
import LensCard from "../../components/lenses/LensListCard.jsx";
import getAllLenses from "../../api/lenses/GetAllLenses.jsx";
import addLens from "../../api/lenses/AddLens.jsx";
import updateLens from "../../api/lenses/UpdateLens.jsx";
import deleteLens from "../../api/lenses/DeleteLens.jsx";
import {useAuth} from "../../AuthContext.jsx";
import LensFormModal from "../../components/lenses/LensFormModal.jsx";
import SelectViewMode from "../../components/SelectViewMode.jsx";
const {Option} = Select;
const {useBreakpoint} = Grid;

View File

@ -1,16 +1,16 @@
import {useAuth} from "../AuthContext.jsx";
import {useAuth} from "../../AuthContext.jsx";
import {useEffect, useState} from "react";
import {FloatButton, Input, List, notification, Row, Spin, Typography} from "antd";
import getAllSets from "../api/sets/GetAllSets.jsx";
import getAllSets from "../../api/sets/GetAllSets.jsx";
import {LoadingOutlined, PlusOutlined, SwitcherOutlined} from "@ant-design/icons";
import SetListCard from "../components/sets/SetListCard.jsx";
import SetFormModal from "../components/sets/SetFormModal.jsx";
import updateSet from "../api/sets/UpdateSet.jsx";
import addSet from "../api/sets/AddSet.jsx";
import deleteSet from "../api/sets/DeleteSet.jsx";
import addSetContent from "../api/set_content/AddSetContent.jsx";
import updateSetContent from "../api/set_content/UpdateSetContent.jsx";
import appendLensesFromSet from "../api/sets/AppendLensesFromSet.jsx";
import SetListCard from "../../components/sets/SetListCard.jsx";
import SetFormModal from "../../components/sets/SetFormModal.jsx";
import updateSet from "../../api/sets/UpdateSet.jsx";
import addSet from "../../api/sets/AddSet.jsx";
import deleteSet from "../../api/sets/DeleteSet.jsx";
import addSetContent from "../../api/set_content/AddSetContent.jsx";
import updateSetContent from "../../api/set_content/UpdateSetContent.jsx";
import appendLensesFromSet from "../../api/sets/AppendLensesFromSet.jsx";
const {Title} = Typography;