design: extend v1 to login / add-host / host-detail / job-log + lock components
Five hi-fi screens completing the Phase 1 surface, all in v1's dark
operator-console register.
v1-login Sparse centred card. Sign-in + first-error variant.
No marketing chrome; build version sits in footer
so a returning operator can spot agent drift.
v1-add-host Focused two-column page (form left, contextual
"what happens next" right) — not a modal. Two
states: form (state A) and minted-token result
with install command (state B). Backed by
POST /api/enrollment-tokens (P1-32).
v1-host-detail Persistent header (status dot, mono name, tags,
primary CTAs, vitals strip) over four sub-tabs
(Snapshots / Jobs / Repo / Settings). Snapshots
is the default — the thing 90% of operators
want when they click a host name. Right rail
holds Recent activity, run-now stack, and a
danger-zone panel.
v1-job-log WS-streamed log view. Three states: running (live
progress bar + auto-scroll cursor), succeeded
(summary stats + final lines), failed (error
panel + tail). Backed by WS /api/jobs/{id}/stream
(P1-21 remainder).
v1-components The load-bearing reference. 14 sections covering
tokens (colour + type scale), status, buttons,
form fields, tags, tabs, host row, log viewer,
progress bar, stat tile, modal, toast, install
snippet, empty-state pattern. Every CSS class is
real and copy-able into the Go template build.
This locks the visual register before P1-23 onwards. Each Phase 1
template gets a {{define}} matching a section in v1-components.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>restic-manager · v1 Host detail</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg: oklch(0.17 0.006 250); --panel: oklch(0.20 0.007 250); --panel-hi: oklch(0.23 0.008 250);
|
||||
--line: oklch(0.27 0.010 250); --line-soft: oklch(0.23 0.008 250);
|
||||
--ink: oklch(0.96 0.005 250); --ink-mid: oklch(0.78 0.005 250);
|
||||
--ink-mute: oklch(0.58 0.006 250); --ink-fade: oklch(0.42 0.006 250);
|
||||
--ok: oklch(0.78 0.14 155); --warn: oklch(0.82 0.13 80); --bad: oklch(0.70 0.20 25);
|
||||
--off: oklch(0.50 0.005 250); --accent: oklch(0.82 0.12 195);
|
||||
}
|
||||
html, body { background: var(--bg); color: var(--ink); }
|
||||
body { font-family: 'Inter', system-ui, sans-serif; }
|
||||
.mono { font-family: 'JetBrains Mono', monospace; font-variant-numeric: tabular-nums; }
|
||||
.text-pretty { text-wrap: pretty; }
|
||||
::selection { background: color-mix(in oklch, var(--accent), transparent 70%); }
|
||||
|
||||
.panel { background: var(--panel); border: 1px solid var(--line-soft); }
|
||||
.hairline { box-shadow: inset 0 -1px 0 var(--line-soft); }
|
||||
|
||||
.dot { width: 7px; height: 7px; border-radius: 9999px; display: inline-block; }
|
||||
.dot-online { background: var(--ok); box-shadow: 0 0 0 3px color-mix(in oklch, var(--ok), transparent 80%); }
|
||||
.dot-degraded { background: var(--warn); box-shadow: 0 0 0 3px color-mix(in oklch, var(--warn), transparent 80%); }
|
||||
.dot-offline { background: var(--off); }
|
||||
.dot-failed { background: var(--bad); box-shadow: 0 0 0 3px color-mix(in oklch, var(--bad), transparent 80%); }
|
||||
|
||||
.btn {
|
||||
font-size: 12px; font-weight: 500; padding: 6px 11px; border-radius: 5px;
|
||||
background: transparent; border: 1px solid var(--line); color: var(--ink-mid);
|
||||
transition: all 120ms ease; cursor: pointer;
|
||||
}
|
||||
.btn:hover { background: var(--panel-hi); color: var(--ink); }
|
||||
.btn-primary { color: oklch(0.18 0.01 195); background: var(--accent); border-color: var(--accent); }
|
||||
.btn-primary:hover { filter: brightness(1.08); }
|
||||
.btn-ghost { border-color: transparent; }
|
||||
.btn-ghost:hover { background: var(--panel-hi); border-color: transparent; }
|
||||
.btn-danger { color: var(--bad); border-color: color-mix(in oklch, var(--bad), transparent 70%); }
|
||||
.btn-danger:hover { background: color-mix(in oklch, var(--bad), transparent 88%); border-color: color-mix(in oklch, var(--bad), transparent 50%); color: oklch(0.85 0.10 25); }
|
||||
|
||||
.nav-tab { font-size: 13px; padding: 18px 0; color: var(--ink-mute); border-bottom: 2px solid transparent; margin-right: 28px; cursor: pointer; }
|
||||
.nav-tab.active { color: var(--ink); border-color: var(--accent); }
|
||||
.nav-tab:hover { color: var(--ink); }
|
||||
|
||||
/* secondary tabs (within host detail) */
|
||||
.sub-tab {
|
||||
font-size: 13px; padding: 12px 0; color: var(--ink-mute);
|
||||
border-bottom: 1.5px solid transparent; margin-right: 24px; cursor: pointer;
|
||||
letter-spacing: 0.005em;
|
||||
}
|
||||
.sub-tab.active { color: var(--ink); border-color: var(--ink); }
|
||||
.sub-tab:hover { color: var(--ink); }
|
||||
|
||||
.tag {
|
||||
font-size: 11px; line-height: 1; padding: 4px 7px;
|
||||
border: 1px solid var(--line); color: var(--ink-mid);
|
||||
border-radius: 3px; letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.doc { max-width: 1280px; margin: 0 auto; padding: 0 32px; }
|
||||
.philosophy { padding: 56px 0 32px; border-bottom: 1px solid var(--line-soft); }
|
||||
.philosophy h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
||||
.philosophy p { color: var(--ink-mid); max-width: 680px; margin-top: 14px; line-height: 1.65; text-wrap: pretty; }
|
||||
.philosophy .meta { color: var(--ink-fade); font-size: 12px; margin-top: 14px; }
|
||||
.stage-frame { margin: 48px -32px; border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
|
||||
|
||||
.crumbs { font-size: 12px; color: var(--ink-mute); }
|
||||
.crumbs a { color: var(--ink-mute); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line); }
|
||||
.crumbs .sep { color: var(--ink-fade); margin: 0 8px; }
|
||||
|
||||
/* snapshots table */
|
||||
.snap-row { display: grid; align-items: center;
|
||||
grid-template-columns: 0.8fr 1fr 2fr 0.7fr 0.7fr 0.7fr;
|
||||
padding: 10px 16px; font-size: 13px; border-left: 3px solid transparent;
|
||||
}
|
||||
.snap-row:hover { background: var(--panel-hi); }
|
||||
.snap-row.head { padding-top: 9px; padding-bottom: 9px; font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="doc">
|
||||
|
||||
<header class="philosophy">
|
||||
<div class="text-xs uppercase tracking-[0.18em] text-[color:var(--ink-fade)] mb-3">v1 · Host detail</div>
|
||||
<h1>One host, every angle.</h1>
|
||||
<p>
|
||||
Reached by clicking any host name on the dashboard. Persistent header
|
||||
carries the host’s identity and key vitals; below, four tabs
|
||||
(<em>Snapshots / Jobs / Repo / Settings</em>) pivot the rest of the page
|
||||
without losing context. <em>Snapshots</em> is the default — it’s the
|
||||
thing 90% of operators want to see when they click a host name.
|
||||
</p>
|
||||
<p class="meta">
|
||||
The right-rail action stack stays present across all four tabs so
|
||||
“Run backup now” and “Edit credentials” are always one click away. The
|
||||
snapshot rows themselves are clickable — they lead to the restore wizard
|
||||
(P3-01) when that lands.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="stage-frame">
|
||||
<div style="background: var(--bg);">
|
||||
|
||||
<!-- chrome -->
|
||||
<div class="hairline" style="background: var(--bg);">
|
||||
<div class="doc flex items-center justify-between" style="padding: 16px 0;">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="mono" style="font-size:13px; color: var(--ink); font-weight:500;">restic-manager</div>
|
||||
<div class="mono" style="font-size:11px; color: var(--ink-fade);">v0.1.0-alpha</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-5">
|
||||
<div class="mono" style="font-size:12px; color: var(--ink-mute);">steve@dcglab</div>
|
||||
<button class="btn btn-ghost">Sign out</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hairline" style="background: var(--bg);">
|
||||
<div class="doc flex items-end">
|
||||
<nav class="flex items-end">
|
||||
<div class="nav-tab active">Dashboard</div>
|
||||
<div class="nav-tab">Repos</div>
|
||||
<div class="nav-tab">Alerts <span class="mono ml-1.5" style="font-size:11px; color: var(--bad);">5</span></div>
|
||||
<div class="nav-tab">Audit</div>
|
||||
<div class="nav-tab">Settings</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- host header -->
|
||||
<div class="doc" style="padding: 28px 32px 0;">
|
||||
<div class="crumbs"><a>Dashboard</a><span class="sep">/</span><span style="color: var(--ink-mid);">prod-db-01</span></div>
|
||||
|
||||
<div class="flex items-start justify-between" style="margin-top: 14px;">
|
||||
<div>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="dot dot-online"></span>
|
||||
<h1 class="mono" style="font-size: 26px; font-weight: 500; letter-spacing: 0.005em; color: var(--ink);">prod-db-01</h1>
|
||||
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">db</span></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3" style="margin-top: 12px; font-size: 13px; color: var(--ink-mute);">
|
||||
<span class="mono" style="color: var(--ink-mid);">linux/amd64</span>
|
||||
<span style="color: var(--ink-fade);">·</span>
|
||||
<span>agent <span class="mono" style="color: var(--ink-mid);">v0.1.0</span></span>
|
||||
<span style="color: var(--ink-fade);">·</span>
|
||||
<span>restic <span class="mono" style="color: var(--ink-mid);">0.17.3</span></span>
|
||||
<span style="color: var(--ink-fade);">·</span>
|
||||
<span>last seen <span class="mono" style="color: var(--ink-mid);">3s ago</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button class="btn btn-primary">Run backup now</button>
|
||||
<button class="btn">Edit credentials</button>
|
||||
<button class="btn btn-ghost" style="font-size: 14px; padding: 6px 10px;">⋯</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- key vitals strip -->
|
||||
<div class="grid grid-cols-12 gap-6" style="margin-top: 24px; padding: 18px 0; border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft);">
|
||||
<div class="col-span-3">
|
||||
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em;">Last backup</div>
|
||||
<div class="mono" style="font-size: 18px; color: var(--ink); margin-top: 4px;"><span style="color: var(--ok);">succeeded</span> · 3m ago</div>
|
||||
<div style="font-size: 11.5px; color: var(--ink-mute); margin-top: 2px;">1.4 GB transferred · 38s</div>
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em;">Repo size</div>
|
||||
<div class="mono" style="font-size: 18px; color: var(--ink); margin-top: 4px;">412 <span style="font-size: 12px; color: var(--ink-mute);">GB</span></div>
|
||||
<div style="font-size: 11.5px; color: var(--ink-mute); margin-top: 2px;">dedup ratio 6.4×</div>
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em;">Snapshots</div>
|
||||
<div class="mono" style="font-size: 18px; color: var(--ink); margin-top: 4px;">1,847</div>
|
||||
<div style="font-size: 11.5px; color: var(--ink-mute); margin-top: 2px;">oldest 18 months ago</div>
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em;">Repo health</div>
|
||||
<div class="mono" style="font-size: 18px; color: var(--ok); margin-top: 4px;">unlocked · ok</div>
|
||||
<div style="font-size: 11.5px; color: var(--ink-mute); margin-top: 2px;">last <span class="mono">restic check</span> 4d ago</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- secondary tabs -->
|
||||
<div class="flex items-end" style="margin-top: 6px;">
|
||||
<div class="sub-tab active">Snapshots <span class="mono" style="color: var(--ink-fade); font-size: 11px; margin-left: 4px;">1,847</span></div>
|
||||
<div class="sub-tab">Jobs <span class="mono" style="color: var(--ink-fade); font-size: 11px; margin-left: 4px;">47 in 24h</span></div>
|
||||
<div class="sub-tab">Repo</div>
|
||||
<div class="sub-tab">Settings</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- snapshots tab body -->
|
||||
<div class="doc grid grid-cols-12 gap-6" style="padding: 24px 32px 56px; align-items: start;">
|
||||
|
||||
<!-- main column: snapshots table -->
|
||||
<div class="col-span-9">
|
||||
<div class="flex items-center justify-between" style="margin-bottom: 14px;">
|
||||
<div class="flex items-center gap-3">
|
||||
<h2 style="font-size: 13px; font-weight: 600; letter-spacing: 0.01em;">Snapshots</h2>
|
||||
<div style="font-size: 12px; color: var(--ink-fade);">showing 12 of 1,847</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="text" placeholder="filter by path, tag, hostname…"
|
||||
class="mono"
|
||||
style="padding: 5px 10px; font-size: 12px; background: var(--panel); border: 1px solid var(--line-soft); color: var(--ink); border-radius: 5px; width: 280px; outline: none;"
|
||||
/>
|
||||
<button class="btn">Date range ▾</button>
|
||||
<button class="btn">Sort: newest ▾</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" style="border-radius: 7px; overflow: hidden;">
|
||||
<div class="snap-row head hairline">
|
||||
<div>Snapshot id</div>
|
||||
<div>Time</div>
|
||||
<div>Paths</div>
|
||||
<div class="text-right">Size</div>
|
||||
<div class="text-right">Files</div>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
<!-- 12 rows -->
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">91bbc80d</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 11:43:21</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,418</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">7a3c1f88</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 11:13:09</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,417</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">f50e2bbc</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 10:43:02</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,415</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">2d916ae4</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 10:12:47</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,415</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">b0c4e1f2</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 09:42:18</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,414</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">a8801c3f</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 09:11:55</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,414</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">e91f4d72</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 08:42:01</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,412</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">3d44a9e8</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 08:11:33</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,412</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">4f8c0c11</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 07:42:08</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,410</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">c113c3d2</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 07:11:42</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,410</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row hairline">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">9be1aa0d</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 06:42:11</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,408</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
<div class="snap-row">
|
||||
<div class="mono" style="color: var(--ink); font-weight: 500;">2eaf9c50</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">2026-05-01 06:12:49</div>
|
||||
<div class="mono" style="color: var(--ink-mid); font-size: 12px;">/var/lib/postgresql · /etc/postgresql</div>
|
||||
<div class="text-right mono" style="color: var(--ink);">1.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
|
||||
<div class="text-right mono" style="color: var(--ink-mid);">12,408</div>
|
||||
<div class="text-right"><button class="btn btn-ghost">Restore →</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- pagination footer -->
|
||||
<div class="flex items-center justify-between" style="padding: 16px 4px; font-size: 12px; color: var(--ink-mute);">
|
||||
<span>showing snapshots 1–12 of 1,847</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<button class="btn btn-ghost" disabled style="opacity: 0.4;">← previous</button>
|
||||
<button class="btn btn-ghost">next →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- right rail -->
|
||||
<aside class="col-span-3" style="display: flex; flex-direction: column; gap: 16px;">
|
||||
|
||||
<!-- recent activity preview -->
|
||||
<div class="panel" style="border-radius: 7px; padding: 14px 16px;">
|
||||
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 10px;">Recent activity</div>
|
||||
<div style="font-size: 12px; line-height: 1.7;">
|
||||
<div class="mono"><span style="color: var(--ok);">●</span> backup ok <span style="color: var(--ink-fade);">·</span> <span style="color: var(--ink-mute);">3m ago</span></div>
|
||||
<div class="mono"><span style="color: var(--ok);">●</span> backup ok <span style="color: var(--ink-fade);">·</span> <span style="color: var(--ink-mute);">33m ago</span></div>
|
||||
<div class="mono"><span style="color: var(--ok);">●</span> backup ok <span style="color: var(--ink-fade);">·</span> <span style="color: var(--ink-mute);">1h ago</span></div>
|
||||
<div class="mono"><span style="color: var(--ok);">●</span> check ok <span style="color: var(--ink-fade);">·</span> <span style="color: var(--ink-mute);">4d ago</span></div>
|
||||
<div class="mono"><span style="color: var(--ok);">●</span> forget ok <span style="color: var(--ink-fade);">·</span> <span style="color: var(--ink-mute);">7d ago</span></div>
|
||||
</div>
|
||||
<a class="text-xs" style="color: var(--ink-mute); display: inline-block; margin-top: 10px; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line);">View all jobs →</a>
|
||||
</div>
|
||||
|
||||
<!-- Run-now actions -->
|
||||
<div class="panel" style="border-radius: 7px; padding: 14px 16px;">
|
||||
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 10px;">Run-now</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 6px;">
|
||||
<button class="btn" style="text-align: left; justify-content: flex-start; width: 100%;">backup</button>
|
||||
<button class="btn" style="text-align: left; justify-content: flex-start; width: 100%;">forget</button>
|
||||
<button class="btn" style="text-align: left; justify-content: flex-start; width: 100%;">prune <span style="font-size: 10px; color: var(--ink-fade); margin-left: 6px;">admin only</span></button>
|
||||
<button class="btn" style="text-align: left; justify-content: flex-start; width: 100%;">check</button>
|
||||
<button class="btn" style="text-align: left; justify-content: flex-start; width: 100%;">unlock</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Danger zone -->
|
||||
<div class="panel" style="border-radius: 7px; padding: 14px 16px;">
|
||||
<div style="font-size: 11px; color: var(--bad); text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 10px; font-weight: 600;">Danger zone</div>
|
||||
<p style="font-size: 12px; color: var(--ink-mute); line-height: 1.6; margin-bottom: 12px;" class="text-pretty">
|
||||
Removes the host record. The repo data on the rest-server is left intact —
|
||||
you delete that yourself.
|
||||
</p>
|
||||
<button class="btn btn-danger" style="width: 100%;">Remove host…</button>
|
||||
</div>
|
||||
|
||||
</aside>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user