Files
infix/src/webui/templates/layouts/sidebar.html
T
Joachim Wiberg f2f52f8518 webui: sidebar fixes, content sectioning, and theme fixes
Drop the useless 768–1024px icon-only sidebar mode; everything up to
1024px now uses the hamburger overlay and full-width sidebar.

Fix the user dropdown on touch devices: click now toggles aria-expanded
so CSS-driven visibility works without hover.  A document click listener
closes the menu when tapping outside.

Give the sidebar proper light/dark tokens instead of hardcoded dark
values. Introduce --sidebar-hover-fg (primary in light, white in dark)
so nav-link hover text is legible in both themes.

Fix dropdown hover background using --border instead of --border-subtle,
which had zero contrast against the surface in dark mode.

Keep active nav link in sync with the current URL via JS so it updates
correctly after htmx navigation instead of staying on the initial
server-rendered page.  Also, add YouTube-style progress when laoding
pages that take time, e.g., Dashboard.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-14 22:07:25 +02:00

178 lines
6.3 KiB
HTML

{{define "sidebar"}}
<nav id="sidebar">
<div class="sidebar-header">
<img src="/assets/img/logo.png" alt="Infix" class="sidebar-logo">
</div>
<div class="sidebar-nav">
<details class="nav-group-top" open>
<summary class="nav-group-summary-top">Status</summary>
<div class="nav-section-label">System</div>
<ul class="nav-group-items">
<li>
<a href="/"
hx-get="/"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "dashboard"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/dashboard.svg')"></span>
Dashboard
</a>
</li>
{{if and .Capabilities (.Capabilities.Has "containers")}}
<li>
<a href="/containers"
hx-get="/containers"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "containers"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/containers.svg')"></span>
Containers
</a>
</li>
{{end}}
<li>
<a href="/keystore"
hx-get="/keystore"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "keystore"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/keystore.svg')"></span>
Keystore
</a>
</li>
</ul>
<div class="nav-section-label">Network</div>
<ul class="nav-group-items">
<li>
<a href="/interfaces"
hx-get="/interfaces"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "interfaces"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/interfaces.svg')"></span>
Interfaces
</a>
</li>
<li>
<a href="/routing"
hx-get="/routing"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "routing"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/routing.svg')"></span>
Routing
</a>
</li>
<li>
<a href="/firewall"
hx-get="/firewall"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "firewall"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/firewall.svg')"></span>
Firewall
</a>
</li>
{{if and .Capabilities (.Capabilities.Has "wifi")}}
<li>
<a href="/wifi"
hx-get="/wifi"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "wifi"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/wifi.svg')"></span>
WiFi
</a>
</li>
{{end}}
<li>
<a href="/vpn"
hx-get="/vpn"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "vpn"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/wireguard.svg')"></span>
WireGuard
</a>
</li>
<li>
<a href="/lldp"
hx-get="/lldp"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "lldp"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/lldp.svg')"></span>
LLDP
</a>
</li>
</ul>
<div class="nav-section-label">Services</div>
<ul class="nav-group-items">
<li>
<a href="/dhcp"
hx-get="/dhcp"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "dhcp"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/dhcp.svg')"></span>
DHCP
</a>
</li>
<li>
<a href="/ntp"
hx-get="/ntp"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "ntp"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/ntp.svg')"></span>
NTP
</a>
</li>
</ul>
</details>
<details class="nav-group-top">
<summary class="nav-group-summary-top">Configure</summary>
</details>
<details class="nav-group-top">
<summary class="nav-group-summary-top">Maintenance</summary>
<ul class="nav-group-items">
<li>
<a href="/firmware"
hx-get="/firmware"
hx-target="#content"
hx-push-url="true"
class="nav-link {{if eq .ActivePage "firmware"}}active{{end}}">
<span class="nav-icon" style="--icon: url('/assets/img/icons/firmware.svg')"></span>
Firmware
</a>
</li>
<li>
<a href="/config" class="nav-link" hx-boost="false" download>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex-shrink:0"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
Download Config
</a>
</li>
<li>
<button class="nav-link nav-link-btn nav-link-danger"
hx-post="/reboot"
hx-confirm="Reboot the device?"
hx-target="#content"
hx-swap="innerHTML">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex-shrink:0"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>
Reboot
</button>
</li>
</ul>
</details>
</div>
</nav>
{{end}}