Auth page: pure-PHP Authelia ACL parser, NPM-sourced certs tab, watchdog JS fixes, rsync settings layout

- Replace python3/PyYAML Authelia ACL parser with pure PHP (no deps available on Unraid)
- Cert tab now pulls live from NPM API instead of cert_monitor.sh — auto-discovers all managed certs sorted by urgency
- Watchdog page: add missing GB constant and _fmtBytes/_relTime functions that were causing silent render failure
- Rsync settings card: pin to far-right 3 columns (grid-column:6/-1), toggle grid narrowed to 2 columns
- Add CLAUDE.md project context file on /boot for session persistence across reboots
- claude_startup.sh: symlink CLAUDE.md into /root on array start
This commit is contained in:
Gmer4Lfe
2026-06-06 15:39:34 -04:00
parent 9c3ace95a7
commit bac0f7c535
7 changed files with 425 additions and 113 deletions
+4 -22
View File
@@ -44,8 +44,7 @@
.vv-ry-run-st { text-align:right; }
/* Settings */
.vv-ry-set-grid { display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-top:6px; }
@media (max-width:900px) { .vv-ry-set-grid { grid-template-columns:repeat(2,1fr); } }
.vv-ry-set-grid { display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-top:6px; }
.vv-ry-toggle { display:inline-flex;align-items:center;gap:8px;cursor:pointer;user-select:none; }
.vv-ry-toggle-track { width:32px;height:18px;border-radius:9px;background:#222;border:1px solid #333;position:relative;transition:background .15s,border-color .15s;flex-shrink:0; }
.vv-ry-toggle-track.on { background:#1a3a1a;border-color:#2d5a2d; }
@@ -534,15 +533,6 @@ const PROF_COLORS = [
'#4dd0e1','#a5d6a7','#ff8a65','#90caf9','#f48fb1',
];
function _rel(ts) {
if (!ts) return '—';
const d = Math.floor(Date.now() / 1000) - ts;
if (d < 60) return 'just now';
if (d < 3600) return Math.floor(d / 60) + 'm ago';
if (d < 86400) return Math.floor(d / 3600) + 'h ' + Math.floor((d % 3600) / 60) + 'm ago';
return Math.floor(d / 86400) + 'd ago';
}
function _dur(s) {
if (!s) return '—';
const h = Math.floor(s / 3600), m = Math.floor((s % 3600) / 60), sec = s % 60;
@@ -551,14 +541,6 @@ function _dur(s) {
return sec + 's';
}
function _fmtBytes(b) {
if (!b) return '';
const G = 1073741824, M = 1048576;
if (b >= G) return (b / G).toFixed(1) + ' GB';
if (b >= M) return (b / M).toFixed(0) + ' MB';
return (b / 1024).toFixed(0) + ' KB';
}
// ── Status + active card ──────────────────────────────────────────────────────
function _statusCard(data) {
const en = data.enabled;
@@ -609,7 +591,7 @@ function _lastSyncCard(data) {
<span class="vv-ry-lbl">${WIN_META[k]?.label || k}</span>
<span class="vv-ry-val">
<span style="${cls}">${e.status}</span>
<span style="color:#444;margin-left:6px;">${_rel(e.ts)}</span>
<span style="color:#444;margin-left:6px;">${_relTime(e.ts)}</span>
${e.duration ? `<span style="color:#3a3a3a;margin-left:4px;">${_dur(e.duration)}</span>` : ''}
</span>
</div>`;
@@ -639,7 +621,7 @@ function _windowsRow(data) {
if (ls && ls.ts) {
const okCol = ls.status === 'success' ? '#4caf50' : '#ef5350';
statusHtml = `<div class="vv-ry-win-stat" style="color:${okCol};">${ls.status}</div>
<div class="vv-ry-win-dur">${_rel(ls.ts)}${ls.duration ? ' · ' + _dur(ls.duration) : ''}</div>`;
<div class="vv-ry-win-dur">${_relTime(ls.ts)}${ls.duration ? ' · ' + _dur(ls.duration) : ''}</div>`;
}
const expandable = !!(scripts.length || shares.length);
@@ -755,7 +737,7 @@ function _settingsSection(data) {
const mbit = s.bw_limit ? ' (~' + (s.bw_limit / 125).toFixed(0) + ' Mbit/s)' : '';
return `<div class="vv-ry-card" style="grid-column:1/-1;">
return `<div class="vv-ry-card" style="grid-column:6/-1;">
<div class="vv-ry-sec" style="margin-bottom:10px;">Settings</div>
<div style="margin-bottom:12px;">