refactor: sidebar layout for Tech Support and Feature Manager

- Add <aside class="sidebar"> with #sidebar-support and #sidebar-features to index.html
- Restyle .main-content as flex layout (sidebar left, tiles right)
- Body is now display:flex column with overflow:hidden for independent scroll panels
- Sidebar (270px fixed) with overflow-y:auto scrolls independently
- Tiles area (flex:1) scrolls independently
- New sidebar support button (.sidebar-support-btn) replaces support tile in main grid
- Feature Manager now renders into #sidebar-features instead of $tilesArea
- Compact sidebar overrides for .feature-card padding/font-size
- Remove 'support' and 'feature-manager' from CATEGORY_ORDER
- Responsive: sidebar becomes full-width above tiles at <=768px

Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/4304350a-bc4f-4698-82b5-8ee28f0ad960

Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-03 18:00:14 +00:00
committed by GitHub
parent 5a4383b6ec
commit c6868b63bc
3 changed files with 165 additions and 12 deletions

View File

@@ -15,8 +15,6 @@ const CATEGORY_ORDER = [
"communication",
"apps",
"nostr",
"support",
"feature-manager",
];
const FEATURE_SUBCATEGORY_LABELS = {
@@ -59,6 +57,8 @@ let _rebuildIsEnabling = true;
// ── DOM refs ──────────────────────────────────────────────────────
const $tilesArea = document.getElementById("tiles-area");
const $sidebarSupport = document.getElementById("sidebar-support");
const $sidebarFeatures = document.getElementById("sidebar-features");
const $updateBtn = document.getElementById("btn-update");
const $updateBadge = document.getElementById("update-badge");
const $refreshBtn = document.getElementById("btn-refresh");
@@ -173,9 +173,15 @@ function buildTiles(services, categoryLabels) {
_servicesCache = services;
var grouped = {};
for (var i = 0; i < services.length; i++) {
var cat = services[i].category || "other";
var svc = services[i];
// Support tiles go to the sidebar, not the main grid
if (svc.category === "support" || svc.type === "support") {
renderSidebarSupport(svc);
continue;
}
var cat = svc.category || "other";
if (!grouped[cat]) grouped[cat] = [];
grouped[cat].push(services[i]);
grouped[cat].push(svc);
}
$tilesArea.innerHTML = "";
var orderedKeys = CATEGORY_ORDER.filter(function(k) { return grouped[k]; });
@@ -202,6 +208,23 @@ function buildTiles(services, categoryLabels) {
}
}
function renderSidebarSupport(svc) {
$sidebarSupport.innerHTML = "";
var btn = document.createElement("button");
btn.className = "sidebar-support-btn";
btn.innerHTML =
'<span class="sidebar-support-icon">🛟</span>' +
'<span class="sidebar-support-text">' +
'<span class="sidebar-support-title">' + escHtml(svc.name || "Tech Support") + '</span>' +
'<span class="sidebar-support-hint">Click for help</span>' +
'</span>';
btn.addEventListener("click", function() { openSupportModal(); });
$sidebarSupport.appendChild(btn);
var hr = document.createElement("hr");
hr.className = "sidebar-divider";
$sidebarSupport.appendChild(hr);
}
function buildTile(svc) {
var isSupport = svc.type === "support";
var sc = statusClass(svc.status);
@@ -1194,7 +1217,7 @@ async function loadFeatureManager() {
function renderFeatureManager(data) {
// Remove old feature manager section if it exists
var old = $tilesArea.querySelector(".feature-manager-section");
var old = $sidebarFeatures.querySelector(".feature-manager-section");
if (old) old.parentNode.removeChild(old);
var section = document.createElement("div");
@@ -1236,7 +1259,7 @@ function renderFeatureManager(data) {
section.appendChild(subcat);
}
$tilesArea.appendChild(section);
$sidebarFeatures.appendChild(section);
}
function buildFeatureCard(feat) {

View File

@@ -37,6 +37,9 @@ body {
color: var(--text-primary);
line-height: 1.5;
min-height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* ── Header bar ─────────────────────────────────────────────────── */
@@ -189,9 +192,87 @@ button:disabled {
/* ── Main content ───────────────────────────────────────────────── */
.main-content {
max-width: 980px;
margin: 0 auto;
padding: 24px 16px 48px;
display: flex;
align-items: flex-start;
flex: 1;
overflow: hidden;
}
/* ── Sidebar ────────────────────────────────────────────────────── */
.sidebar {
width: 270px;
flex-shrink: 0;
height: 100%;
overflow-y: auto;
border-right: 1px solid var(--border-color);
background-color: var(--surface-color);
padding: 20px 14px;
display: flex;
flex-direction: column;
gap: 0;
}
/* ── Sidebar: Tech Support button ───────────────────────────────── */
.sidebar-support-btn {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
background-color: var(--card-color);
border: 2px dashed var(--accent-color);
border-radius: 12px;
padding: 12px 14px;
color: var(--text-primary);
cursor: pointer;
transition: border-style 0.15s, border-color 0.15s, background-color 0.15s;
text-align: left;
}
.sidebar-support-btn:hover {
border-style: solid;
border-color: #a8c8ff;
background-color: #35354a;
}
.sidebar-support-icon {
font-size: 1.5rem;
flex-shrink: 0;
}
.sidebar-support-text {
display: flex;
flex-direction: column;
gap: 2px;
}
.sidebar-support-title {
font-size: 0.88rem;
font-weight: 700;
color: var(--text-primary);
}
.sidebar-support-hint {
font-size: 0.72rem;
color: var(--accent-color);
font-weight: 600;
}
.sidebar-divider {
border: none;
border-top: 1px solid var(--border-color);
margin: 16px 0;
}
/* ── Tiles area ─────────────────────────────────────────────────── */
#tiles-area {
flex: 1;
height: 100%;
overflow-y: auto;
padding: 24px 20px 48px;
min-width: 0;
}
/* ── Category sections ──────────────────────────────────────────── */
@@ -859,6 +940,28 @@ button.btn-reboot:hover:not(:disabled) {
/* ── Responsive ─────────────────────────────────────────────────── */
@media (max-width: 768px) {
body {
overflow: auto;
}
.main-content {
flex-direction: column;
overflow: visible;
}
.sidebar {
width: 100%;
height: auto;
border-right: none;
border-bottom: 1px solid var(--border-color);
padding: 14px 12px;
}
#tiles-area {
height: auto;
overflow-y: visible;
padding: 16px 12px 40px;
}
}
@media (max-width: 600px) {
.header-bar {
padding: 10px 14px;
@@ -872,9 +975,6 @@ button.btn-reboot:hover:not(:disabled) {
flex-wrap: wrap;
padding: 8px 14px;
}
.main-content {
padding: 16px 12px 40px;
}
.tiles-grid {
justify-content: center;
}
@@ -1444,3 +1544,29 @@ button.btn-reboot:hover:not(:disabled) {
.tile-ports-label--loading {
color: var(--text-dim);
}
/* ── Sidebar: compact feature card overrides ─────────────────────── */
.sidebar .feature-manager-section {
margin-bottom: 0;
}
.sidebar .feature-subcategory {
margin-bottom: 16px;
}
.sidebar .feature-card {
padding: 10px 12px;
}
.sidebar .feature-card-name {
font-size: 0.88rem;
}
.sidebar .feature-card-desc {
font-size: 0.78rem;
}
.sidebar .section-header {
font-size: 0.75rem;
}