создал пустую страницу для преимов, изменил обработку ошибок в методах API, исправил закрывающиеся модальные окна при просмотре информации о пациенте и линзе

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

View File

@ -6,6 +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";
const AppRouter = () => (
@ -17,6 +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={"/"} element={<HomePage/>}/>
</Route>
</Route>

View File

@ -8,7 +8,7 @@ const loginUser = async (loginData) => {
});
return response.data.access_token;
} catch (error) {
if (error.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Неверное имя пользователя или пароль")
}

View File

@ -11,7 +11,7 @@ const AddLensIssue = async (token, lens_issue) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь неайден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const GetAllLensIssues = async (token) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const getAllLensTypes = async (token) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const addLens = async (token, lens) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const deleteLens = async (token, lens_id) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -10,7 +10,7 @@ const getAllLenses = async (token) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw Error("Ошибка авторизации: пользователь неяден или токен недействителен");
}
throw Error(error.message);

View File

@ -10,7 +10,7 @@ const getNotIssuedLenses = async (token) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw Error("Ошибка авторизации: пользователь неяден или токен недействителен");
}
throw Error(error.message);

View File

@ -11,7 +11,7 @@ const updateLens = async (token, lensId, lensData) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const addPatient = async (token, patient) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const deletePatient = async (token, patient_id) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const getAllPatients = async (token) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const updatePatient = async (token, patientId, patientData) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const addSetContent = async (token, set_content, set_id) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const getSetContentBySetId = async (token, set_id) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const updateSetContent = async (token, set_content, set_id) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const addSet = async (token, set) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,11 +11,10 @@ const appendLensesFromSet = async (token, set_id) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
} else {
throw new Error(error.message);
}
throw new Error(error.message);
}
};

View File

@ -10,7 +10,7 @@ const deleteSet = async (token, set_id) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -10,7 +10,7 @@ const getAllSets = async (token) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -11,7 +11,7 @@ const updateSet = async (token, set_id, set) => {
});
return response.data;
} catch (error) {
if (error.response?.status === 403) {
if (error.status === 403 || error.status === 401) {
throw new Error("Ошибка авторизации: пользователь не найден или токен недействителен");
}
throw new Error(error.message);

View File

@ -1,5 +1,5 @@
import {useState} from "react";
import {Layout, Menu} from "antd";
import {Grid, Layout, Menu} from "antd";
import {Outlet, useLocation, useNavigate} from "react-router-dom";
import {
HomeOutlined,
@ -16,8 +16,11 @@ import {useAuth} from "../AuthContext.jsx";
const {Content, Footer, Sider} = Layout;
const getItem = (label, key, icon, children) => ({key, icon, children, label});
const {useBreakpoint} = Grid;
const MainLayout = () => {
const screens = useBreakpoint();
const [collapsed, setCollapsed] = useState(true);
const navigate = useNavigate();
const location = useLocation();
@ -47,7 +50,12 @@ const MainLayout = () => {
return (
<Layout style={{minHeight: "100vh"}}>
<Sider collapsible collapsed={collapsed} onCollapse={setCollapsed} style={{height: "100vh", position: "fixed", left: 0}}>
<Sider
collapsible={!screens.xs}
collapsed={collapsed}
onCollapse={setCollapsed}
style={{height: "100vh", position: "fixed", left: 0}}
>
<div style={{display: "flex", justifyContent: "center", padding: 16}}>
<img
src="/logo_rounded.png"
@ -64,8 +72,18 @@ const MainLayout = () => {
/>
</Sider>
<Layout style={{marginLeft: collapsed ? 80 : 200, transition: "margin-left 0.2s"}}>
<Content style={{margin: "0 16px", padding: 24, minHeight: "100vh", overflow: "auto", background: "#fff", borderRadius: 8, marginTop: "15px"}}>
<Layout
style={{marginLeft: collapsed ? 80 : 200, transition: "margin-left 0.2s"}}
>
<Content style={{
margin: "0 16px",
padding: 24,
minHeight: "100vh",
overflow: "auto",
background: "#fff",
borderRadius: 8,
marginTop: "15px"
}}>
<Outlet/>
</Content>
<Footer style={{textAlign: "center"}}>Линза+ © {new Date().getFullYear()}</Footer>

View File

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

View File

@ -283,7 +283,7 @@ const IssuesPage = () => {
<Row gutter={[16, 16]} style={{marginBottom: 20}}>
<Col xs={24} md={24} sm={24} xl={12}>
<Input
placeholder="Поиск по пациенту или дате"
placeholder="Поиск по пациенту или врачу"
onChange={handleSearch}
style={{width: "100%"}}
allowClear
@ -301,6 +301,7 @@ const IssuesPage = () => {
title="Фильтр по дате выдачи линзы"
>
<DatePicker.RangePicker
allowClear={false}
style={{width: "100%"}}
placeholder={["Дата начала", "Дата окончания"]}
format="DD.MM.YYYY"

View File

@ -72,11 +72,11 @@ const LensesPage = () => {
}, []);
useEffect(() => {
if (!isModalVisible) {
if (!isModalVisible && !selectedLens) {
const intervalId = setInterval(fetchLenses, 5000);
return () => clearInterval(intervalId);
}
}, [user, isModalVisible]);
}, [user, isModalVisible, selectedLens]);
const fetchLensWithCache = async () => {
const cachedData = localStorage.getItem("lensData");
@ -107,7 +107,6 @@ const LensesPage = () => {
}
};
const fetchViewModeFromCache = () => {
const cachedViewMode = localStorage.getItem("viewModeLenses");
if (cachedViewMode) {
@ -351,7 +350,7 @@ const LensesPage = () => {
<div style={{padding: 20}}>
<Title level={1}><FolderViewOutlined/> Линзы</Title>
<Row gutter={[16, 16]} style={{marginBottom: 20}}>
<Col xs={24} md={14} sm={10} xl={16}>
<Col xs={24} md={24} sm={24} xl={15}>
<Input
placeholder="Поиск линзы"
value={searchText}
@ -360,7 +359,7 @@ const LensesPage = () => {
allowClear
/>
</Col>
<Col xs={24} md={7} sm={10} xl={4}>
<Col xs={24} md={12} sm={24} xl={5}>
<Button
onClick={toggleAdvancedSearch} icon={showAdvancedSearch ? <UpOutlined/> : <DownOutlined/>}
block
@ -368,7 +367,7 @@ const LensesPage = () => {
Расширенный поиск
</Button>
</Col>
<Col xs={24} md={4} sm={4} xl={4}>
<Col xs={24} md={12} sm={24} xl={4}>
<SelectViewMode
viewMode={viewMode}
setViewMode={setViewMode}

View File

@ -55,11 +55,11 @@ const PatientsPage = () => {
}, []);
useEffect(() => {
if (!isModalVisible) {
if (!isModalVisible && !selectedPatient) {
const intervalId = setInterval(fetchPatients, 5000);
return () => clearInterval(intervalId);
}
}, [user, isModalVisible]);
}, [user, isModalVisible, selectedPatient]);
const fetchPatientsWithCache = async () => {
const cachedData = localStorage.getItem("patientsData");
@ -359,7 +359,7 @@ const PatientsPage = () => {
} xl={
viewMode === "tile" ? 3 : 5
} xxl={
viewMode === "tile" ? 3 : 4
viewMode === "tile" ? 3 : 5
}>
<SelectViewMode
viewMode={viewMode}