feat(web): React-фронтенд вместо Flet + fix restore rmtree на bind-mount
web-react/: SPA Vite+React+TS, nginx раздаёт статику и проксирует /api на api:8000 по локалке. docker-compose: web(Flet)->web-react на :80. transfer_crud.backup_restore: чистим содержимое data/radar вместо rmtree точки монтирования (EBUSY).
This commit is contained in:
40
web-react/src/components/Layout.tsx
Normal file
40
web-react/src/components/Layout.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { IconArrowBack, IconAccount } from "./icons";
|
||||
|
||||
// Оболочка экранов: заголовок + опциональная кнопка «назад» + кнопка профиля.
|
||||
export function Layout({
|
||||
title,
|
||||
children,
|
||||
back,
|
||||
showProfile = true,
|
||||
}: {
|
||||
title: string;
|
||||
children: ReactNode;
|
||||
back?: string; // путь для кнопки «назад»
|
||||
showProfile?: boolean;
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div className="page">
|
||||
<header className="app-header">
|
||||
<div className="row row-gap" style={{ minWidth: 0 }}>
|
||||
{back && (
|
||||
<button className="icon-btn" onClick={() => navigate(back)} aria-label="Назад">
|
||||
<IconArrowBack />
|
||||
</button>
|
||||
)}
|
||||
<span className="app-title" style={{ overflow: "hidden", textOverflow: "ellipsis" }}>
|
||||
{title}
|
||||
</span>
|
||||
</div>
|
||||
{showProfile && (
|
||||
<button className="icon-btn" onClick={() => navigate("/profile")} aria-label="Профиль">
|
||||
<IconAccount />
|
||||
</button>
|
||||
)}
|
||||
</header>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user