Initial commit: IT Nexus Web-App
This commit is contained in:
219
nexus-scanner/internal/web/templates/setup.html
Normal file
219
nexus-scanner/internal/web/templates/setup.html
Normal file
@@ -0,0 +1,219 @@
|
||||
{{define "setup"}}
|
||||
<!DOCTYPE html>
|
||||
<html data-theme="light">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Einrichtung — Nexus Scanner</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<script>(function(){ var t=localStorage.getItem('nx-theme')||'light'; document.documentElement.setAttribute('data-theme',t); })();</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wizard-wrap">
|
||||
<div class="wizard">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="wizard-header">
|
||||
<div style="display:flex;align-items:center;gap:10px;">
|
||||
<div class="brand-mark" style="width:28px;height:28px;border-radius:7px;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" style="width:15px;height:15px;color:#fff;"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
|
||||
</div>
|
||||
<span style="font-size:13px;font-weight:600;color:var(--text-2);">Nexus Scanner</span>
|
||||
</div>
|
||||
<div class="wizard-steps">
|
||||
{{range $i, $_ := .Steps}}
|
||||
<div class="wizard-step{{if lt $i $.Step}} done{{else if eq $i $.Step}} active{{end}}"></div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if eq .Step 0}}
|
||||
<!-- Schritt 1: Standort -->
|
||||
<div class="wizard-body">
|
||||
<div class="wizard-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
|
||||
</div>
|
||||
<h2 class="wizard-title">Willkommen beim Nexus Scanner.</h2>
|
||||
<p class="wizard-sub">Wähle zuerst deinen Standort.</p>
|
||||
<form method="POST" action="/setup" id="f">
|
||||
<input type="hidden" name="step" value="0">
|
||||
<div class="site-cards">
|
||||
<label class="site-card{{if eq .Site "LUD"}} selected{{end}}" onclick="sel(this,'LUD')">
|
||||
<input type="radio" name="site" value="LUD" style="display:none;"{{if eq .Site "LUD"}} checked{{end}}>
|
||||
<div class="site-card-name">Lüdenscheid</div>
|
||||
<div class="site-card-sub">LUD · 192.168.0.0/24</div>
|
||||
</label>
|
||||
<label class="site-card{{if eq .Site "BAR"}} selected{{end}}" onclick="sel(this,'BAR')">
|
||||
<input type="radio" name="site" value="BAR" style="display:none;"{{if eq .Site "BAR"}} checked{{end}}>
|
||||
<div class="site-card-name">Barleben</div>
|
||||
<div class="site-card-sub">BAR · 192.168.10.0/24</div>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="wizard-footer">
|
||||
<span style="font-size:12.5px;color:var(--text-3);">Schritt 1 von {{len .Steps}}</span>
|
||||
<button form="f" type="submit" name="next" value="1" class="btn btn-primary">
|
||||
Weiter <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{else if eq .Step 1}}
|
||||
<!-- Schritt 2: Netzwerk -->
|
||||
<div class="wizard-body">
|
||||
<div class="wizard-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2"/><rect x="2" y="14" width="20" height="8" rx="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg>
|
||||
</div>
|
||||
<h2 class="wizard-title">Netzwerk konfigurieren.</h2>
|
||||
<p class="wizard-sub">Welches Subnetz soll gescannt werden?</p>
|
||||
{{if .Error}}<div class="error-msg" style="margin-bottom:14px;">{{.Error}}</div>{{end}}
|
||||
<form method="POST" action="/setup" id="f">
|
||||
<input type="hidden" name="step" value="1">
|
||||
<input type="hidden" name="site" value="{{.Site}}">
|
||||
<div class="form-group">
|
||||
<label class="input-label">Subnetz (CIDR)</label>
|
||||
<input class="input" type="text" name="subnet" value="{{.Subnet}}" placeholder="192.168.0.0/24" required autofocus>
|
||||
<p style="font-size:12px;color:var(--text-3);margin-top:5px;">Beispiel: 192.168.0.0/24 scannt 254 Adressen.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="input-label">Netzwerk-Interface</label>
|
||||
<select class="select" name="interface">
|
||||
{{range .Interfaces}}
|
||||
<option value="{{.}}"{{if eq . $.Interface}} selected{{end}}>{{.}}</option>
|
||||
{{end}}
|
||||
{{if not .Interfaces}}<option value="eth0">eth0</option>{{end}}
|
||||
</select>
|
||||
<p style="font-size:12px;color:var(--text-3);margin-top:5px;">Automatisch erkannt — wähle das Interface zum LAN.</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="wizard-footer">
|
||||
<a href="/setup?step=0" class="btn">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M19 12H5M12 19l-7-7 7-7"/></svg> Zurück
|
||||
</a>
|
||||
<div style="display:flex;align-items:center;gap:12px;">
|
||||
<span style="font-size:12.5px;color:var(--text-3);">Schritt 2 von {{len .Steps}}</span>
|
||||
<button form="f" type="submit" name="next" value="2" class="btn btn-primary">
|
||||
Weiter <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{else if eq .Step 2}}
|
||||
<!-- Schritt 3: IT Nexus API -->
|
||||
<div class="wizard-body">
|
||||
<div class="wizard-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
|
||||
</div>
|
||||
<h2 class="wizard-title">IT Nexus verbinden.</h2>
|
||||
<p class="wizard-sub">Optional — kann auch später konfiguriert werden.</p>
|
||||
<form method="POST" action="/setup" id="f">
|
||||
<input type="hidden" name="step" value="2">
|
||||
<input type="hidden" name="site" value="{{.Site}}">
|
||||
<input type="hidden" name="subnet" value="{{.Subnet}}">
|
||||
<input type="hidden" name="interface" value="{{.Interface}}">
|
||||
<div class="form-group">
|
||||
<label class="input-label">IT Nexus API URL</label>
|
||||
<input class="input" type="url" name="nexus_url" value="{{.NexusURL}}" placeholder="https://it-nexus.cereda-systems.de">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="input-label">API Key</label>
|
||||
<input class="input" type="password" name="nexus_api_key" value="{{.NexusAPIKey}}" placeholder="nsx-…">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="wizard-footer">
|
||||
<a href="/setup?step=1" class="btn">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M19 12H5M12 19l-7-7 7-7"/></svg> Zurück
|
||||
</a>
|
||||
<div style="display:flex;align-items:center;gap:12px;">
|
||||
<span style="font-size:12.5px;color:var(--text-3);">Schritt 3 von {{len .Steps}}</span>
|
||||
<button form="f" type="submit" name="next" value="3" class="btn btn-primary">
|
||||
Weiter <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{else if eq .Step 3}}
|
||||
<!-- Schritt 4: Passwort -->
|
||||
<div class="wizard-body">
|
||||
<div class="wizard-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
||||
</div>
|
||||
<h2 class="wizard-title">Passwort festlegen.</h2>
|
||||
<p class="wizard-sub">Mindestens 6 Zeichen für den Web-Login.</p>
|
||||
{{if .Error}}<div class="error-msg" style="margin-bottom:14px;">{{.Error}}</div>{{end}}
|
||||
<form method="POST" action="/setup" id="f">
|
||||
<input type="hidden" name="step" value="3">
|
||||
<input type="hidden" name="site" value="{{.Site}}">
|
||||
<input type="hidden" name="subnet" value="{{.Subnet}}">
|
||||
<input type="hidden" name="interface" value="{{.Interface}}">
|
||||
<input type="hidden" name="nexus_url" value="{{.NexusURL}}">
|
||||
<input type="hidden" name="nexus_api_key" value="{{.NexusAPIKey}}">
|
||||
<div class="form-group">
|
||||
<label class="input-label">Passwort</label>
|
||||
<input class="input" type="password" name="password" placeholder="Mindestens 6 Zeichen" minlength="6" required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="input-label">Bestätigung</label>
|
||||
<input class="input" type="password" name="confirm" placeholder="Passwort wiederholen" required>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="wizard-footer">
|
||||
<a href="/setup?step=2" class="btn">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M19 12H5M12 19l-7-7 7-7"/></svg> Zurück
|
||||
</a>
|
||||
<div style="display:flex;align-items:center;gap:12px;">
|
||||
<span style="font-size:12.5px;color:var(--text-3);">Schritt 4 von {{len .Steps}}</span>
|
||||
<button form="f" type="submit" name="next" value="4" class="btn btn-primary">
|
||||
Weiter <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{else}}
|
||||
<!-- Schritt 5: Fertig -->
|
||||
<div class="wizard-body">
|
||||
<div class="wizard-icon" style="background:rgba(52,168,83,.12);color:var(--success);">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
|
||||
</div>
|
||||
<h2 class="wizard-title">Alles bereit.</h2>
|
||||
<p class="wizard-sub">Der Scanner ist konfiguriert und startet jetzt.</p>
|
||||
<div style="display:flex;flex-direction:column;gap:10px;font-size:13px;margin-top:16px;">
|
||||
<div style="display:flex;align-items:center;gap:8px;"><span class="badge badge-teal">{{.Site}}</span><span style="color:var(--text-2);">Standort</span></div>
|
||||
<div style="display:flex;align-items:center;gap:8px;"><span class="badge badge-green">{{.Subnet}}</span><span style="color:var(--text-2);">Subnetz</span></div>
|
||||
{{if .NexusURL}}<div style="display:flex;align-items:center;gap:8px;"><span class="badge badge-green">Verbunden</span><span style="color:var(--text-2);">IT Nexus API</span></div>{{end}}
|
||||
<div style="display:flex;align-items:center;gap:8px;"><span class="badge badge-green">✓</span><span style="color:var(--text-2);">Passwort gesetzt</span></div>
|
||||
</div>
|
||||
<form method="POST" action="/setup/complete" id="f">
|
||||
<input type="hidden" name="step" value="4">
|
||||
<input type="hidden" name="site" value="{{.Site}}">
|
||||
<input type="hidden" name="subnet" value="{{.Subnet}}">
|
||||
<input type="hidden" name="interface" value="{{.Interface}}">
|
||||
<input type="hidden" name="nexus_url" value="{{.NexusURL}}">
|
||||
<input type="hidden" name="nexus_api_key" value="{{.NexusAPIKey}}">
|
||||
<input type="hidden" name="password" value="{{.Password}}">
|
||||
</form>
|
||||
</div>
|
||||
<div class="wizard-footer" style="justify-content:center;">
|
||||
<button form="f" type="submit" class="btn btn-primary" style="width:100%;justify-content:center;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
||||
Scanner starten
|
||||
</button>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
</div><!-- .wizard -->
|
||||
</div><!-- .wizard-wrap -->
|
||||
|
||||
<script>
|
||||
function sel(card, site) {
|
||||
document.querySelectorAll('.site-card').forEach(c => c.classList.remove('selected'));
|
||||
card.classList.add('selected');
|
||||
card.querySelector('input[type=radio]').checked = true;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user