diff --git a/frontend/src/app/providers/layout/layout.tsx b/frontend/src/app/providers/layout/layout.tsx
index 4210ac4..8a54aea 100644
--- a/frontend/src/app/providers/layout/layout.tsx
+++ b/frontend/src/app/providers/layout/layout.tsx
@@ -4,9 +4,34 @@ import { Navigation } from "@/app/providers/layout/navigation/navigation";
import { useAgentStore } from "@/app/providers/layout/store/agent.store";
export const Layout = ({ children }: { children: ReactNode }) => {
- const [isOpen, setOpen] = useState(true);
+ const [mobileOpen, setMobileOpen] = useState(false);
+ const [isMobile, setIsMobile] = useState(() =>
+ typeof window !== "undefined" ? window.innerWidth < 856 : false,
+ );
const { fetchAgents } = useAgentStore();
+ const sidebarOpen = isMobile ? mobileOpen : true;
+
+ useEffect(() => {
+ const handleResize = () => {
+ const mobile = window.innerWidth < 856;
+ setIsMobile(mobile);
+ if (!mobile) {
+ setMobileOpen(false);
+ }
+ };
+
+ window.addEventListener("resize", handleResize);
+ handleResize();
+ return () => window.removeEventListener("resize", handleResize);
+ }, []);
+
+ const toggleSidebar = () => {
+ if (isMobile) {
+ setMobileOpen((prev) => !prev);
+ }
+ };
+
useEffect(() => {
fetchAgents();
}, [fetchAgents]);
@@ -20,10 +45,17 @@ export const Layout = ({ children }: { children: ReactNode }) => {
}, [fetchAgents]);
return (
-
-
setOpen(!isOpen)} />
+
diff --git a/frontend/src/app/providers/layout/navigation/navigation.tsx b/frontend/src/app/providers/layout/navigation/navigation.tsx
index a081579..289c62c 100644
--- a/frontend/src/app/providers/layout/navigation/navigation.tsx
+++ b/frontend/src/app/providers/layout/navigation/navigation.tsx
@@ -1,6 +1,6 @@
import { useState, useRef, useEffect } from "react";
import { useNavigate, useLocation } from "react-router-dom";
-import { FaCode, FaChevronDown } from "react-icons/fa";
+import { FaBars, FaCode, FaChevronDown } from "react-icons/fa";
import {
FaHome,
FaServer,
@@ -21,7 +21,15 @@ import {
getCurrentTheme,
} from "@/modules/theme-changer/utils/apply.theme";
-export const Navigation = () => {
+interface NavigationProps {
+ onToggleSidebar?: () => void;
+ isMobile?: boolean;
+}
+
+export const Navigation: React.FC = ({
+ onToggleSidebar,
+ isMobile,
+}) => {
const navigate = useNavigate();
const location = useLocation();
const { user, logout } = useAuthStore();
@@ -75,6 +83,22 @@ export const Navigation = () => {
}}
>
+ {/* Бургер — только на мобильных */}
+ {isMobile && (
+
+ )}
+
{/* Навигация */}
diff --git a/frontend/src/app/providers/layout/sidebar/sidebar.tsx b/frontend/src/app/providers/layout/sidebar/sidebar.tsx
index 763cf74..6064324 100644
--- a/frontend/src/app/providers/layout/sidebar/sidebar.tsx
+++ b/frontend/src/app/providers/layout/sidebar/sidebar.tsx
@@ -1,4 +1,4 @@
-import React, { useMemo, useState } from "react";
+import React, { useMemo, useState, useRef, useEffect } from "react";
import {
FaBars,
FaMicrochip,
@@ -21,11 +21,13 @@ import { adminApi } from "@/modules/admin/api/admin.api";
interface SidebarProps {
isOpen?: boolean;
onToggle?: () => void;
+ isMobile?: boolean;
}
export const Sidebar: React.FC
= ({
isOpen = true,
onToggle,
+ isMobile = false,
}) => {
const navigate = useNavigate();
const { agents, isLoading, error, fetchAgents, removeAgent } =
@@ -35,10 +37,26 @@ export const Sidebar: React.FC = ({
const [copied, setCopied] = useState(false);
const [showTokenModal, setShowTokenModal] = useState(false);
const [showGraphs, setShowGraphs] = useState(false);
+ const [sidebarWidth, setSidebarWidth] = useState(288);
+ const sidebarRef = useRef(null);
const [expandedAgents, setExpandedAgents] = useState>(
new Set(agents.map((a) => a.label)),
);
+ // Рассчитываем максимальную ширину при переключении на графы
+ useEffect(() => {
+ const updateWidth = () => {
+ const targetWidth = showGraphs ? 500 : 288;
+ const maxWidth = window.innerWidth - 200;
+ const finalWidth = Math.min(targetWidth, maxWidth);
+ setSidebarWidth(Math.max(finalWidth, 250));
+ };
+
+ updateWidth();
+ window.addEventListener("resize", updateWidth);
+ return () => window.removeEventListener("resize", updateWidth);
+ }, [showGraphs]);
+
// Token generation state
const [tokenLabel, setTokenLabel] = useState("");
const [generatedToken, setGeneratedToken] = useState(null);
@@ -132,35 +150,21 @@ export const Sidebar: React.FC = ({
};
if (!isOpen) {
- return (
-
- );
+ return null;
}
return (
<>
- {/* Overlay для мобильных */}
-
+ {/* Overlay — только на мобильных (< 856px) */}
+ {isMobile && (
+
+ )}