diff --git a/tools/control-panel.ps1 b/tools/control-panel.ps1 index 1a42d78..5baf2e2 100644 --- a/tools/control-panel.ps1 +++ b/tools/control-panel.ps1 @@ -68,7 +68,8 @@ $script:Stat = $null function Refresh-Status { $proc = Server-Proc $s = @{ running = ($null -ne $proc); procId = '-'; uptime = '-'; health = '—'; healthMs = $null; - dbSize = '—'; users = '?'; migr = '-' } + dbSize = '—'; users = '?'; migr = '-'; at = (Get-Date -Format 'HH:mm:ss'); backups = 0 } + try { $s.backups = @(Get-ChildItem $script:BackupDir -Filter 'learnspace-*.db' -ErrorAction SilentlyContinue).Count } catch {} if ($proc) { $s.procId = $proc.Id try { $u = (Get-Date) - $proc.StartTime; $s.uptime = ('{0}ч {1}м' -f [int]$u.TotalHours, $u.Minutes) } catch {} @@ -205,6 +206,42 @@ function Run-Cmd($title, $block) { [void](Read-Host ' [Enter] вернуться в меню') } +# ── Рисование рамки/дашборда ── +$script:W = 62 # внутренняя ширина рамки (символов) +function B-Top { Write-Host (' ╔' + ('═' * ($script:W + 2)) + '╗') -ForegroundColor DarkCyan } +function B-Mid { Write-Host (' ╠' + ('═' * ($script:W + 2)) + '╣') -ForegroundColor DarkCyan } +function B-Bot { Write-Host (' ╚' + ('═' * ($script:W + 2)) + '╝') -ForegroundColor DarkCyan } +function B-Line($text, $color) { + $t = [string]$text + if ($t.Length -gt $script:W) { $t = $t.Substring(0, $script:W) } + Write-Host ' ║ ' -ForegroundColor DarkCyan -NoNewline + Write-Host $t.PadRight($script:W) -ForegroundColor $color -NoNewline + Write-Host ' ║' -ForegroundColor DarkCyan +} +# Строка с цветным маркером ● слева (статус). Маркер + пробел = 2 столбца. +function B-Status($markerColor, $text, $textColor) { + $avail = $script:W - 2 + $t = [string]$text + if ($t.Length -gt $avail) { $t = $t.Substring(0, $avail) } + Write-Host ' ║ ' -ForegroundColor DarkCyan -NoNewline + Write-Host '●' -ForegroundColor $markerColor -NoNewline + Write-Host ' ' -NoNewline + Write-Host $t.PadRight($avail) -ForegroundColor $textColor -NoNewline + Write-Host ' ║' -ForegroundColor DarkCyan +} +# Заголовок секции меню (две колонки выравниваются под пунктами). +function Menu-Head($left, $right) { Write-Host (' ' + $left.PadRight(34) + $right) -ForegroundColor DarkCyan } +# Пункт меню в две колонки: ключ голубой, подпись серая. +function Menu-Row($lk, $ll, $rk, $rl) { + Write-Host ' ' -NoNewline + Write-Host $lk -ForegroundColor Cyan -NoNewline + Write-Host ((' ' + $ll).PadRight(31)) -ForegroundColor Gray -NoNewline + if ($rk) { + Write-Host $rk -ForegroundColor Cyan -NoNewline + Write-Host (' ' + $rl) -ForegroundColor Gray + } else { Write-Host '' } +} + # ── Неинтерактивные режимы (для start/stop-server.bat) ── if ($Stop) { Stop-Server; Start-Sleep -Milliseconds 800; exit } if ($Start) { Start-Server; Start-Sleep -Milliseconds 800; exit } @@ -215,34 +252,41 @@ $run = $true while ($run) { Clear-Host $s = $script:Stat - $bar = ' ' + ('=' * 58) + $migrShort = $s.migr; if ($s.migr -match '^(\d+)') { $migrShort = $matches[1] } Write-Host '' - Write-Host $bar -ForegroundColor DarkCyan - Write-Host ' LearnSpace — Панель управления' -ForegroundColor Cyan - Write-Host $bar -ForegroundColor DarkCyan + B-Top + B-Line 'LearnSpace · Панель управления сервером' Cyan + B-Mid if ($s.running) { - Write-Host (' Статус: РАБОТАЕТ — PID ' + $s.procId + ', порт ' + $script:Port + ', аптайм ' + $s.uptime) -ForegroundColor Green + B-Status Green ('РАБОТАЕТ PID ' + $s.procId + ' · порт ' + $script:Port + ' · аптайм ' + $s.uptime) Green $hc = if ($s.health -eq 'healthy') { 'Green' } else { 'Yellow' } $hm = if ($s.healthMs -ne $null) { " ($($s.healthMs) ms)" } else { '' } - Write-Host (' Health: ' + $s.health + $hm) -ForegroundColor $hc + B-Line ('Health: ' + $s.health + $hm) $hc } else { - Write-Host ' Статус: остановлен' -ForegroundColor Yellow + B-Status DarkGray 'ОСТАНОВЛЕН' Yellow } - Write-Host (' БД: ' + $s.dbSize + ', пользователей: ' + $s.users + ', миграций до: ' + $s.migr) -ForegroundColor Gray - Write-Host (' Node: ' + $script:NodeVer + ' | .env: CLIENT_ORIGIN=' + $script:EnvSum.origin + ', JWT_SECRET=' + $script:EnvSum.jwt + ', LLM=' + $script:EnvSum.llm) -ForegroundColor DarkGray - Write-Host (' URL: http://localhost:' + $script:Port) -ForegroundColor DarkGray - Write-Host $bar -ForegroundColor DarkCyan + B-Line ('БД ' + $s.dbSize + ' · пользователей: ' + $s.users + ' · миграция: ' + $migrShort + ' · бэкапов: ' + $s.backups) Gray + B-Line ('Node ' + $script:NodeVer + ' · JWT: ' + $script:EnvSum.jwt + ' · LLM: ' + $script:EnvSum.llm + ' · обновлено ' + $s.at) DarkGray + B-Line ('URL ' + $script:EnvSum.origin) DarkGray + B-Bot Write-Host '' - Write-Host ' [1] Запустить сервер [6] Тесты (npm test)' - Write-Host ' [2] Остановить сервер [7] Проверка роутов (lint)' - Write-Host ' [3] Перезапустить [8] Открыть сайт в браузере' - Write-Host ' [4] Живые логи (окно) [9] Обновить статус' - Write-Host ' [5] Применить миграции [0] Выход' + Menu-Head 'СЕРВЕР' 'ОБСЛУЖИВАНИЕ' + Menu-Row '[1]' 'Запустить' '[B]' 'Бэкап БД' + Menu-Row '[2]' 'Остановить' '[R]' 'Восстановить БД' + Menu-Row '[3]' 'Перезапустить' '[A]' 'Создать админа' + Menu-Row '[4]' 'Живые логи (окно)' '[W]' 'Сторож (авто-рестарт)' + Menu-Row '[5]' 'Применить миграции' '[E]' 'Ошибки в логах' Write-Host '' - Write-Host ' Данные и обслуживание:' -ForegroundColor DarkCyan - Write-Host ' [B] Бэкап БД [R] Восстановить БД [A] Создать админа [W] Сторож [E] Ошибки' + Menu-Head 'ДИАГНОСТИКА И ПРОЧЕЕ' '' + Write-Host ' ' -NoNewline + Write-Host '[6]' -ForegroundColor Cyan -NoNewline; Write-Host ' Тесты ' -ForegroundColor Gray -NoNewline + Write-Host '[7]' -ForegroundColor Cyan -NoNewline; Write-Host ' Lint роутов ' -ForegroundColor Gray -NoNewline + Write-Host '[8]' -ForegroundColor Cyan -NoNewline; Write-Host ' Сайт ' -ForegroundColor Gray -NoNewline + Write-Host '[9]' -ForegroundColor Cyan -NoNewline; Write-Host ' Обновить ' -ForegroundColor Gray -NoNewline + Write-Host '[0]' -ForegroundColor Cyan -NoNewline; Write-Host ' Выход' -ForegroundColor Gray Write-Host '' - $c = (Read-Host ' Выбор').Trim().ToUpper() + Write-Host ' ▶ ' -ForegroundColor Cyan -NoNewline + $c = (Read-Host 'Выбор').Trim().ToUpper() switch -Regex ($c) { '^1$' { Start-Server; Refresh-Status; Start-Sleep 1 } '^2$' { Stop-Server; Refresh-Status; Start-Sleep 1 } @@ -267,3 +311,4 @@ Write-Host ' Панель закрыта. Сервер, если запуще Write-Host ' Остановить позже: stop-server.bat или пункт [2] панели.' -ForegroundColor DarkGray +