Files
vibedns/web/templates/partials.html
T
2026-08-16 21:18:45 -05:00

185 lines
8.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{/* Shared building blocks used across pages. */}}
{{define "sidebar"}}
<nav class="sidebar-nav" aria-label="Main navigation">
<a class="sidebar-link {{if eq .Nav "dashboard"}}active{{end}}" href="/">
<i class="bi bi-speedometer2"></i><span>Dashboard</span>
</a>
<div class="sidebar-heading">DNS</div>
<a class="sidebar-link {{if eq .Nav "zones"}}active{{end}}" href="/zones">
<i class="bi bi-diagram-3"></i><span>Forward Zones</span>
</a>
<a class="sidebar-link {{if eq .Nav "zones-reverse"}}active{{end}}" href="/zones/reverse">
<i class="bi bi-arrow-left-right"></i><span>Reverse Zones</span>
</a>
<a class="sidebar-link {{if eq .Nav "records"}}active{{end}}" href="/records">
<i class="bi bi-list-columns-reverse"></i><span>Records</span>
</a>
<a class="sidebar-link {{if eq .Nav "resolver"}}active{{end}}" href="/resolver">
<i class="bi bi-globe2"></i><span>Resolver</span>
</a>
<a class="sidebar-link {{if eq .Nav "cache"}}active{{end}}" href="/cache">
<i class="bi bi-lightning-charge"></i><span>Cache</span>
</a>
<div class="sidebar-heading">Policies</div>
<a class="sidebar-link {{if eq .Nav "networks"}}active{{end}}" href="/policies/networks">
<i class="bi bi-router"></i><span>Client Networks</span>
</a>
<a class="sidebar-link {{if eq .Nav "blacklists"}}active{{end}}" href="/policies/blacklists">
<i class="bi bi-shield-slash"></i><span>Blacklists</span>
</a>
<a class="sidebar-link {{if eq .Nav "allowlists"}}active{{end}}" href="/policies/allowlists">
<i class="bi bi-shield-check"></i><span>Allowlists</span>
</a>
<a class="sidebar-link {{if eq .Nav "policies"}}active{{end}}" href="/policies">
<i class="bi bi-sliders"></i><span>Rules</span>
</a>
<div class="sidebar-heading">Operations</div>
<a class="sidebar-link {{if eq .Nav "querylog"}}active{{end}}" href="/querylog">
<i class="bi bi-journal-text"></i><span>Query Log</span>
</a>
<a class="sidebar-link {{if eq .Nav "audit"}}active{{end}}" href="/audit">
<i class="bi bi-clipboard-check"></i><span>Audit Log</span>
</a>
<a class="sidebar-link {{if eq .Nav "tools"}}active{{end}}" href="/tools">
<i class="bi bi-tools"></i><span>Tools</span>
</a>
<div class="sidebar-heading">Settings</div>
<a class="sidebar-link {{if eq .Nav "settings"}}active{{end}}" href="/settings/dns">
<i class="bi bi-gear"></i><span>Settings</span>
</a>
<a class="sidebar-link {{if eq .Nav "account"}}active{{end}}" href="/account">
<i class="bi bi-person-badge"></i><span>Account</span>
</a>
</nav>
{{end}}
{{/* Page header: title, optional subtitle and a slot for actions. */}}
{{define "pageheader"}}
<div class="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-4">
<div>
<h1 class="page-title">{{.Title}}</h1>
{{if .Subtitle}}<p class="text-body-secondary mb-0">{{.Subtitle}}</p>{{end}}
</div>
{{if .Actions}}<div class="d-flex flex-wrap gap-2">{{.Actions}}</div>{{end}}
</div>
{{end}}
{{/* A statistic tile. Pass: Label, Value, Icon, Sub, Tone. */}}
{{define "stat"}}
<div class="col-6 col-md-4 col-xl-3">
<div class="card stat-card h-100">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start">
<div class="stat-label">{{.Label}}</div>
{{if .Icon}}<i class="bi {{.Icon}} stat-icon {{with .Tone}}text-{{.}}{{end}}"></i>{{end}}
</div>
<div class="stat-value">{{.Value}}</div>
{{if .Sub}}<div class="stat-sub">{{.Sub}}</div>{{end}}
</div>
</div>
</div>
{{end}}
{{/* Empty state. Pass: Icon, Title, Message, optional Action (safe HTML). */}}
{{define "empty"}}
<div class="empty-state text-center py-5">
<i class="bi {{.Icon}} empty-icon"></i>
<h2 class="h5 mt-3 mb-2">{{.Title}}</h2>
<p class="text-body-secondary mx-auto" style="max-width: 34rem;">{{.Message}}</p>
{{if .Action}}<div class="mt-3">{{.Action}}</div>{{end}}
</div>
{{end}}
{{/* Pagination. Pass: P (pagination struct), Q (url.Values). */}}
{{define "pagination"}}
{{$p := .P}}{{$q := .Q}}
{{if gt $p.Pages 1}}
<nav class="d-flex flex-wrap justify-content-between align-items-center gap-2 mt-3" aria-label="Pagination">
<div class="text-body-secondary small">
Showing {{num $p.From}}{{num $p.To}} of {{num $p.Total}}
</div>
<ul class="pagination pagination-sm mb-0">
<li class="page-item {{if not $p.HasPrev}}disabled{{end}}">
<a class="page-link" href="{{withQuery $q "page" 1}}" aria-label="First page">&laquo;</a>
</li>
<li class="page-item {{if not $p.HasPrev}}disabled{{end}}">
<a class="page-link" href="{{withQuery $q "page" (sub $p.Page 1)}}" aria-label="Previous page">&lsaquo;</a>
</li>
{{range $n := pages $p.Page $p.Pages}}
<li class="page-item {{if eq $n $p.Page}}active{{end}}">
<a class="page-link" href="{{withQuery $q "page" $n}}">{{$n}}</a>
</li>
{{end}}
<li class="page-item {{if not $p.HasNext}}disabled{{end}}">
<a class="page-link" href="{{withQuery $q "page" (add $p.Page 1)}}" aria-label="Next page">&rsaquo;</a>
</li>
<li class="page-item {{if not $p.HasNext}}disabled{{end}}">
<a class="page-link" href="{{withQuery $q "page" $p.Pages}}" aria-label="Last page">&raquo;</a>
</li>
</ul>
</nav>
{{else if gt $p.Total 0}}
<div class="text-body-secondary small mt-3">{{num $p.Total}} result{{if ne $p.Total 1}}s{{end}}</div>
{{end}}
{{end}}
{{/* A destructive submit button that opens the shared confirmation modal.
Pass: Action, CSRF, Label, Message, optional Icon, Class, ReturnTo. */}}
{{define "confirmform"}}
<form method="post" action="{{.Action}}" class="d-inline js-confirm" data-confirm="{{.Message}}">
<input type="hidden" name="_csrf" value="{{.CSRF}}">
{{if .ReturnTo}}<input type="hidden" name="return_to" value="{{.ReturnTo}}">{{end}}
{{range $k, $v := .Fields}}<input type="hidden" name="{{$k}}" value="{{$v}}">{{end}}
<button type="submit" class="{{if .Class}}{{.Class}}{{else}}btn btn-sm btn-outline-danger{{end}}"
{{if .Title}}title="{{.Title}}"{{end}}>
{{if .Icon}}<i class="bi {{.Icon}}"></i>{{end}}{{if .Label}} {{.Label}}{{end}}
</button>
</form>
{{end}}
{{/* A plain post button with no confirmation. Same fields as confirmform. */}}
{{define "postform"}}
<form method="post" action="{{.Action}}" class="d-inline">
<input type="hidden" name="_csrf" value="{{.CSRF}}">
{{if .ReturnTo}}<input type="hidden" name="return_to" value="{{.ReturnTo}}">{{end}}
{{range $k, $v := .Fields}}<input type="hidden" name="{{$k}}" value="{{$v}}">{{end}}
<button type="submit" class="{{if .Class}}{{.Class}}{{else}}btn btn-sm btn-outline-secondary{{end}}"
{{if .Title}}title="{{.Title}}"{{end}}>
{{if .Icon}}<i class="bi {{.Icon}}"></i>{{end}}{{if .Label}} {{.Label}}{{end}}
</button>
</form>
{{end}}
{{/* Settings sub-navigation. Pass the active key as .Subnav. */}}
{{define "settingsnav"}}
<ul class="nav nav-pills settings-nav mb-4 flex-wrap gap-1">
<li class="nav-item"><a class="nav-link {{if eq .Subnav "dns"}}active{{end}}" href="/settings/dns">DNS</a></li>
<li class="nav-item"><a class="nav-link {{if eq .Subnav "resolver"}}active{{end}}" href="/settings/resolver">Resolver</a></li>
<li class="nav-item"><a class="nav-link {{if eq .Subnav "cache"}}active{{end}}" href="/settings/cache">Cache</a></li>
<li class="nav-item"><a class="nav-link {{if eq .Subnav "http"}}active{{end}}" href="/settings/http">Web Server</a></li>
<li class="nav-item"><a class="nav-link {{if eq .Subnav "logging"}}active{{end}}" href="/settings/logging">Logging</a></li>
<li class="nav-item"><a class="nav-link {{if eq .Subnav "database"}}active{{end}}" href="/settings/database">Database</a></li>
<li class="nav-item"><a class="nav-link {{if eq .Subnav "api"}}active{{end}}" href="/settings/api">API</a></li>
<li class="nav-item"><a class="nav-link {{if eq .Subnav "account"}}active{{end}}" href="/account">Authentication</a></li>
</ul>
{{end}}
{{/* Marks a field that needs a restart to take effect. */}}
{{define "restartbadge"}}
<span class="badge text-bg-warning-subtle border border-warning-subtle text-warning-emphasis ms-1"
title="Changing this requires a restart">restart required</span>
{{end}}