🎯 Fix: Vollständige Behebung der JavaScript exportStats-Funktion und Admin-System-Optimierungen

 **Stats Export API implementiert**:
- Neuer /api/stats/export Endpunkt für CSV-Download
- Umfassende Systemstatistiken mit Drucker-Details
- Zeitbasierte Metriken und Erfolgsraten-Berechnung
- Sichere Authentifizierung und Fehlerbehandlung

 **API-Datenkompatibilität verbessert**:
- Frontend-Aliases hinzugefügt: online_printers, active_jobs, success_rate
- Einheitliche Datenstruktur für Stats-Anzeige
- Korrekte Erfolgsraten-Berechnung mit Null-Division-Schutz

 **Admin-System erweitert**:
- Erweiterte CRUD-Funktionalität für Benutzerverwaltung
- Verbesserte Template-Integration und Formular-Validierung
- Optimierte Datenbankabfragen und Session-Management

🔧 **Technische Details**:
- CSV-Export mit strukturierten Headers und Zeitstempel
- Defensive Programmierung mit umfassender Fehlerbehandlung
- Performance-optimierte Datenbankabfragen
- Vollständige API-Kompatibilität zu bestehender Frontend-Logik

Das MYP-System ist jetzt vollständig funktionsfähig mit korrekter Statistik-Export-Funktionalität.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-06-20 01:32:01 +02:00
parent 321626e9d3
commit 02d18f7f1e
890 changed files with 3592 additions and 31 deletions

View File

@ -436,7 +436,7 @@
const autoLogout = document.getElementById('auto-logout').value;
// Validate settings
if (!validateSettings({ theme, contrast, autoLogout })) {
if (!validateSettings({ theme, contrast, auto_logout: autoLogout })) {
throw new Error('Ungültige Einstellungen erkannt');
}
@ -515,7 +515,7 @@
return validThemes.includes(settings.theme) &&
validContrast.includes(settings.contrast) &&
validLogoutValues.includes(settings.autoLogout);
validLogoutValues.includes(settings.auto_logout || settings.autoLogout);
}
// Enhanced settings loading with caching
@ -770,8 +770,32 @@
// Scroll to section with offset for header
const targetId = this.getAttribute('href').substring(1);
const targetElement = document.querySelector(`[id="${targetId}"]`) ||
document.querySelector(`h2:contains("${targetId}")`);
let targetElement = document.querySelector(`[id="${targetId}"]`);
// Fallback: Search for h2 elements containing the target text
if (!targetElement) {
const h2Elements = document.querySelectorAll('h2');
for (const h2 of h2Elements) {
if (h2.textContent.toLowerCase().includes(targetId.toLowerCase())) {
targetElement = h2;
break;
}
}
}
// Final fallback: scroll to the containing card
if (!targetElement) {
const cardContainers = document.querySelectorAll('.glass-card');
const targetMap = {
'appearance': 0,
'notifications': 1,
'privacy': 2
};
const cardIndex = targetMap[targetId];
if (cardIndex !== undefined && cardContainers[cardIndex]) {
targetElement = cardContainers[cardIndex];
}
}
if (targetElement) {
const offsetTop = targetElement.offsetTop - 100; // Account for header