diff --git a/backend/app/database/myp.db b/backend/app/database/myp.db index 35e1f1ca..9c28d98f 100644 Binary files a/backend/app/database/myp.db and b/backend/app/database/myp.db differ diff --git a/backend/app/docs/ADMIN_PANEL_FUNKTIONEN.md b/backend/app/docs/ADMIN_PANEL_FUNKTIONEN.md new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/backend/app/docs/ADMIN_PANEL_FUNKTIONEN.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/app/static/js/admin-system.js b/backend/app/static/js/admin-system.js new file mode 100644 index 00000000..2eabf15e --- /dev/null +++ b/backend/app/static/js/admin-system.js @@ -0,0 +1,214 @@ +/** + * Admin System Management JavaScript + * Funktionen für System-Wartung und -Konfiguration + */ + +// CSRF Token für AJAX-Anfragen +function getCsrfToken() { + const token = document.querySelector('meta[name="csrf-token"]'); + return token ? token.getAttribute('content') : ''; +} + +// Hilfsfunktion für API-Aufrufe +async function makeApiCall(url, method = 'GET', data = null) { + const options = { + method: method, + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': getCsrfToken() + } + }; + + if (data) { + options.body = JSON.stringify(data); + } + + try { + const response = await fetch(url, options); + const result = await response.json(); + + if (response.ok) { + showNotification(result.message || 'Aktion erfolgreich ausgeführt', 'success'); + return result; + } else { + showNotification(result.error || 'Ein Fehler ist aufgetreten', 'error'); + return null; + } + } catch (error) { + showNotification('Netzwerkfehler: ' + error.message, 'error'); + return null; + } +} + +// Notification anzeigen +function showNotification(message, type = 'info') { + // Erstelle Notification-Element falls nicht vorhanden + let notification = document.getElementById('admin-notification'); + if (!notification) { + notification = document.createElement('div'); + notification.id = 'admin-notification'; + notification.className = 'fixed top-4 right-4 z-50 p-4 rounded-lg shadow-lg max-w-sm transition-all duration-300 transform translate-x-full'; + document.body.appendChild(notification); + } + + // Setze Farbe basierend auf Typ + const colors = { + success: 'bg-green-500 text-white', + error: 'bg-red-500 text-white', + warning: 'bg-yellow-500 text-white', + info: 'bg-blue-500 text-white' + }; + + notification.className = `fixed top-4 right-4 z-50 p-4 rounded-lg shadow-lg max-w-sm transition-all duration-300 ${colors[type] || colors.info}`; + notification.textContent = message; + + // Zeige Notification + notification.style.transform = 'translateX(0)'; + + // Verstecke nach 5 Sekunden + setTimeout(() => { + notification.style.transform = 'translateX(100%)'; + }, 5000); +} + +// Cache leeren +async function clearCache() { + if (confirm('Möchten Sie wirklich den Cache leeren?')) { + showNotification('Cache wird geleert...', 'info'); + const result = await makeApiCall('/api/admin/cache/clear', 'POST'); + if (result) { + setTimeout(() => location.reload(), 2000); + } + } +} + +// Datenbank optimieren +async function optimizeDatabase() { + if (confirm('Möchten Sie wirklich die Datenbank optimieren? Dies kann einige Minuten dauern.')) { + showNotification('Datenbank wird optimiert...', 'info'); + const result = await makeApiCall('/api/admin/database/optimize', 'POST'); + if (result) { + setTimeout(() => location.reload(), 2000); + } + } +} + +// Backup erstellen +async function createBackup() { + if (confirm('Möchten Sie wirklich ein Backup erstellen?')) { + showNotification('Backup wird erstellt...', 'info'); + const result = await makeApiCall('/api/admin/backup/create', 'POST'); + } +} + +// Drucker aktualisieren +async function updatePrinters() { + if (confirm('Möchten Sie alle Drucker-Verbindungen aktualisieren?')) { + showNotification('Drucker werden aktualisiert...', 'info'); + const result = await makeApiCall('/api/admin/printers/update', 'POST'); + if (result) { + setTimeout(() => location.reload(), 2000); + } + } +} + +// System neustarten +async function restartSystem() { + if (confirm('WARNUNG: Möchten Sie wirklich das System neustarten? Alle aktiven Verbindungen werden getrennt.')) { + const result = await makeApiCall('/api/admin/system/restart', 'POST'); + if (result) { + showNotification('System wird neugestartet...', 'warning'); + setTimeout(() => { + window.location.href = '/'; + }, 3000); + } + } +} + +// Einstellungen bearbeiten +function editSettings() { + window.location.href = '/settings'; +} + +// Systemstatus automatisch aktualisieren +async function updateSystemStatus() { + if (window.location.search.includes('tab=system')) { + const result = await makeApiCall('/api/admin/system/status'); + if (result) { + // Aktualisiere die Anzeige + updateStatusDisplay('cpu_usage', result.cpu_usage + '%'); + updateStatusDisplay('memory_usage', result.memory_usage + '%'); + updateStatusDisplay('disk_usage', result.disk_usage + '%'); + updateStatusDisplay('uptime', result.uptime); + updateStatusDisplay('db_size', result.db_size); + updateStatusDisplay('scheduler_jobs', result.scheduler_jobs); + updateStatusDisplay('next_job', result.next_job); + + // Scheduler-Status aktualisieren + const schedulerStatus = document.querySelector('.scheduler-status'); + if (schedulerStatus) { + if (result.scheduler_running) { + schedulerStatus.innerHTML = 'Läuft'; + schedulerStatus.className = 'inline-flex items-center px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200'; + } else { + schedulerStatus.innerHTML = 'Gestoppt'; + schedulerStatus.className = 'inline-flex items-center px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'; + } + } + } + } +} + +// Hilfsfunktion zum Aktualisieren der Status-Anzeige +function updateStatusDisplay(key, value) { + const element = document.querySelector(`[data-status="${key}"]`); + if (element) { + element.textContent = value; + } +} + +// Datenbankstatus aktualisieren +async function updateDatabaseStatus() { + if (window.location.search.includes('tab=system')) { + const result = await makeApiCall('/api/admin/database/status'); + if (result) { + const dbStatus = document.querySelector('.database-status'); + if (dbStatus) { + if (result.connected) { + dbStatus.innerHTML = 'Verbunden'; + dbStatus.className = 'inline-flex items-center px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'; + } else { + dbStatus.innerHTML = 'Getrennt'; + dbStatus.className = 'inline-flex items-center px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'; + } + } + + updateStatusDisplay('db_size', result.size); + updateStatusDisplay('db_connections', result.connected ? 'Aktiv' : 'Getrennt'); + } + } +} + +// Auto-Update alle 30 Sekunden +setInterval(() => { + updateSystemStatus(); + updateDatabaseStatus(); +}, 30000); + +// Initial load +document.addEventListener('DOMContentLoaded', function() { + updateSystemStatus(); + updateDatabaseStatus(); +}); + +// Export für globale Verwendung +window.adminSystem = { + clearCache, + optimizeDatabase, + createBackup, + updatePrinters, + restartSystem, + editSettings, + updateSystemStatus, + updateDatabaseStatus +}; \ No newline at end of file diff --git a/backend/app/templates/admin.html b/backend/app/templates/admin.html index 82bea5eb..697b934d 100644 --- a/backend/app/templates/admin.html +++ b/backend/app/templates/admin.html @@ -7,6 +7,7 @@ + {% endblock %} {% block content %} @@ -478,7 +479,7 @@
${printer.model}