Files
GuacPanel/webgui/templates/dashboard.html
T
njomac 50c125e0db Initial commit — GuacPanel v1.0
All-in-one installer za Apache Guacamole s Nginx reverse proxy,
fail2ban, SSL (Let's Encrypt / Self-signed), GeoIP blokiranjem
i Flask web GUI za upravljanje.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 11:21:44 +02:00

131 lines
4.3 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.
{% extends 'base.html' %}
{% block title %}Dashboard Guacamole Manager{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h4 class="mb-0">Dashboard</h4>
<small class="text-muted">{{ domain }}</small>
</div>
<button class="btn btn-sm btn-outline-secondary" onclick="loadStatus()">
<i class="bi bi-arrow-clockwise"></i> Osvježi
</button>
</div>
<!-- Kontejneri -->
<div class="row g-3 mb-4">
<div class="col-12"><h6 class="text-muted text-uppercase small mb-2">Docker kontejneri</h6></div>
{% for name, label in [('guacamole','Guacamole Web'), ('guacd','Guacd Daemon'), ('guac_postgres','PostgreSQL')] %}
<div class="col-md-4">
<div class="card p-3" id="card-{{ name }}">
<div class="d-flex align-items-center gap-2">
<span class="status-dot status-warn" id="dot-{{ name }}"></span>
<div>
<div class="fw-semibold">{{ label }}</div>
<small class="text-muted" id="txt-{{ name }}">Učitavanje...</small>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<!-- Servisi -->
<div class="row g-3 mb-4">
<div class="col-12"><h6 class="text-muted text-uppercase small mb-2">Sistemski servisi</h6></div>
{% for name, label, icon in [('nginx','Nginx','bi-server'), ('fail2ban','fail2ban','bi-shield'), ('docker','Docker','bi-box')] %}
<div class="col-md-4">
<div class="card p-3">
<div class="d-flex align-items-center gap-2">
<span class="status-dot status-warn" id="dot-svc-{{ name }}"></span>
<div>
<div class="fw-semibold"><i class="bi {{ icon }} me-1"></i>{{ label }}</div>
<small class="text-muted" id="txt-svc-{{ name }}">Učitavanje...</small>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<!-- Info kartice -->
<div class="row g-3">
<div class="col-md-4">
<div class="card p-3">
<div class="d-flex align-items-center gap-3">
<i class="bi bi-globe fs-3 text-info"></i>
<div>
<div class="small text-muted">GeoIP blokiranje</div>
<span id="badge-geoip" class="badge bg-secondary">Provjera...</span>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card p-3">
<div class="d-flex align-items-center gap-3">
<i class="bi bi-lock fs-3 text-success"></i>
<div>
<div class="small text-muted">SSL certifikat</div>
<span id="badge-ssl" class="badge bg-secondary">Provjera...</span>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card p-3">
<div class="d-flex align-items-center gap-3">
<i class="bi bi-shield-x fs-3 text-danger"></i>
<div>
<div class="small text-muted">Zabanjeni IP-ovi</div>
<span id="badge-banned" class="fs-4 fw-bold">...</span>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
async function loadStatus() {
const data = await fetch('/api/status').then(r => r.json());
// Containers
const containers = {
guacamole: data.containers.guacamole,
guacd: data.containers.guacd,
guac_postgres: data.containers.guac_postgres
};
for (const [name, running] of Object.entries(containers)) {
document.getElementById(`dot-${name}`).className =
`status-dot ${running ? 'status-ok' : 'status-err'}`;
document.getElementById(`txt-${name}`).textContent =
running ? 'Aktivan' : 'Nije aktivan';
}
// Services
for (const [name, active] of Object.entries(data.services)) {
document.getElementById(`dot-svc-${name}`).className =
`status-dot ${active ? 'status-ok' : 'status-err'}`;
document.getElementById(`txt-svc-${name}`).textContent =
active ? 'Aktivan' : 'Nije aktivan';
}
// Badges
const geoip = document.getElementById('badge-geoip');
geoip.textContent = data.geoip ? 'Aktivno' : 'Neaktivno';
geoip.className = `badge ${data.geoip ? 'bg-success' : 'bg-secondary'}`;
const ssl = document.getElementById('badge-ssl');
ssl.textContent = data.ssl ? 'Aktivan' : 'Nije aktivan';
ssl.className = `badge ${data.ssl ? 'bg-success' : 'bg-warning text-dark'}`;
document.getElementById('badge-banned').textContent = data.banned;
}
loadStatus();
setInterval(loadStatus, 15000);
</script>
{% endblock %}