fix(gui): correct wg dump indexes, status, traffic, UX improvements

- Fix off-by-one bug in wg_dump(): handshake was read from parts[5] (rx_bytes),
  now correctly reads from parts[4]; rx/tx shifted accordingly
- Run wg show via sudo to work under unprivileged wgadmin user
- Remove NoNewPrivileges from systemd service (needed for sudo)
- Merge Handshake column into Status badge (shows "online · 2м назад")
- Add humanize_ago() for human-readable handshake time
- Add next_free_ip() to suggest next available IP in new peer form
- Add device type quick-select buttons (Phone/Laptop/PC/Router/Server/Tablet)
- Placeholder in AllowedIPs now shows the real next free IP
- Traffic column shows ↓ rx / ↑ tx separately

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 10:18:38 +03:00
parent 904582e7fa
commit fe1cba2d02
4 changed files with 100 additions and 26 deletions
+22
View File
@@ -200,6 +200,11 @@ tbody tr.row-disabled td { opacity: 0.45; }
.badge.offline { background: var(--bg3); color: var(--text-muted); }
.badge.offline .dot { background: #9ca3af; }
.badge-ago { font-weight: 400; opacity: 0.75; font-size: 10.5px; margin-left: 2px; }
.traffic { display: flex; flex-direction: column; gap: 1px; font-size: 12px; font-family: var(--mono); }
.traffic span { white-space: nowrap; }
/* ─── Buttons ────────────────────────────────────────────────── */
.btn {
display: inline-flex;
@@ -269,6 +274,23 @@ tbody tr.row-disabled td { opacity: 0.45; }
.form-actions { display: flex; gap: 8px; margin-top: 24px; }
.optional { font-size: 11px; font-weight: 400; color: var(--text-muted); margin-left: 4px; }
.name-hints { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.hint-label { font-size: 12px; color: var(--text-muted); }
.hint-btn {
padding: 3px 10px;
border-radius: 6px;
border: 1px solid var(--border);
background: var(--bg3);
color: var(--text);
font-size: 12px;
cursor: pointer;
font-family: var(--font);
transition: background 0.12s, border-color 0.12s;
}
.hint-btn:hover { background: #e8eaf6; border-color: var(--accent); color: var(--accent); }
/* ─── Peer detail ────────────────────────────────────────────── */
.peer-detail-grid { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: start; }
@media (max-width: 768px) { .peer-detail-grid { grid-template-columns: 1fr; } }