🎯 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:
@ -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
|
||||
|
Reference in New Issue
Block a user