219 lines
9.8 KiB
HTML
219 lines
9.8 KiB
HTML
{% extends "sidebar.html" %}
|
|
|
|
{% block title %}AstraOS — Hybrid Dashboard{% endblock %}
|
|
|
|
{% block head %}
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
|
|
<style>
|
|
.glow-card {
|
|
transition: 0.2s ease;
|
|
}
|
|
.glow-card:hover {
|
|
box-shadow: 0 0 20px rgba(192,132,252,0.3);
|
|
transform: translateY(-4px);
|
|
}
|
|
/* Schriftgröße für Systemstatus-Text im Wartungsmodus noch kleiner und mittig */
|
|
#system-status-text.small {
|
|
font-size: 2rem;
|
|
text-align: center;
|
|
margin: 0 auto;
|
|
display: block;
|
|
}
|
|
#system-status-desc .wartung-desc {
|
|
font-size: 0.75rem;
|
|
display: block;
|
|
text-align: center;
|
|
margin: 0 auto;
|
|
font-weight: 500;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<header class="flex justify-between items-center mb-6 opacity-0">
|
|
<h2 class="text-4xl font-bold tracking-wide {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Dashboard</h2>
|
|
</header>
|
|
|
|
<div class="grid grid-cols-1 gap-8">
|
|
<div class="glow-card opacity-0 translate-y-8 lg:col-span-2 bg-black/40 p-6 rounded-xl backdrop-blur
|
|
{% if maintenance_active %}border border-yellow-500/30{% else %}border border-purple-500/20{% endif %}">
|
|
<h3 class="text-2xl font-semibold mb-4">🚀 Willkommen bei AstraOS!</h3>
|
|
<p class="text-gray-300">
|
|
AstraOS ist da! Wir haben alles von Grund auf neu gebaut, damit du deine Systeme noch intuitiver und effizienter verwalten kannst. Wir hoffen, dir gefallen das neue Design und die vielen praktischen Funktionen.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
<!-- Aktive Benutzer -->
|
|
<div class="glow-card opacity-0 translate-y-8 bg-black/40 rounded-xl p-6 backdrop-blur
|
|
{% if maintenance_active %}border border-yellow-500/30{% else %}border border-purple-500/20{% endif %}">
|
|
<h3 class="text-xl font-semibold mb-2 {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Aktive Benutzer</h3>
|
|
<p class="text-4xl font-bold" id="active-users">{{ stats.active_users.value }}</p>
|
|
<p class="text-green-400 text-sm mt-1" id="active-users-percent">
|
|
{% set pct = stats.active_users.percent %}
|
|
{% if pct is not none %}
|
|
{{ '+' if pct>=0 else '' }}{{ pct }}% seit letzter Woche
|
|
{% else %}
|
|
-
|
|
{% endif %}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Server-Auslastung -->
|
|
<div id="server-load-card" class="glow-card opacity-0 translate-y-8 bg-black/40 border border-red-500/40 rounded-xl p-6 backdrop-blur">
|
|
<h3 class="text-xl font-semibold mb-2 {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Server-Auslastung</h3>
|
|
<p class="text-4xl font-bold" id="server-load">{{ stats.server_load.percent }}%</p>
|
|
<p class="text-red-400 text-sm mt-1" id="server-load-status">{{ stats.server_load.status }}</p>
|
|
</div>
|
|
|
|
<!-- Offene Tickets -->
|
|
<div class="glow-card opacity-0 translate-y-8 bg-black/40 rounded-xl p-6 backdrop-blur
|
|
{% if maintenance_active %}border border-yellow-500/30{% else %}border border-purple-500/20{% endif %}">
|
|
<h3 class="text-xl font-semibold mb-2 {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Offene Tickets</h3>
|
|
<p class="text-4xl font-bold" id="open-tickets">{{ stats.open_tickets.count }}</p>
|
|
<p class="text-gray-400 text-sm mt-1">Keine offenen Anfragen</p>
|
|
</div>
|
|
|
|
<!-- Systemstatus -->
|
|
<div id="system-status-card" class="glow-card opacity-0 translate-y-8 bg-black/40 border border-green-500/40 rounded-xl p-6 backdrop-blur">
|
|
<h3 class="text-xl font-semibold mb-2 {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Systemstatus</h3>
|
|
{% set status = stats.system_status.status %}
|
|
<p id="system-status-text"
|
|
class="text-4xl font-bold
|
|
{% if 'online' in status.lower() %}text-green-400
|
|
{% elif 'wartung' in status.lower() or 'systeme im wartungsmodus' in status.lower() %}text-yellow-400 small
|
|
{% else %}text-red-400{% endif %}">
|
|
{{ status }}
|
|
</p>
|
|
<p class="text-gray-400 text-sm mt-1" id="system-status-desc">
|
|
{% if 'wartung' in status.lower() or 'systeme im wartungsmodus' in status.lower() %}
|
|
<span class="wartung-desc">Systeme im Wartungsmodus</span>
|
|
{% elif 'online' in status.lower() %}
|
|
Alle Systeme funktionsfähig
|
|
{% else %}
|
|
Teilweise oder komplett offline
|
|
{% endif %}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Geplante Wartung -->
|
|
<div class="glow-card opacity-0 translate-y-8 bg-black/40 rounded-xl p-6 backdrop-blur
|
|
{% if maintenance_active %}border border-yellow-500/30{% else %}border border-purple-500/20{% endif %}">
|
|
<h3 class="text-xl font-semibold mb-2 {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Geplante Wartung</h3>
|
|
{% set maint = stats.scheduled_maintenance %}
|
|
{% if maint and maint.enabled %}
|
|
<p class="text-2xl font-bold text-yellow-400">Aktiv</p>
|
|
<p class="text-yellow-400 text-sm mt-1">{{ maint.status if maint.status else 'Wartungsarbeiten laufen' }}</p>
|
|
{% elif maint and maint.time_str %}
|
|
<p class="text-2xl font-bold">{{ maint.time_str }}</p>
|
|
<p class="text-yellow-400 text-sm mt-1">{{ maint.status if maint and maint.status else 'Geplant' }} {% if maint and maint.duration_minutes %}— Dauer: {{ maint.duration_minutes }} Min.{% endif %}</p>
|
|
{% else %}
|
|
<p class="text-2xl font-bold">Keine geplant</p>
|
|
<p class="text-gray-400 text-sm mt-1">Alle Systeme sind betriebsbereit.</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Letzte Benutzererstellung -->
|
|
<div class="glow-card opacity-0 translate-y-8 bg-black/40 rounded-xl p-6 backdrop-blur
|
|
{% if maintenance_active %}border border-yellow-500/30{% else %}border border-purple-500/20{% endif %}">
|
|
<h3 class="text-xl font-semibold mb-2 {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Letzte Benutzererstellung</h3>
|
|
{% set last = stats.last_user_created %}
|
|
<p class="text-2xl font-bold" id="last-user-time">{{ last.time_str if last and last.time_str else 'Keine Daten' }}</p>
|
|
<p class="text-gray-400 text-sm mt-1" id="last-user-by">Durch: {{ last.by if last and last.by else 'N/A' }}</p>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
gsap.registerPlugin(ScrollTrigger);
|
|
|
|
// Lade-Timeline
|
|
setTimeout(() => {
|
|
// Timeline für Header + Cards
|
|
const tl = gsap.timeline({ defaults: { duration: 0.4, ease: "power3.out" } });
|
|
|
|
// Header
|
|
tl.to("header", { opacity: 1, y: 0 });
|
|
|
|
// Cards schnell einblenden
|
|
tl.to(".glow-card", { opacity: 1, y: 0, stagger: 0.08 });
|
|
|
|
// Header Parallax
|
|
gsap.to("header", {
|
|
y: 8,
|
|
ease: "none",
|
|
scrollTrigger: {
|
|
trigger: "header",
|
|
start: "top top",
|
|
scrub: true
|
|
}
|
|
});
|
|
}, 800);
|
|
|
|
// Hover Glow
|
|
document.querySelectorAll(".glow-card").forEach(card => {
|
|
card.addEventListener("mouseenter", () => {
|
|
gsap.to(card, { boxShadow: "0 0 30px rgba(192,132,252,0.4)", duration: 0.2 });
|
|
});
|
|
card.addEventListener("mouseleave", () => {
|
|
gsap.to(card, { boxShadow: "0 0 0 rgba(0,0,0,0)", duration: 0.2 });
|
|
});
|
|
});
|
|
|
|
// Server-Auslastung alle 5 Sekunden aktualisieren
|
|
function updateServerLoad() {
|
|
fetch('/api/server_load')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
const loadCard = document.getElementById('server-load-card');
|
|
const loadStatus = document.getElementById('server-load-status');
|
|
|
|
document.getElementById('server-load').textContent = data.percent + '%';
|
|
loadStatus.textContent = data.status;
|
|
|
|
// Klassen für Farben entfernen
|
|
loadCard.classList.remove('border-red-500/40', 'border-green-500/40', 'border-yellow-500/40');
|
|
loadStatus.classList.remove('text-red-400', 'text-green-400', 'text-yellow-400');
|
|
|
|
if (data.status === 'Online') {
|
|
if (data.percent > 75) {
|
|
// Gelb bei hoher Auslastung
|
|
loadCard.classList.add('border-yellow-500/40');
|
|
loadStatus.classList.add('text-yellow-400');
|
|
} else {
|
|
// Grün bei normaler Auslastung
|
|
loadCard.classList.add('border-green-500/40');
|
|
loadStatus.classList.add('text-green-400');
|
|
}
|
|
} else {
|
|
// Rot bei Fehler/Offline
|
|
loadCard.classList.add('border-red-500/40');
|
|
loadStatus.classList.add('text-red-400');
|
|
}
|
|
});
|
|
}
|
|
setInterval(updateServerLoad, 5000);
|
|
updateServerLoad();
|
|
|
|
// Systemstatus dynamisch Randfarbe anpassen
|
|
function updateSystemStatusCard() {
|
|
const card = document.getElementById('system-status-card');
|
|
const statusText = document.getElementById('system-status-text');
|
|
if (!card || !statusText) return;
|
|
card.classList.remove('border-green-500/40', 'border-yellow-500/40', 'border-red-500/40');
|
|
statusText.classList.remove('small');
|
|
const status = statusText.textContent.toLowerCase();
|
|
if (status.includes('wartung') || status.includes('systeme im wartungsmodus')) {
|
|
card.classList.add('border-yellow-500/40');
|
|
statusText.classList.add('small');
|
|
} else if (status.includes('online')) {
|
|
card.classList.add('border-green-500/40');
|
|
} else {
|
|
card.classList.add('border-red-500/40');
|
|
}
|
|
}
|
|
setTimeout(updateSystemStatusCard, 100); // initial nach Render
|
|
// Optional: falls Systemstatus dynamisch per AJAX kommt, hier regelmäßig prüfen
|
|
setInterval(updateSystemStatusCard, 2000);
|
|
</script>
|
|
{% endblock %}
|