Initial commit: IT Nexus Web-App

This commit is contained in:
2026-06-01 20:49:07 +02:00
commit 8023765e6c
387 changed files with 106900 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
{{define "content"}}
<div class="page-header">
<div>
<h2 class="page-title">Geräte-Inventar</h2>
<p class="page-sub">{{.TotalHosts}} Einträge · zuletzt aktualisiert {{.LastScan}}</p>
</div>
<div style="display:flex;gap:8px;">
<a href="/assets/export.csv" class="btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
CSV Export
</a>
</div>
</div>
<!-- Filter bar -->
<div class="card" style="margin-bottom:16px;overflow:visible;">
<form method="GET" action="/assets">
<div class="filter-bar">
<div class="search-wrap">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
<input class="input" type="search" name="q" value="{{.Query}}" placeholder="IP, Hostname oder MAC…">
</div>
<div style="display:flex;align-items:center;gap:6px;">
<span style="font-size:12px;color:var(--text-3);white-space:nowrap;">Standort:</span>
<div class="filter-chips">
<button type="submit" name="site" value="" class="chip{{if eq .SiteFilter ""}} active{{end}}">Alle</button>
<button type="submit" name="site" value="LUD" class="chip{{if eq .SiteFilter "LUD"}} active{{end}}">Lüdenscheid</button>
<button type="submit" name="site" value="BAR" class="chip{{if eq .SiteFilter "BAR"}} active{{end}}">Barleben</button>
</div>
</div>
<div style="display:flex;align-items:center;gap:6px;">
<span style="font-size:12px;color:var(--text-3);white-space:nowrap;">Status:</span>
<div class="filter-chips">
<button type="submit" name="status" value="" class="chip{{if eq .StatusFilter ""}} active{{end}}">Alle</button>
<button type="submit" name="status" value="online" class="chip{{if eq .StatusFilter "online"}} active{{end}}">Online</button>
<button type="submit" name="status" value="offline" class="chip{{if eq .StatusFilter "offline"}} active{{end}}">Offline</button>
</div>
</div>
<input type="hidden" name="site" value="{{.SiteFilter}}">
<input type="hidden" name="status" value="{{.StatusFilter}}">
</div>
</form>
</div>
<!-- Table -->
<div class="card">
<table>
<thead>
<tr>
<th style="padding-left:20px;">IP-Adresse</th>
<th>MAC-Adresse</th>
<th>Hersteller</th>
<th>Hostname</th>
<th>Offene Ports</th>
<th>Standort</th>
<th>Zuletzt gesehen</th>
<th style="padding-right:20px;">Status</th>
</tr>
</thead>
<tbody>
{{range .Hosts}}
<tr>
<td style="padding-left:20px;" class="mono" style="font-weight:600;">{{.IP}}</td>
<td class="mono" style="color:var(--text-3);">{{.MAC}}</td>
<td>
<div class="device-row">
<div class="device-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<rect x="2" y="3" width="20" height="8" rx="2"/><rect x="2" y="13" width="20" height="8" rx="2"/><path d="M6 7h.01M6 17h.01"/>
</svg>
</div>
<span style="color:var(--text-2);">{{if .Vendor}}{{.Vendor}}{{else}}<span style="color:var(--text-3);"></span>{{end}}</span>
</div>
</td>
<td style="color:var(--text-2);font-size:12.5px;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">{{if .Hostname}}{{.Hostname}}{{else}}<span style="color:var(--text-3);"></span>{{end}}</td>
<td>
{{if .OpenPorts}}
<div style="display:flex;flex-wrap:wrap;gap:3px;">
{{range .OpenPorts}}<span style="background:var(--teal-50);color:var(--teal);border-radius:3px;padding:1px 5px;font-size:10px;font-family:monospace;font-weight:600;">{{.}}</span>{{end}}
</div>
{{else}}<span style="color:var(--text-3);"></span>{{end}}
</td>
<td><span class="badge badge-gray">{{.Site}}</span></td>
<td style="color:var(--text-3);font-size:12px;">{{.LastSeenFmt}}</td>
<td style="padding-right:20px;">
{{if eq .Status "online"}}
<span class="badge badge-green"><span class="dot green" style="width:5px;height:5px;margin-right:4px;"></span>Online</span>
{{else}}
<span class="badge badge-gray"><span class="dot gray" style="width:5px;height:5px;margin-right:4px;"></span>Offline</span>
{{end}}
</td>
</tr>
{{else}}
<tr><td colspan="8" style="text-align:center;padding:48px;color:var(--text-3);">
Keine Geräte gefunden.
</td></tr>
{{end}}
</tbody>
</table>
{{if gt .TotalPages 1}}
<div style="display:flex;align-items:center;justify-content:space-between;padding:12px 20px;border-top:1px solid var(--border);background:var(--surface-2);">
<span style="font-size:12.5px;color:var(--text-3);">
Zeige {{if gt .TotalHosts 0}}{{inc (mul (dec .PageNum) 20)}}{{end}}{{.TotalHosts}} Einträge
</span>
<div class="pagination">
{{if gt .PageNum 1}}
<a href="/assets?{{.QueryString}}&page={{dec .PageNum}}" class="page-btn"></a>
{{else}}
<button class="page-btn" disabled></button>
{{end}}
{{range .Pages}}
<a href="/assets?{{$.QueryString}}&page={{.}}" class="page-btn{{if eq . $.PageNum}} active{{end}}">{{.}}</a>
{{end}}
{{if lt .PageNum .TotalPages}}
<a href="/assets?{{.QueryString}}&page={{inc .PageNum}}" class="page-btn"></a>
{{else}}
<button class="page-btn" disabled></button>
{{end}}
</div>
</div>
{{end}}
</div>
{{end}}