355 lines
20 KiB
HTML
355 lines
20 KiB
HTML
<!doctype html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>NODE.DC Admin</title>
|
||
<link rel="stylesheet" href="./admin.css" />
|
||
</head>
|
||
<body>
|
||
<div class="admin-backdrop" aria-hidden="true"></div>
|
||
<header class="nodedc-expanded-toolbar-shell">
|
||
<div class="nodedc-expanded-toolbar">
|
||
<div class="nodedc-expanded-toolbar-top">
|
||
<div class="nodedc-expanded-toolbar-left">
|
||
<a href="/" class="nodedc-expanded-brand-link" target="_blank" aria-label="NODE.DC">
|
||
<img src="./nodedc-logo.svg" alt="NODE.DC" class="nodedc-expanded-brand-logo" />
|
||
</a>
|
||
</div>
|
||
<div class="nodedc-expanded-toolbar-center">
|
||
<span class="nodedc-expanded-workspace-button" aria-hidden="true">
|
||
<img src="../assets/uploads/images/Logo/dclogo_white_alpha-mqus5if2.png" alt="" class="nodedc-expanded-workspace-avatar" />
|
||
</span>
|
||
<nav class="nodedc-expanded-nav-group" aria-label="Навигация админки">
|
||
<button id="admin-mode-content" class="nodedc-expanded-nav-button" type="button" data-active="true">
|
||
<span>Администрирование</span>
|
||
</button>
|
||
<button id="admin-mode-seo" class="nodedc-expanded-nav-button" type="button" data-active="false">
|
||
<span>SEO</span>
|
||
</button>
|
||
<button id="admin-mode-knowledge" class="nodedc-expanded-nav-button" type="button" data-active="false">
|
||
<span>База знаний</span>
|
||
</button>
|
||
</nav>
|
||
</div>
|
||
<div class="nodedc-expanded-toolbar-right">
|
||
<div class="nodedc-expanded-user-group">
|
||
<span class="nodedc-toolbar-icon-button" aria-hidden="true">▣</span>
|
||
<span class="nodedc-expanded-profile-trigger">
|
||
<span class="nodedc-expanded-nav-button" data-active="false">
|
||
<span>Профиль</span>
|
||
</span>
|
||
<span class="nodedc-expanded-user-avatar-button" aria-hidden="true">
|
||
<span class="nodedc-expanded-user-avatar">DC</span>
|
||
</span>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
<main class="admin-shell">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-head">
|
||
<div>
|
||
<div class="section-kicker">NODE.DC</div>
|
||
<h1 id="sidebar-title">Администрирование</h1>
|
||
</div>
|
||
<button id="add-project" class="admin-panel-close add-block-button" type="button" aria-label="Добавить сайт" title="Добавить сайт">+</button>
|
||
<div class="workspace-card admin-panel-client-select">
|
||
<div class="workspace-logo admin-panel-client-select__icon">DC</div>
|
||
<div>
|
||
<div id="workspace-name" class="workspace-name">NODE.DC</div>
|
||
<div id="workspace-role" class="workspace-role">Администратор сайта</div>
|
||
</div>
|
||
<div class="workspace-card-actions">
|
||
<button id="project-settings" class="workspace-action-button" type="button" aria-label="Настройки проекта" title="Настройки проекта">
|
||
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
||
<path d="M12 8.2a3.8 3.8 0 1 1 0 7.6 3.8 3.8 0 0 1 0-7.6Z" />
|
||
<path d="M19.4 13.5c.06-.48.06-.98 0-1.5l2-1.55-1.9-3.3-2.35.95a8.2 8.2 0 0 0-1.3-.75L15.5 4.8h-3.8l-.35 2.55c-.46.2-.9.45-1.3.75L7.7 7.15l-1.9 3.3L7.8 12a8.5 8.5 0 0 0 0 1.5l-2 1.55 1.9 3.3 2.35-.95c.4.3.84.55 1.3.75l.35 2.55h3.8l.35-2.55c.46-.2.9-.45 1.3-.75l2.35.95 1.9-3.3-2-1.55Z" />
|
||
</svg>
|
||
</button>
|
||
<button id="add-block" class="workspace-action-button workspace-action-button--plus" type="button" aria-label="Добавить блок" title="Добавить блок">+</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="regions" class="regions"></div>
|
||
</aside>
|
||
|
||
<section class="editor">
|
||
<header class="editor-head">
|
||
<div>
|
||
<h1 id="editor-heading">Настройки сайта</h1>
|
||
<div id="selected-region" class="breadcrumb">NODE.DC / Выберите блок</div>
|
||
<h2 id="selected-title">Контентный слой</h2>
|
||
</div>
|
||
<div class="actions">
|
||
<span id="dirty-state" class="dirty-state" data-dirty="false">Синхронизировано</span>
|
||
<button id="reload" class="icon-btn" type="button" title="Перезагрузить данные">↻</button>
|
||
<button id="save" class="primary-btn" type="button" title="Записать текущую модель в content/pages/home.json">Сохранить модель</button>
|
||
<button id="render" class="ghost-btn" type="button" title="Сохранить модель и пересобрать публичный index.html">Обновить index.html</button>
|
||
</div>
|
||
</header>
|
||
|
||
<div id="empty-state" class="empty-state">
|
||
<div class="empty-icon">ND</div>
|
||
<div>
|
||
<h3>Выберите блок слева</h3>
|
||
<p>Статика, hero, форма и секции страницы разделены на рабочие группы. Сначала редактируем typed-поля, сырой JSON оставлен как технический fallback.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<form id="block-form" class="block-form hidden">
|
||
<section class="settings-card block-meta-card">
|
||
<div class="card-head">
|
||
<div>
|
||
<div class="section-kicker">Идентификатор</div>
|
||
<h3>Служебные параметры</h3>
|
||
</div>
|
||
<label class="toggle-row">
|
||
<input id="block-enabled" name="enabled" type="checkbox" />
|
||
<span>Отображение</span>
|
||
</label>
|
||
</div>
|
||
<div class="field-grid">
|
||
<label class="field-control">
|
||
<span>ID блока</span>
|
||
<input id="block-id" name="id" type="text" autocomplete="off" />
|
||
</label>
|
||
<label class="field-control">
|
||
<span>Название в админке</span>
|
||
<input id="block-label" name="adminLabel" type="text" autocomplete="off" />
|
||
</label>
|
||
<label class="field-control">
|
||
<span>Шаблон / тип</span>
|
||
<input id="block-template" name="template" type="text" autocomplete="off" readonly />
|
||
</label>
|
||
<label class="field-control">
|
||
<span>Target</span>
|
||
<input id="block-anchor" name="target" type="text" autocomplete="off" list="block-target-options" />
|
||
<datalist id="block-target-options"></datalist>
|
||
</label>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="settings-card structure-card">
|
||
<div class="card-head structure-head">
|
||
<div>
|
||
<div class="section-kicker">Порядок блока</div>
|
||
<h3>Операции с блоком</h3>
|
||
</div>
|
||
<div class="button-row icon-action-row">
|
||
<button id="move-up" class="icon-action-btn" type="button" title="Поднять блок" aria-label="Поднять блок">
|
||
<span aria-hidden="true">↑</span>
|
||
</button>
|
||
<button id="move-down" class="icon-action-btn" type="button" title="Опустить блок" aria-label="Опустить блок">
|
||
<span aria-hidden="true">↓</span>
|
||
</button>
|
||
<button id="duplicate" class="icon-action-btn" type="button" title="Дублировать блок" aria-label="Дублировать блок">
|
||
<span aria-hidden="true">⧉</span>
|
||
</button>
|
||
<button id="copy" class="icon-action-btn operation-extra" type="button" title="Копировать блок" aria-label="Копировать блок">
|
||
<span aria-hidden="true">□</span>
|
||
</button>
|
||
<button id="paste-after" class="icon-action-btn operation-extra" type="button" title="Вставить после" aria-label="Вставить после">
|
||
<span aria-hidden="true">▣</span>
|
||
</button>
|
||
<button id="delete-block" class="icon-action-btn danger-action-btn" type="button" title="Удалить блок" aria-label="Удалить блок">
|
||
<svg class="trash-can-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
||
<path d="M3.75 6.75h16.5" />
|
||
<path d="M8.25 6.75V4.9c0-.64.51-1.15 1.15-1.15h5.2c.64 0 1.15.51 1.15 1.15v1.85" />
|
||
<path d="M6.25 6.75l.7 12.15c.06.78.7 1.35 1.47 1.35h7.16c.77 0 1.41-.57 1.47-1.35l.7-12.15" />
|
||
<path d="M10 10.75v5.5" />
|
||
<path d="M14 10.75v5.5" />
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="content-panel">
|
||
<div class="panel-head">
|
||
<div>
|
||
<div id="content-panel-kicker" class="section-kicker">Контент</div>
|
||
<h3 id="content-panel-title">Редактируемые поля</h3>
|
||
</div>
|
||
<span id="content-panel-note" class="panel-note">Поля сгруппированы по смысловым подблокам верстки.</span>
|
||
</div>
|
||
<div id="content-fields" class="content-fields"></div>
|
||
</section>
|
||
|
||
<details class="json-details">
|
||
<summary>JSON выбранного блока</summary>
|
||
<label class="json-field">
|
||
<span>Техническое представление</span>
|
||
<textarea id="block-json" spellcheck="false"></textarea>
|
||
</label>
|
||
</details>
|
||
</form>
|
||
|
||
<div id="knowledge-form" class="knowledge-editor hidden"></div>
|
||
<div id="project-settings-form" class="project-settings-editor hidden"></div>
|
||
|
||
<pre id="status" class="status"></pre>
|
||
</section>
|
||
</main>
|
||
<div id="template-modal" class="template-modal-layer hidden" role="dialog" aria-modal="true" aria-labelledby="template-modal-title">
|
||
<article class="template-modal">
|
||
<header class="template-modal-head">
|
||
<div>
|
||
<div class="section-kicker">Библиотека блоков</div>
|
||
<h2 id="template-modal-title">Добавить блок</h2>
|
||
<p>Выберите шаблон. Новый блок появится в конце соответствующего списка.</p>
|
||
</div>
|
||
<button id="template-modal-close" class="admin-panel-close modal-close-button" type="button" aria-label="Закрыть">×</button>
|
||
</header>
|
||
<div id="template-list" class="template-list"></div>
|
||
<footer class="template-modal-foot">
|
||
<button id="template-modal-cancel" class="ghost-btn" type="button">Отмена</button>
|
||
</footer>
|
||
</article>
|
||
</div>
|
||
<div id="delete-modal" class="template-modal-layer delete-modal-layer hidden" role="dialog" aria-modal="true" aria-labelledby="delete-modal-title" aria-describedby="delete-modal-body">
|
||
<article class="template-modal delete-modal">
|
||
<header class="template-modal-head delete-modal-head">
|
||
<div>
|
||
<div class="section-kicker">Удаление</div>
|
||
<h2 id="delete-modal-title">Подтвердите действие</h2>
|
||
<p id="delete-modal-body">Вы действительно подтвердить удаление элемента?</p>
|
||
</div>
|
||
</header>
|
||
<footer class="template-modal-foot delete-modal-foot">
|
||
<button id="delete-modal-cancel" class="ghost-btn" type="button">Отмена</button>
|
||
<button id="delete-modal-confirm" class="danger-btn delete-confirm-btn" type="button">Да</button>
|
||
</footer>
|
||
</article>
|
||
</div>
|
||
<div id="media-modal" class="template-modal-layer media-modal-layer hidden" role="dialog" aria-modal="true" aria-labelledby="media-modal-title">
|
||
<article class="template-modal media-modal">
|
||
<header class="template-modal-head media-modal-head">
|
||
<div>
|
||
<div class="section-kicker">Медиатека</div>
|
||
<h2 id="media-modal-title">Выбрать файл</h2>
|
||
<p id="media-modal-subtitle">Существующие файлы на сервере и загрузки для текущего поля.</p>
|
||
</div>
|
||
<div class="media-modal-actions">
|
||
<span id="media-site-size" class="media-site-size">Сайт: считаем...</span>
|
||
<button id="media-trash-toggle" class="admin-panel-close media-header-action media-trash-toggle" type="button" aria-label="Недавно удалённые" title="Недавно удалённые">
|
||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||
<path d="M3.75 6.75h16.5" />
|
||
<path d="M8.25 6.75V4.9c0-.64.51-1.15 1.15-1.15h5.2c.64 0 1.15.51 1.15 1.15v1.85" />
|
||
<path d="M6.25 6.75l.7 12.15c.06.78.7 1.35 1.47 1.35h7.16c.77 0 1.41-.57 1.47-1.35l.7-12.15" />
|
||
<path d="M10 10.75v5.5" />
|
||
<path d="M14 10.75v5.5" />
|
||
</svg>
|
||
</button>
|
||
<button id="media-modal-close" class="admin-panel-close modal-close-button media-header-action" type="button" aria-label="Закрыть">×</button>
|
||
</div>
|
||
</header>
|
||
<div class="media-toolbar">
|
||
<label class="media-search">
|
||
<span>Поиск</span>
|
||
<input id="media-search" type="search" autocomplete="off" placeholder="Имя, папка, путь" />
|
||
</label>
|
||
<div id="media-kind-filters" class="media-filter-row media-kind-row" aria-label="Тип файла"></div>
|
||
<div id="media-root-filters" class="media-filter-row media-root-row" aria-label="Корень файлов"></div>
|
||
<button id="media-upload" class="primary-btn media-upload-btn" type="button">+ Загрузить</button>
|
||
</div>
|
||
<div id="media-drop-zone" class="media-browser media-browser-columns">
|
||
<section class="media-main">
|
||
<div id="media-breadcrumbs" class="media-breadcrumbs"></div>
|
||
<div id="media-list" class="media-columns"></div>
|
||
<div id="media-empty" class="media-empty hidden">Папка пуста.</div>
|
||
</section>
|
||
<aside class="media-preview-panel">
|
||
<div id="media-preview" class="media-preview">
|
||
<span>FILE</span>
|
||
</div>
|
||
<div class="media-preview-copy">
|
||
<div id="media-preview-name" class="media-preview-name">Выберите файл</div>
|
||
<div id="media-preview-path" class="media-preview-path"></div>
|
||
<div id="media-preview-meta" class="media-preview-meta"></div>
|
||
</div>
|
||
<div id="media-preview-usage" class="media-usage-pill" data-status="idle">
|
||
<span class="media-usage-dot"></span>
|
||
<span>Нет выбора</span>
|
||
</div>
|
||
<div class="media-preview-actions">
|
||
<button id="media-select" class="primary-btn" type="button" disabled>Выбрать</button>
|
||
<button id="media-delete" class="danger-btn media-delete-btn" type="button" aria-label="Удалить файл" title="Удалить файл" disabled>
|
||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||
<path d="M3.75 6.75h16.5" />
|
||
<path d="M8.25 6.75V4.9c0-.64.51-1.15 1.15-1.15h5.2c.64 0 1.15.51 1.15 1.15v1.85" />
|
||
<path d="M6.25 6.75l.7 12.15c.06.78.7 1.35 1.47 1.35h7.16c.77 0 1.41-.57 1.47-1.35l.7-12.15" />
|
||
<path d="M10 10.75v5.5" />
|
||
<path d="M14 10.75v5.5" />
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
<footer class="template-modal-foot media-modal-foot">
|
||
<button id="media-refresh" class="ghost-btn" type="button">Обновить список</button>
|
||
<button id="media-modal-cancel" class="ghost-btn" type="button">Отмена</button>
|
||
</footer>
|
||
</article>
|
||
</div>
|
||
<div id="media-context-menu" class="media-context-menu hidden" role="menu"></div>
|
||
<div id="media-action-modal" class="template-modal-layer media-action-modal-layer hidden" role="dialog" aria-modal="true" aria-labelledby="media-action-title">
|
||
<article class="template-modal media-action-modal">
|
||
<header class="template-modal-head media-action-head">
|
||
<div>
|
||
<div class="section-kicker">Файл-менеджер</div>
|
||
<h2 id="media-action-title">Действие</h2>
|
||
<p id="media-action-body">Введите имя.</p>
|
||
</div>
|
||
</header>
|
||
<div class="media-action-body">
|
||
<label class="field-control">
|
||
<span id="media-action-label">Имя</span>
|
||
<input id="media-action-input" type="text" autocomplete="off" />
|
||
</label>
|
||
</div>
|
||
<footer class="template-modal-foot media-action-foot">
|
||
<button id="media-action-cancel" class="ghost-btn" type="button">Отмена</button>
|
||
<button id="media-action-confirm" class="primary-btn" type="button">Подтвердить</button>
|
||
</footer>
|
||
</article>
|
||
</div>
|
||
<div id="knowledge-button-modal" class="template-modal-layer knowledge-button-modal-layer hidden" role="dialog" aria-modal="true" aria-labelledby="knowledge-button-title">
|
||
<article class="template-modal knowledge-button-modal">
|
||
<header class="template-modal-head knowledge-button-head">
|
||
<div>
|
||
<div class="section-kicker">База знаний</div>
|
||
<h2 id="knowledge-button-title">Кнопка в статье</h2>
|
||
<p>Ссылка ведёт на лендинг или внешний адрес. Target открывает нужный блок лендинга.</p>
|
||
</div>
|
||
<button id="knowledge-button-close" class="admin-panel-close modal-close-button" type="button" aria-label="Закрыть">×</button>
|
||
</header>
|
||
<div class="knowledge-button-body">
|
||
<label class="field-control">
|
||
<span>Название</span>
|
||
<input id="knowledge-button-name" type="text" autocomplete="off" placeholder="Посмотреть демо" />
|
||
</label>
|
||
<label class="field-control">
|
||
<span>Ссылка</span>
|
||
<input id="knowledge-button-link" type="text" autocomplete="off" placeholder="/" />
|
||
</label>
|
||
<label class="field-control">
|
||
<span>Target / блок лендинга</span>
|
||
<input id="knowledge-button-target" type="text" autocomplete="off" list="knowledge-button-target-options" placeholder="hub-video" />
|
||
<datalist id="knowledge-button-target-options"></datalist>
|
||
</label>
|
||
<p class="knowledge-button-hint">Можно выбрать target из списка или ввести ID блока лендинга. Если target пустой, ссылка откроет первый экран.</p>
|
||
<p id="knowledge-button-error" class="knowledge-button-error" aria-live="polite"></p>
|
||
</div>
|
||
<footer class="template-modal-foot knowledge-button-foot">
|
||
<button id="knowledge-button-cancel" class="ghost-btn" type="button">Отмена</button>
|
||
<button id="knowledge-button-confirm" class="primary-btn" type="button">Добавить кнопку</button>
|
||
</footer>
|
||
</article>
|
||
</div>
|
||
<script src="./admin.js" type="module"></script>
|
||
</body>
|
||
</html>
|