76 lines
4.5 KiB
HTML
76 lines
4.5 KiB
HTML
{{/* html/template requires {{template "name"}} names to be string
|
|
literals, not dynamic pipelines — so a single "layout" wrapper that
|
|
dispatches to a per-page content block by name isn't possible within
|
|
one shared template set. Instead, layout.html provides small named
|
|
partials (html_head, sidebar_nav, topbar_mobile, banner_inner,
|
|
error_banner) that each page's *_page template (see e.g.
|
|
overview.html) assembles around its own *_content block explicitly.
|
|
A few lines of boilerplate are duplicated per page as a result — see
|
|
any *_page define for the pattern. */}}
|
|
|
|
{{define "html_head"}}
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Cloud IP Validator — Admin</title>
|
|
<link rel="stylesheet" href="/static/vendor/fonts.css">
|
|
<link rel="stylesheet" href="/static/dashboard.css">
|
|
<script src="/static/vendor/htmx.min.js"></script>
|
|
<script src="/static/vendor/alpine.min.js" defer></script>
|
|
{{end}}
|
|
|
|
{{define "sidebar_nav"}}
|
|
<aside class="sidebar">
|
|
<div class="brand">
|
|
<span class="brand-mark">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v6M12 16v6M2 12h6M16 12h6"/><circle cx="12" cy="12" r="3"/></svg>
|
|
</span>
|
|
<span class="brand-name">Cloud IP Validator<small>admin</small></span>
|
|
</div>
|
|
|
|
<nav class="nav-groups">
|
|
<a class="nav-link{{if eq .ActiveNav "overview"}} active{{end}}" {{if eq .ActiveNav "overview"}}aria-current="page"{{end}} href="/overview">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="9" rx="1.5"/><rect x="14" y="3" width="7" height="5" rx="1.5"/><rect x="14" y="12" width="7" height="9" rx="1.5"/><rect x="3" y="16" width="7" height="5" rx="1.5"/></svg>
|
|
Обзор
|
|
</a>
|
|
<a class="nav-link{{if eq .ActiveNav "ips"}} active{{end}}" {{if eq .ActiveNav "ips"}}aria-current="page"{{end}} href="/ips">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 10h18M8 4v16"/></svg>
|
|
Очередь IP
|
|
</a>
|
|
<a class="nav-link{{if eq .ActiveNav "validators"}} active{{end}}" {{if eq .ActiveNav "validators"}}aria-current="page"{{end}} href="/validators">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="7" rx="1.5"/><rect x="4" y="14" width="16" height="7" rx="1.5"/><circle cx="8" cy="6.5" r="1"/><circle cx="8" cy="17.5" r="1"/></svg>
|
|
Валидаторы
|
|
</a>
|
|
<a class="nav-link{{if eq .ActiveNav "sites"}} active{{end}}" {{if eq .ActiveNav "sites"}}aria-current="page"{{end}} href="/sites">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2 3 7l9 5 9-5-9-5Z"/><path d="m3 12 9 5 9-5M3 17l9 5 9-5"/></svg>
|
|
Площадки
|
|
</a>
|
|
<a class="nav-link{{if eq .ActiveNav "targets"}} active{{end}}" {{if eq .ActiveNav "targets"}}aria-current="page"{{end}} href="/targets">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4.5"/><circle cx="12" cy="12" r=".6" fill="currentColor"/></svg>
|
|
Цели
|
|
</a>
|
|
<a class="nav-link{{if eq .ActiveNav "check-types"}} active{{end}}" {{if eq .ActiveNav "check-types"}}aria-current="page"{{end}} href="/check-types">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>
|
|
Типы проверок
|
|
</a>
|
|
</nav>
|
|
|
|
<div class="sidebar-foot">
|
|
<span class="pulse-dot"></span>
|
|
control-api
|
|
</div>
|
|
</aside>
|
|
{{end}}
|
|
|
|
{{define "topbar_mobile"}}
|
|
<div class="topbar-mobile">
|
|
<label class="burger" for="nav-toggle">
|
|
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
|
|
</label>
|
|
<strong>Cloud IP Validator</strong>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "banner_inner"}}{{if .Message}}<div class="alert {{if .Client}}alert-warning{{else}}alert-danger{{end}}" role="alert">{{.Message}}</div>{{end}}{{end}}
|
|
|
|
{{define "error_banner"}}<div id="error-banner" hx-swap-oob="true">{{template "banner_inner" .}}</div>{{end}}
|