base dashboard and login
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
{{define "base"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{.Title}} — CrowdSec Dashy</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=JetBrains+Mono:wght@400;600&display=swap">
|
||||
<link rel="stylesheet" href="/static/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<div style="display:flex;height:100vh;overflow:hidden">
|
||||
|
||||
<aside class="sidebar" id="sidebar">
|
||||
<div class="sidebar-logo">
|
||||
<div class="logo-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#00d4ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<span class="logo-name">CrowdSec</span>
|
||||
<span class="logo-sub">Dashy</span>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
{{range .Nav}}
|
||||
{{if .Divider}}<div class="nav-divider"></div>{{end}}
|
||||
<a href="{{.Path}}" class="nav-item{{if eq $.CurrentPath .Path}} nav-item--active{{end}}">
|
||||
<span class="nav-icon">{{safeHTML .Icon}}</span>
|
||||
{{.Label}}
|
||||
</a>
|
||||
{{end}}
|
||||
</nav>
|
||||
<div class="sidebar-footer">
|
||||
{{if .CLIAvailable}}
|
||||
<div class="cli-badge cli-badge--ok">cscli: available</div>
|
||||
{{else}}
|
||||
<div class="cli-badge cli-badge--warn">cscli: unavailable</div>
|
||||
{{end}}
|
||||
<form method="POST" action="/logout" style="margin-top:10px">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRFToken}}">
|
||||
<button type="submit" class="btn-ghost-sm" style="width:100%;text-align:center;padding:6px 0">Sign out</button>
|
||||
</form>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="sidebar-overlay" id="sidebar-overlay"></div>
|
||||
|
||||
<div style="display:flex;flex-direction:column;flex:1;overflow:hidden">
|
||||
<header class="topbar">
|
||||
<button class="topbar-menu-btn" id="menu-btn" aria-label="Toggle sidebar">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
|
||||
</button>
|
||||
<div class="topbar-breadcrumb">
|
||||
<span class="topbar-page">{{.Title}}</span>
|
||||
</div>
|
||||
<div id="health-badge" class="status-pill status-pill--loading">
|
||||
<span class="status-dot"></span>checking
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{if .Flash.Message}}
|
||||
<div class="flash flash--{{.Flash.Type}}" id="flash-msg">
|
||||
<span class="flash-text">{{.Flash.Message}}</span>
|
||||
<button class="flash-close" onclick="document.getElementById('flash-msg').remove()">dismiss</button>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<main style="flex:1;overflow-y:auto;padding:20px">
|
||||
{{template "content" .}}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
document.body.classList.add('ready');
|
||||
var btn = document.getElementById('menu-btn');
|
||||
var sb = document.getElementById('sidebar');
|
||||
var ov = document.getElementById('sidebar-overlay');
|
||||
if (btn) {
|
||||
btn.addEventListener('click', function() { sb.classList.toggle('open'); ov.classList.toggle('open'); });
|
||||
ov.addEventListener('click', function() { sb.classList.remove('open'); ov.classList.remove('open'); });
|
||||
}
|
||||
function checkHealth() {
|
||||
var badge = document.getElementById('health-badge');
|
||||
if (!badge) return;
|
||||
fetch('/api/v1/health').then(function(r) { return r.json(); }).then(function(d) {
|
||||
if (d.healthy) {
|
||||
badge.className = 'status-pill status-pill--healthy';
|
||||
badge.innerHTML = '<span class="status-dot"></span>healthy';
|
||||
} else {
|
||||
badge.className = 'status-pill status-pill--unhealthy';
|
||||
badge.innerHTML = '<span class="status-dot"></span>unhealthy';
|
||||
}
|
||||
}).catch(function() {
|
||||
badge.className = 'status-pill status-pill--unhealthy';
|
||||
badge.innerHTML = '<span class="status-dot"></span>offline';
|
||||
});
|
||||
}
|
||||
checkHealth();
|
||||
setInterval(checkHealth, 30000);
|
||||
})();
|
||||
</script>
|
||||
{{block "scripts" .}}{{end}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user