Полноценно редактируются черновики

Добавляются фасовки как в черновике, так и в обучении
Исправил внешний вид
This commit is contained in:
2025-12-17 22:00:21 +03:00
parent e2df2350f7
commit c8aab42e8e
24 changed files with 1313 additions and 433 deletions

View File

@@ -1,57 +1,86 @@
import React from 'react';
import { Layout, Menu, theme } from 'antd';
import { Layout, theme } from 'antd';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import { BarChartOutlined, ScanOutlined, FileTextOutlined } from '@ant-design/icons';
import { ScanOutlined, FileTextOutlined, SettingOutlined } from '@ant-design/icons';
const { Header, Content, Footer } = Layout;
const { Content } = Layout;
export const AppLayout: React.FC = () => {
const navigate = useNavigate();
const location = useLocation();
// Получаем токены темы (чтобы подстроить AntD под Telegram можно позже настроить ConfigProvider)
const {
token: { colorBgContainer, borderRadiusLG },
token: { colorBgContainer, colorPrimary, colorTextSecondary },
} = theme.useToken();
// Определяем активный пункт меню
const selectedKey = location.pathname === '/' ? 'dashboard'
: location.pathname.startsWith('/ocr') ? 'ocr'
: location.pathname.startsWith('/invoices') ? 'invoices'
: 'dashboard';
const path = location.pathname;
let activeKey = 'invoices';
if (path.startsWith('/ocr')) activeKey = 'ocr';
else if (path.startsWith('/settings')) activeKey = 'settings';
const menuItems = [
{ key: 'dashboard', icon: <BarChartOutlined />, label: 'Дашборд', onClick: () => navigate('/') },
{ key: 'ocr', icon: <ScanOutlined />, label: 'Обучение', onClick: () => navigate('/ocr') },
{ key: 'invoices', icon: <FileTextOutlined />, label: 'Накладные', onClick: () => navigate('/invoices') },
{ key: 'invoices', icon: <FileTextOutlined style={{ fontSize: 20 }} />, label: 'Накладные', path: '/invoices' },
{ key: 'ocr', icon: <ScanOutlined style={{ fontSize: 20 }} />, label: 'Обучение', path: '/ocr' },
{ key: 'settings', icon: <SettingOutlined style={{ fontSize: 20 }} />, label: 'Настройки', path: '#' },
];
return (
<Layout style={{ minHeight: '100vh' }}>
<Header style={{ display: 'flex', alignItems: 'center', padding: 0 }}>
<Menu
theme="dark"
mode="horizontal"
selectedKeys={[selectedKey]}
items={menuItems}
style={{ flex: 1, minWidth: 0 }}
/>
</Header>
<Content style={{ padding: '16px' }}>
<Layout style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column' }}>
{/* Верхнюю шапку (Header) удалили для экономии места */}
<Content style={{ padding: '0', flex: 1, overflowY: 'auto', marginBottom: 60 }}>
{/* Убрали лишние паддинги вокруг контента для мобилок */}
<div
style={{
background: colorBgContainer,
minHeight: 280,
padding: 24,
borderRadius: borderRadiusLG,
minHeight: '100%',
padding: '12px 12px 80px 12px', // Добавили отступ снизу, чтобы контент не перекрывался меню
borderRadius: 0, // На мобильных скругления углов всего экрана обычно не нужны
}}
>
<Outlet />
</div>
</Content>
<Footer style={{ textAlign: 'center', padding: '12px 0' }}>
RMSer ©{new Date().getFullYear()}
</Footer>
{/* Нижний Таб-бар */}
<div style={{
position: 'fixed',
bottom: 0,
width: '100%',
zIndex: 1000,
background: '#fff',
borderTop: '1px solid #f0f0f0',
display: 'flex',
justifyContent: 'space-around',
alignItems: 'center',
padding: '8px 0',
height: 60,
boxShadow: '0 -2px 8px rgba(0,0,0,0.05)'
}}>
{menuItems.map(item => {
const isActive = activeKey === item.key;
return (
<div
key={item.key}
onClick={() => navigate(item.path)}
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '33%',
cursor: 'pointer',
color: isActive ? colorPrimary : colorTextSecondary
}}
>
{item.icon}
<span style={{ fontSize: 10, marginTop: 2, fontWeight: isActive ? 500 : 400 }}>
{item.label}
</span>
</div>
);
})}
</div>
</Layout>
);
};