import { useEffect, useMemo, useState, type CSSProperties, type ReactNode } from "react"; import { applyNodedcTheme, type NodedcTheme, type RgbTuple } from "@nodedc/ui-core"; import { AppHeader, Button, Checker, ColorField, ConfirmationModal, ControlRow, Dropdown, FieldFrame, GlassSurface, HeaderProfile, HeaderWorkspace, IconButton, Inspector, RangeControl, SegmentedControl, Select, StatusBadge, TextAreaField, TextField, Window, WindowFooterActions, } from "@nodedc/ui-react"; type CatalogSection = "foundation" | "controls" | "windows" | "inspector"; const accents: Array<{ label: string; value: RgbTuple; hex: string }> = [ { label: "Hub", value: [195, 255, 102], hex: "#c3ff66" }, { label: "Engine", value: [148, 123, 219], hex: "#947bdb" }, { label: "BIM", value: [78, 164, 255], hex: "#4ea4ff" }, { label: "SEO", value: [32, 32, 34], hex: "#202022" }, ]; const selectOptions = [ { value: "active", label: "Активен", description: "Сервис доступен пользователям" }, { value: "maintenance", label: "Техработы", description: "Временно недоступен" }, { value: "disabled", label: "Отключён", description: "Запуск запрещён" }, ] as const; function rgbFromHex(hex: string): RgbTuple | null { const normalized = hex.trim().replace(/^#/, ""); if (!/^[0-9a-f]{6}$/i.test(normalized)) return null; return [ Number.parseInt(normalized.slice(0, 2), 16), Number.parseInt(normalized.slice(2, 4), 16), Number.parseInt(normalized.slice(4, 6), 16), ]; } function Section({ id, eyebrow, title, description, children }: { id: string; eyebrow: string; title: string; description: string; children: ReactNode; }) { return (
{eyebrow}

{title}

{description}

{children}
); } function Preview({ title, note, children, className }: { title: string; note?: string; children: ReactNode; className?: string; }) { return (
{title} {note ? {note} : null}
{children}
); } export function CatalogApp() { const [theme, setTheme] = useState("dark"); const [accentHex, setAccentHex] = useState("#c3ff66"); const [section, setSection] = useState("foundation"); const [selectedStatus, setSelectedStatus] = useState<(typeof selectOptions)[number]["value"]>("active"); const [checker, setChecker] = useState(true); const [range, setRange] = useState(64); const [modalOpen, setModalOpen] = useState(false); const [inspectorOpen, setInspectorOpen] = useState(false); const [confirmOpen, setConfirmOpen] = useState(false); const [projectName, setProjectName] = useState("NODE.DC Platform"); const [notes, setNotes] = useState("Общий контракт компонентов без доменной логики приложения."); const accent = useMemo(() => rgbFromHex(accentHex) ?? accents[0].value, [accentHex]); useEffect(() => { applyNodedcTheme(document.documentElement, { theme, accent }); }, [accent, theme]); const openSection = (next: CatalogSection) => { setSection(next); document.getElementById(next)?.scrollIntoView({ behavior: "smooth", block: "start" }); }; const inspectorSections = [ { id: "definition", label: "Definition Control", description: "Параметры агентной ноды", content: ( <> ( )} > {({ close }) => ( <> )}
`${value}%`} onChange={setRange} />
Черновик Готово Нужна проверка Ошибка В работе
ИнспекторAgent Definition
setModalOpen(false)} footer={ <> } >
setProjectName(event.target.value)} />