diff --git a/frontend/src/app/providers/layout/navigation/navigation.tsx b/frontend/src/app/providers/layout/navigation/navigation.tsx index 14ea644..d89fe05 100644 --- a/frontend/src/app/providers/layout/navigation/navigation.tsx +++ b/frontend/src/app/providers/layout/navigation/navigation.tsx @@ -3,19 +3,24 @@ import { FaCode } from "react-icons/fa"; import { FaHome, FaServer, - FaPalette, FaUser, FaUsers, FaRocket, FaKey, FaFileAlt, + FaSun, + FaMoon, } from "react-icons/fa"; import { useAuthStore } from "@/modules/auth/store/useAuthStore"; +import { useThemeStore } from "@/modules/theme-bw/stores/theme.store"; export const Navigation = () => { const navigate = useNavigate(); const location = useLocation(); const { user, logout } = useAuthStore(); + const { toggleTheme, theme } = useThemeStore(); + + const isDark = theme === "dark"; const navItems = [ { path: "/", label: "Главная", icon: FaHome }, @@ -25,7 +30,6 @@ export const Navigation = () => { { path: "/registration", label: "Регистрация", icon: FaKey }, { path: "/logs", label: "Логи", icon: FaFileAlt }, { path: "/admin", label: "Админка", icon: FaUsers, adminOnly: true }, - { path: "/themes", label: "Темы", icon: FaPalette }, ]; const isActive = (path: string) => location.pathname === path; @@ -101,6 +105,21 @@ export const Navigation = () => { )} + + {/* Переключатель темы */} + + @@ -64,11 +94,18 @@ export const GraphContextMenu: React.FC = ({ )} {menu.link && ( <> -
+
Связь:{" "} {typeof menu.link.source === "string" ? menu.link.source - : (menu.link.source as any).name || (menu.link.source as any).id}{" "} + : (menu.link.source as any).name || + (menu.link.source as any).id}{" "} →{" "} {typeof menu.link.target === "string" ? menu.link.target @@ -76,7 +113,14 @@ export const GraphContextMenu: React.FC = ({
diff --git a/frontend/src/modules/graph/components/GraphControls.tsx b/frontend/src/modules/graph/components/GraphControls.tsx index df0b732..ff53aab 100644 --- a/frontend/src/modules/graph/components/GraphControls.tsx +++ b/frontend/src/modules/graph/components/GraphControls.tsx @@ -4,7 +4,6 @@ import { FiZoomIn, FiZoomOut, FiMove, - FiPlus, FiLink, } from "react-icons/fi"; import { useGraphStore } from "../store/useGraphStore"; @@ -16,37 +15,20 @@ interface GraphControlsProps { onDataChange?: (data: GraphData) => void; } +const btnStyle: React.CSSProperties = { + backgroundColor: "var(--bg-secondary)", + color: "var(--text-primary)", +}; + export const GraphControls: React.FC = ({ fgRef, onExport, onDataChange, }) => { const isLinkMode = useGraphStore((s) => s.isLinkMode); - const selectedNode = useGraphStore((s) => s.selectedNode); - const data = useGraphStore((s) => s.data); const toggleLinkMode = useGraphStore((s) => s.toggleLinkMode); - const addNode = useGraphStore((s) => s.addNode); const exportData = useGraphStore((s) => s.exportData); - const handleAddNode = () => { - const newNodeName = prompt( - "Введите имя узла:", - `Node ${data.nodes.length + 1}`, - ); - if (newNodeName) { - const isService = window.confirm( - "Выберите тип: OK - Сервис, Отмена - Агент", - ); - addNode({ - id: `node-${Date.now()}`, - name: newNodeName, - type: isService ? "service" : "agent", - val: isService ? 12 : 8, - description: "Новый узел", - }); - } - }; - const handleZoomIn = () => { if (fgRef.current) { const currentZoom = fgRef.current.zoom(); @@ -72,22 +54,21 @@ export const GraphControls: React.FC = ({ {/* Режим создания связи */} {/* Зум + */} @@ -95,7 +76,8 @@ export const GraphControls: React.FC = ({ {/* Зум - */} @@ -103,7 +85,8 @@ export const GraphControls: React.FC = ({ {/* Fit */} @@ -111,10 +94,11 @@ export const GraphControls: React.FC = ({ {/* Экспорт */}
); diff --git a/frontend/src/modules/graph/components/GraphStats.tsx b/frontend/src/modules/graph/components/GraphStats.tsx index f3ab918..856782d 100644 --- a/frontend/src/modules/graph/components/GraphStats.tsx +++ b/frontend/src/modules/graph/components/GraphStats.tsx @@ -7,15 +7,19 @@ interface GraphStatsProps { export const GraphStats: React.FC = ({ data }) => { return ( -
+
Сервисы: {data.nodes.filter((n) => n.type === "service").length} - - Агенты: {data.nodes.filter((n) => n.type === "agent").length} - + Агенты: {data.nodes.filter((n) => n.type === "agent").length}
-
+
Связи: {data.links.length}
diff --git a/frontend/src/modules/graph/components/GraphStatusBar.tsx b/frontend/src/modules/graph/components/GraphStatusBar.tsx index e8cbc14..f98d340 100644 --- a/frontend/src/modules/graph/components/GraphStatusBar.tsx +++ b/frontend/src/modules/graph/components/GraphStatusBar.tsx @@ -14,7 +14,10 @@ export const GraphStatusBar: React.FC = ({ if (!isLinkMode) return null; return ( -
+
Режим создания связей: кликните на два узла для соединения {selectedNode && ( Выбран: {selectedNode.name} diff --git a/frontend/src/modules/ide/IDE.tsx b/frontend/src/modules/ide/IDE.tsx index ca2214f..272fb2a 100644 --- a/frontend/src/modules/ide/IDE.tsx +++ b/frontend/src/modules/ide/IDE.tsx @@ -13,16 +13,45 @@ import { TitleBar, StatusBar, } from "./components"; +import { useThemeStore } from "@/modules/theme-bw/stores/theme.store"; interface IDEProps { initialFiles?: FileNode; onBack?: () => void; } +const darkColors = { + bg: "#1e1e1e", + bgSecondary: "#252526", + bgTertiary: "#2d2d30", + border: "#3e3e42", + textPrimary: "#cccccc", + textSecondary: "#858585", + accent: "#0e639c", + accentHover: "#1177bb", + statusBar: "#007acc", +}; + +const lightColors = { + bg: "#ffffff", + bgSecondary: "#f3f3f3", + bgTertiary: "#e8e8e8", + border: "#e0e0e0", + textPrimary: "#333333", + textSecondary: "#616161", + accent: "#0e639c", + accentHover: "#1177bb", + statusBar: "#007acc", +}; + export const IDE: React.FC = ({ initialFiles: externalFiles, onBack, }: IDEProps = {}) => { + const theme = useThemeStore((s) => s.theme); + const isDark = theme === "dark"; + const c = isDark ? darkColors : lightColors; + const files = useIDEStore((state) => state.files); const openFiles = useIDEStore((state) => state.openFiles); const activeFile = useIDEStore((state) => state.activeFile); @@ -51,7 +80,7 @@ export const IDE: React.FC = ({ height: "100vh", display: "flex", flexDirection: "column", - backgroundColor: "#1e1e1e", + backgroundColor: c.bg, fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", position: "relative", @@ -66,8 +95,8 @@ export const IDE: React.FC = ({ top: "40px", left: "12px", background: "transparent", - border: "1px solid #3e3e42", - color: "#cccccc", + border: `1px solid ${c.border}`, + color: c.textPrimary, cursor: "pointer", display: "flex", alignItems: "center", @@ -79,14 +108,14 @@ export const IDE: React.FC = ({ zIndex: 10, }} onMouseEnter={(e) => { - e.currentTarget.style.backgroundColor = "#3e3e42"; + e.currentTarget.style.backgroundColor = c.border; e.currentTarget.style.color = "#fff"; e.currentTarget.style.borderColor = "#555"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = "transparent"; - e.currentTarget.style.color = "#cccccc"; - e.currentTarget.style.borderColor = "#3e3e42"; + e.currentTarget.style.color = c.textPrimary; + e.currentTarget.style.borderColor = c.border; }} title="Go back" > @@ -117,7 +146,7 @@ export const IDE: React.FC = ({ style={{ fontSize: "22px", marginBottom: "12px", - color: "#cccccc", + color: c.textPrimary, fontWeight: 300, }} > @@ -127,7 +156,7 @@ export const IDE: React.FC = ({ style={{ fontSize: "13px", marginBottom: "32px", - color: "#858585", + color: c.textSecondary, }} > Create a new project to get started @@ -136,7 +165,7 @@ export const IDE: React.FC = ({ onClick={createNewProject} style={{ padding: "10px 24px", - backgroundColor: "#0e639c", + backgroundColor: c.accent, border: "none", borderRadius: "4px", color: "#fff", @@ -146,10 +175,10 @@ export const IDE: React.FC = ({ transition: "background-color 0.1s", }} onMouseEnter={(e) => { - e.currentTarget.style.backgroundColor = "#1177bb"; + e.currentTarget.style.backgroundColor = c.accentHover; }} onMouseLeave={(e) => { - e.currentTarget.style.backgroundColor = "#0e639c"; + e.currentTarget.style.backgroundColor = c.accent; }} > New Project @@ -168,7 +197,7 @@ export const IDE: React.FC = ({ display: "flex", flexDirection: "column", overflow: "hidden", - backgroundColor: "#1e1e1e", + backgroundColor: c.bg, fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", }} @@ -176,14 +205,14 @@ export const IDE: React.FC = ({
= ({ style={{ background: "transparent", border: "none", - color: "#cccccc", + color: c.textPrimary, cursor: "pointer", display: "flex", alignItems: "center", @@ -205,12 +234,12 @@ export const IDE: React.FC = ({ transition: "all 0.1s", }} onMouseEnter={(e) => { - e.currentTarget.style.backgroundColor = "#3e3e42"; + e.currentTarget.style.backgroundColor = c.border; e.currentTarget.style.color = "#fff"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = "transparent"; - e.currentTarget.style.color = "#cccccc"; + e.currentTarget.style.color = c.textPrimary; }} title="Go back" > diff --git a/frontend/src/modules/ide/components/FilePicker.tsx b/frontend/src/modules/ide/components/FilePicker.tsx index e6441c9..7a7bf1a 100644 --- a/frontend/src/modules/ide/components/FilePicker.tsx +++ b/frontend/src/modules/ide/components/FilePicker.tsx @@ -57,6 +57,7 @@ export const FilePicker: React.FC = ({ files }) => { style={{ height: "100%", overflowY: "auto", + backgroundColor: "var(--bg-primary)", }} > diff --git a/frontend/src/modules/ide/components/FilePickerItem.tsx b/frontend/src/modules/ide/components/FilePickerItem.tsx index 39aeddd..22f5f5f 100644 --- a/frontend/src/modules/ide/components/FilePickerItem.tsx +++ b/frontend/src/modules/ide/components/FilePickerItem.tsx @@ -44,7 +44,7 @@ export const FilePickerItem: React.FC = ({ paddingLeft: `${paddingLeft}px`, paddingRight: "12px", height: "36px", - borderBottom: "1px solid #1a1a1a", + borderBottom: "1px solid var(--border)", cursor: "pointer", transition: "background-color 0.1s", gap: "8px", @@ -57,7 +57,7 @@ export const FilePickerItem: React.FC = ({ } }} onMouseEnter={(e) => { - e.currentTarget.style.backgroundColor = "#2a2a2a"; + e.currentTarget.style.backgroundColor = "var(--bg-secondary)"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = "transparent"; @@ -65,7 +65,13 @@ export const FilePickerItem: React.FC = ({ > {/* Folder expand icon */} {isFolder && ( - + {isExpanded ? ( ) : ( @@ -77,9 +83,9 @@ export const FilePickerItem: React.FC = ({ {/* File/Folder icon */} {isFolder ? ( - + ) : ( - + )} @@ -87,7 +93,7 @@ export const FilePickerItem: React.FC = ({ = ({ {!isFolder && extension && ( = ({ style={{ width: "18px", height: "18px", - border: isSelected ? "2px solid #0e639c" : "2px solid #555", + border: isSelected + ? "2px solid #0e639c" + : "2px solid var(--border)", borderRadius: "3px", backgroundColor: isSelected ? "#0e639c" : "transparent", display: "flex", diff --git a/frontend/src/pages/ide.page.tsx b/frontend/src/pages/ide.page.tsx index d518e94..a5fe8ef 100644 --- a/frontend/src/pages/ide.page.tsx +++ b/frontend/src/pages/ide.page.tsx @@ -8,7 +8,10 @@ export const IDEPage = () => { const files: FileNode | undefined = location.state?.files; return ( -
+
navigate("/templates")} initialFiles={files} />
); diff --git a/frontend/src/pages/templates.page.tsx b/frontend/src/pages/templates.page.tsx index 2cc3561..68c6783 100644 --- a/frontend/src/pages/templates.page.tsx +++ b/frontend/src/pages/templates.page.tsx @@ -118,6 +118,7 @@ export const TemplatesPage = () => { style={{ height: "100vh", position: "relative", + backgroundColor: "var(--bg-primary)", }} > {/* Floating header */} @@ -139,13 +140,13 @@ export const TemplatesPage = () => { alignItems: "center", gap: "8px", padding: "6px 12px", - backgroundColor: "#1a1a1a", + backgroundColor: "var(--card-bg)", borderRadius: "4px", - border: "1px solid #2a2a2a", + border: "1px solid var(--border)", }} > - + {selectedPaths.size} script{selectedPaths.size !== 1 ? "s" : ""}{" "} running diff --git a/frontend/src/pages/themes.page.tsx b/frontend/src/pages/themes.page.tsx deleted file mode 100644 index fa02cc9..0000000 --- a/frontend/src/pages/themes.page.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { ThemeChanger } from "@/modules/theme-changer"; - -export const ThemesPage = () => { - return ( -
- -
- ); -};