создал пустые страницы для линз и главную. изменил загрузку страницы пациентов, сделал список пациента в виде адаптивной сетки
This commit is contained in:
parent
1da1b70d5e
commit
e2c4a0b944
37
api/app/application/lenses_repository.py
Normal file
37
api/app/application/lenses_repository.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from sqlalchemy import select
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.domain.models import Lens
|
||||||
|
|
||||||
|
|
||||||
|
class LensesRepository:
|
||||||
|
def __init__(self, db: AsyncSession):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
async def get_all(self):
|
||||||
|
stmt = select(Lens)
|
||||||
|
result = await self.db.execute(stmt)
|
||||||
|
return result.scalars().all()
|
||||||
|
|
||||||
|
async def create(self, lens: Lens):
|
||||||
|
self.db.add(lens)
|
||||||
|
await self.db.commit()
|
||||||
|
await self.db.refresh(lens)
|
||||||
|
return lens
|
||||||
|
|
||||||
|
async def update(self, lens: Lens):
|
||||||
|
await self.db.merge(lens)
|
||||||
|
await self.db.commit()
|
||||||
|
return lens
|
||||||
|
|
||||||
|
async def delete(self, lens_id: int):
|
||||||
|
stmt = select(Lens).filter(Lens.id == lens_id)
|
||||||
|
result = await self.db.execute(stmt)
|
||||||
|
lens = result.scalars().first()
|
||||||
|
|
||||||
|
if lens:
|
||||||
|
await self.db.delete(lens)
|
||||||
|
await self.db.commit()
|
||||||
|
return lens
|
||||||
|
|
||||||
|
return None
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
"""добавил признак выдачи у линз
|
||||||
|
|
||||||
|
Revision ID: c0997c6bf2f1
|
||||||
|
Revises: 463487eaaa57
|
||||||
|
Create Date: 2025-02-13 20:35:52.618925
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = 'c0997c6bf2f1'
|
||||||
|
down_revision: Union[str, None] = '463487eaaa57'
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('lens', sa.Column('issued', sa.Boolean(), nullable=False))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('lens', 'issued')
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -1,5 +1,5 @@
|
|||||||
from enum import Enum as PyEnum
|
from enum import Enum as PyEnum
|
||||||
from sqlalchemy import Column, Integer, ForeignKey, Float, Enum
|
from sqlalchemy import Column, Integer, ForeignKey, Float, Enum, Boolean
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
from app.domain.models import Base
|
from app.domain.models import Base
|
||||||
@ -22,6 +22,7 @@ class Lens(Base):
|
|||||||
diameter = Column(Float, nullable=False)
|
diameter = Column(Float, nullable=False)
|
||||||
periphery_toricity = Column(Float, nullable=False) # Торичность перефирии
|
periphery_toricity = Column(Float, nullable=False) # Торичность перефирии
|
||||||
side = Column(Enum(SideEnum), nullable=False)
|
side = Column(Enum(SideEnum), nullable=False)
|
||||||
|
issued = Column(Boolean, nullable=False, default=False)
|
||||||
|
|
||||||
type_id = Column(Integer, ForeignKey('lenses_types.id'), nullable=False)
|
type_id = Column(Integer, ForeignKey('lenses_types.id'), nullable=False)
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@ 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";
|
import PatientsPage from "./pages/PatientsPage.jsx";
|
||||||
|
import HomePage from "./pages/HomePage.jsx";
|
||||||
|
import LensPage from "./pages/LensPage.jsx";
|
||||||
|
|
||||||
|
|
||||||
const AppRouter = () => (
|
const AppRouter = () => (
|
||||||
@ -12,7 +14,8 @@ 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={"/"} element={<p>1234</p>}/>
|
<Route path={"/lenses"} element={<LensPage/>}/>
|
||||||
|
<Route path={"/"} element={<HomePage/>}/>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path={"*"} element={<Navigate to={"/"}/>}/>
|
<Route path={"*"} element={<Navigate to={"/"}/>}/>
|
||||||
|
|||||||
12
web-app/src/pages/HomePage.jsx
Normal file
12
web-app/src/pages/HomePage.jsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const HomePage = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HomePage;
|
||||||
11
web-app/src/pages/LensPage.jsx
Normal file
11
web-app/src/pages/LensPage.jsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const LensPage = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LensPage;
|
||||||
@ -16,7 +16,6 @@ const PatientsPage = () => {
|
|||||||
const [searchText, setSearchText] = useState("");
|
const [searchText, setSearchText] = useState("");
|
||||||
const [sortOrder, setSortOrder] = useState("asc");
|
const [sortOrder, setSortOrder] = useState("asc");
|
||||||
const [patients, setPatients] = useState([]);
|
const [patients, setPatients] = useState([]);
|
||||||
const [error, setError] = useState(null);
|
|
||||||
|
|
||||||
const [current, setCurrent] = useState(1);
|
const [current, setCurrent] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(10);
|
const [pageSize, setPageSize] = useState(10);
|
||||||
@ -38,8 +37,8 @@ const PatientsPage = () => {
|
|||||||
try {
|
try {
|
||||||
const data = await getAllPatients(user.token);
|
const data = await getAllPatients(user.token);
|
||||||
setPatients(data);
|
setPatients(data);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
setError(err.message);
|
console.log(error);
|
||||||
notification.error({
|
notification.error({
|
||||||
message: "Ошибка загрузки данных",
|
message: "Ошибка загрузки данных",
|
||||||
description: "Проверьте подключение к сети.",
|
description: "Проверьте подключение к сети.",
|
||||||
@ -53,7 +52,13 @@ const PatientsPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filteredPatients = patients
|
const filteredPatients = patients
|
||||||
.filter((patient) => `${patient.first_name} ${patient.last_name}`.toLowerCase().includes(searchText.toLowerCase()))
|
.filter((patient) => {
|
||||||
|
const searchLower = searchText.toLowerCase();
|
||||||
|
|
||||||
|
return Object.values(patient)
|
||||||
|
.filter(value => typeof value === "string")
|
||||||
|
.some(value => value.toLowerCase().includes(searchLower));
|
||||||
|
})
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const fullNameA = `${a.last_name} ${a.first_name}`;
|
const fullNameA = `${a.last_name} ${a.first_name}`;
|
||||||
const fullNameB = `${b.last_name} ${b.first_name}`;
|
const fullNameB = `${b.last_name} ${b.first_name}`;
|
||||||
@ -81,8 +86,8 @@ const PatientsPage = () => {
|
|||||||
description: "Пациент успешно удалён из базы.",
|
description: "Пациент успешно удалён из базы.",
|
||||||
placement: "topRight",
|
placement: "topRight",
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
setError(err.message);
|
console.log(error);
|
||||||
notification.error({
|
notification.error({
|
||||||
message: "Ошибка удаления",
|
message: "Ошибка удаления",
|
||||||
description: "Не удалось удалить пациента.",
|
description: "Не удалось удалить пациента.",
|
||||||
@ -133,6 +138,7 @@ const PatientsPage = () => {
|
|||||||
placeholder="Поиск пациента"
|
placeholder="Поиск пациента"
|
||||||
onChange={(e) => setSearchText(e.target.value)}
|
onChange={(e) => setSearchText(e.target.value)}
|
||||||
style={{width: "100%"}}
|
style={{width: "100%"}}
|
||||||
|
allowClear
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={8}>
|
<Col xs={24} sm={8}>
|
||||||
@ -148,10 +154,24 @@ const PatientsPage = () => {
|
|||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<Spin indicator={<LoadingOutlined style={{fontSize: 48}} spin/>}/>
|
<div style={{
|
||||||
) : (
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100vh",
|
||||||
|
}}>
|
||||||
|
<Spin indicator={<LoadingOutlined style={{fontSize: 64, color: "#1890ff"}} spin/>}/>
|
||||||
|
</div>) : (
|
||||||
<List
|
<List
|
||||||
grid={{gutter: 16, column: 1}}
|
grid={{
|
||||||
|
gutter: 16,
|
||||||
|
xs: 1,
|
||||||
|
sm: 1,
|
||||||
|
md: 2,
|
||||||
|
lg: 2,
|
||||||
|
xl: 3,
|
||||||
|
xxl: 3,
|
||||||
|
}}
|
||||||
dataSource={filteredPatients}
|
dataSource={filteredPatients}
|
||||||
renderItem={(patient) => (
|
renderItem={(patient) => (
|
||||||
<List.Item>
|
<List.Item>
|
||||||
@ -167,6 +187,10 @@ const PatientsPage = () => {
|
|||||||
pageSize,
|
pageSize,
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
pageSizeOptions: ["5", "10", "20", "50"],
|
pageSizeOptions: ["5", "10", "20", "50"],
|
||||||
|
onChange: (page, newPageSize) => {
|
||||||
|
setCurrent(page);
|
||||||
|
setPageSize(newPageSize);
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user