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

This commit is contained in:
Андрей Дувакин 2025-02-09 21:51:48 +05:00
parent ad76dac42a
commit bb08761d84
5 changed files with 109 additions and 5 deletions

View File

@ -2,6 +2,7 @@ import {Routes, Route, Navigate} from "react-router-dom";
import PrivateRoute from "./components/PrivateRoute.jsx"; import PrivateRoute from "./components/PrivateRoute.jsx";
import LoginPage from "./pages/LoginPage.jsx"; import LoginPage from "./pages/LoginPage.jsx";
import MainLayout from "./layouts/MainLayout.jsx"; import MainLayout from "./layouts/MainLayout.jsx";
import PatientsPage from "./pages/PatientsPage.jsx";
const AppRouter = () => ( const AppRouter = () => (
@ -11,6 +12,7 @@ const AppRouter = () => (
<Route element={<PrivateRoute/>}> <Route element={<PrivateRoute/>}>
<Route element={<MainLayout/>}> <Route element={<MainLayout/>}>
<Route path={"/"} element={<p>1234</p>}/> <Route path={"/"} element={<p>1234</p>}/>
<Route path={"/patients"} element={<PatientsPage/>}/>
<Route path={"*"} element={<Navigate to={"/"}/>}/> <Route path={"*"} element={<Navigate to={"/"}/>}/>
</Route> </Route>
</Route> </Route>

View File

@ -1,6 +1,6 @@
import {createContext, useState, useContext, useEffect} from "react"; import {createContext, useState, useContext, useEffect} from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {loginUser} from "./api/LoginRequest.jsx"; import loginUser from "./api/LoginRequest.jsx";
const AuthContext = createContext(undefined); const AuthContext = createContext(undefined);

View File

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

View File

@ -1,8 +1,7 @@
import axios from "axios"; import axios from "axios";
import CONFIG from "../core/Config.jsx"; import CONFIG from "../core/Config.jsx";
export const loginUser = async (loginData) => { const loginUser = async (loginData) => {
console.log(loginData)
try { try {
const response = await axios.post(`${CONFIG.BASE_URL}/login/`, loginData, { const response = await axios.post(`${CONFIG.BASE_URL}/login/`, loginData, {
withCredentials: true, withCredentials: true,
@ -16,3 +15,5 @@ export const loginUser = async (loginData) => {
throw new Error(error.message); throw new Error(error.message);
} }
}; };
export default loginUser;

View File

@ -1,5 +1,81 @@
import {useEffect, useState} from "react";
import {Input, Select, List, Card, Button, FloatButton} from "antd";
import {PlusOutlined} from "@ant-design/icons";
import {useAuth} from "../AuthContext.jsx";
import getAllPatients from "../api/GetAllPatients.jsx";
const {Search} = Input;
const {Option} = Select;
const PatientsPage = () => { const PatientsPage = () => {
const { user } = useAuth();
const [searchText, setSearchText] = useState("");
const [sortOrder, setSortOrder] = useState("asc");
const [patients, setPatients] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
const fetchPatients = async () => {
if (!user || !user.token) return;
try {
const data = await getAllPatients(user.token);
setPatients(data);
} catch (err) {
setError(err.message);
}
};
fetchPatients();
}, [user]);
const filteredPatients = patients
.filter((patient) =>
`${patient.first_name} ${patient.last_name}`.toLowerCase().includes(searchText.toLowerCase())
)
.sort((a, b) => {
const fullNameA = `${a.last_name} ${a.first_name}`;
const fullNameB = `${b.last_name} ${b.first_name}`;
return sortOrder === "asc" ? fullNameA.localeCompare(fullNameB) : fullNameB.localeCompare(fullNameA);
});
return ( return (
) <div style={{padding: 20}}>
} <div style={{display: "flex", gap: 10, marginBottom: 20}}>
<Search
placeholder="Поиск пациента"
onChange={(e) => setSearchText(e.target.value)}
style={{flex: 1}}
/>
<Select
value={sortOrder}
onChange={(value) => setSortOrder(value)}
style={{width: 150}}
>
<Option value="asc">А-Я</Option>
<Option value="desc">Я-А</Option>
</Select>
</div>
<List
grid={{gutter: 16, column: 2}}
dataSource={filteredPatients}
renderItem={(patient) => (
<List.Item>
<Card title={`${patient.last_name} ${patient.first_name}`}>
Информация о пациенте
</Card>
</List.Item>
)}
/>
<FloatButton
icon={<PlusOutlined/>}
style={{position: "fixed", bottom: 20, right: 20}}
onClick={() => console.log("Добавить пациента")}
/>
</div>
);
};
export default PatientsPage;