📝 "Refactor backend files

This commit is contained in:
2025-06-01 01:31:02 +02:00
parent 40ca104860
commit 66621f1539
16 changed files with 881 additions and 43 deletions

View File

@ -202,6 +202,53 @@
.dark .dropdown-menu::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
}
/* ===== DO NOT DISTURB BUTTON STYLES ===== */
.dnd-toggle-button {
/* Inaktiv (Standard) */
background: linear-gradient(135deg, rgba(99, 102, 241, 0.1), rgba(59, 130, 246, 0.1));
color: rgb(99, 102, 241);
border: 1px solid rgba(99, 102, 241, 0.2);
}
.dnd-toggle-button:hover {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.15), rgba(59, 130, 246, 0.15));
border-color: rgba(99, 102, 241, 0.3);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.15);
}
/* Aktiv (DND eingeschaltet) */
.dnd-toggle-button.active {
background: linear-gradient(135deg, rgba(249, 115, 22, 0.9), rgba(234, 88, 12, 0.9));
color: white;
border: 1px solid rgba(249, 115, 22, 0.8);
box-shadow: 0 2px 8px rgba(249, 115, 22, 0.3);
}
.dnd-toggle-button.active:hover {
background: linear-gradient(135deg, rgba(249, 115, 22, 1), rgba(234, 88, 12, 1));
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(249, 115, 22, 0.4);
}
/* Dark Mode Anpassungen */
.dark .dnd-toggle-button {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.15), rgba(59, 130, 246, 0.15));
color: rgb(147, 197, 253);
border: 1px solid rgba(99, 102, 241, 0.3);
}
.dark .dnd-toggle-button:hover {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.2), rgba(59, 130, 246, 0.2));
border-color: rgba(99, 102, 241, 0.4);
}
.dark .dnd-toggle-button.active {
background: linear-gradient(135deg, rgba(249, 115, 22, 0.9), rgba(234, 88, 12, 0.9));
color: white;
border: 1px solid rgba(249, 115, 22, 0.8);
}
</style>
{% block head %}{% endblock %}
@ -662,43 +709,30 @@
</div>
</div>
</div>
<!-- Do Not Disturb Controls -->
<div class="flex flex-col space-y-4">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white transition-colors duration-300">Benachrichtigungen</h3>
<div class="space-y-3">
<!-- Do Not Disturb Toggle -->
<!-- Do Not Disturb Toggle - Vereinfacht -->
<div class="flex items-center justify-between">
<span class="text-xs text-slate-600 dark:text-slate-400">Nicht stören:</span>
<button
id="dndToggle"
class="relative p-2 rounded-lg text-slate-700 dark:text-slate-300 hover:bg-slate-100/80 dark:hover:bg-slate-800/50 transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 group"
class="dnd-toggle-button px-3 py-1.5 rounded-lg text-xs font-medium transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
aria-label="Do Not Disturb umschalten"
data-dnd-toggle
title="Benachrichtigungen stumm schalten"
>
<!-- DND Icon (Stumm) -->
<div class="dnd-icon-off transition-all duration-300">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
</svg>
</div>
<!-- DND Icon (Aktiv) - versteckt by default -->
<div class="dnd-icon-on absolute inset-0 flex items-center justify-center transition-all duration-300 opacity-0 scale-75">
<svg class="w-4 h-4 text-red-500" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z"/>
</svg>
</div>
<!-- Notification Counter für unterdrückte Messages -->
<span id="dndCounter" class="dnd-counter hidden">0</span>
<span class="dnd-text">Inaktiv</span>
</button>
</div>
<!-- DND Status Anzeige -->
<div id="dndStatus" class="text-xs text-slate-500 dark:text-slate-400 hidden">
<span class="dnd-status-text">Inaktiv</span>
<!-- DND Status und Counter -->
<div id="dndStatus" class="text-xs text-slate-500 dark:text-slate-400">
<div class="flex items-center justify-between">
<span class="dnd-status-text">Alle Benachrichtigungen aktiv</span>
<span id="dndCounter" class="dnd-counter hidden px-2 py-1 bg-orange-500 text-white rounded-full text-xs font-medium">0 unterdrückt</span>
</div>
</div>
</div>
</div>
@ -810,6 +844,183 @@
console.log('🚀 MYP Platform UI erfolgreich initialisiert');
});
/**
* Do Not Disturb (DND) Funktionalität
*/
class DoNotDisturbManager {
constructor() {
this.storageKey = 'myp-dnd-mode';
this.counterKey = 'myp-dnd-counter';
this.suppressedMessages = [];
this.isEnabled = this.loadDNDState();
this.suppressedCount = this.loadSuppressedCount();
this.init();
}
init() {
const dndToggle = document.getElementById('dndToggle');
const dndStatus = document.getElementById('dndStatus');
const dndCounter = document.getElementById('dndCounter');
if (dndToggle) {
dndToggle.addEventListener('click', () => this.toggle());
this.updateUI();
}
// Integration mit dem bestehenden Benachrichtigungssystem
this.integrateWithNotificationSystem();
}
toggle() {
this.isEnabled = !this.isEnabled;
this.saveDNDState();
this.updateUI();
if (!this.isEnabled) {
// Beim Deaktivieren alle unterdrückten Nachrichten anzeigen
this.showSuppressedMessages();
this.resetSuppressedCount();
}
// Feedback für den Benutzer
const message = this.isEnabled
? 'Nicht stören aktiviert - Benachrichtigungen werden unterdrückt'
: 'Nicht stören deaktiviert - Benachrichtigungen sind wieder aktiv';
if (typeof showFlashMessage === 'function') {
showFlashMessage(message, 'info', 3000);
}
console.log(`🔕 DND ${this.isEnabled ? 'aktiviert' : 'deaktiviert'}`);
}
updateUI() {
const dndToggle = document.getElementById('dndToggle');
const dndText = dndToggle?.querySelector('.dnd-text');
const dndStatusText = document.querySelector('.dnd-status-text');
const dndCounter = document.getElementById('dndCounter');
if (this.isEnabled) {
dndToggle?.classList.add('active');
if (dndText) dndText.textContent = 'Aktiv';
if (dndStatusText) dndStatusText.textContent = 'Benachrichtigungen unterdrückt';
dndToggle?.setAttribute('title', 'Nicht stören deaktivieren');
} else {
dndToggle?.classList.remove('active');
if (dndText) dndText.textContent = 'Inaktiv';
if (dndStatusText) dndStatusText.textContent = 'Alle Benachrichtigungen aktiv';
dndToggle?.setAttribute('title', 'Nicht stören aktivieren');
}
// Counter aktualisieren
if (dndCounter) {
if (this.suppressedCount > 0 && this.isEnabled) {
dndCounter.textContent = `${this.suppressedCount} unterdrückt`;
dndCounter.classList.remove('hidden');
} else {
dndCounter.classList.add('hidden');
}
}
}
shouldSuppressNotification(message, type) {
if (!this.isEnabled) return false;
// Wichtige Nachrichten (Fehler) nicht unterdrücken
if (type === 'error' || type === 'danger') return false;
// Nachricht zur Liste der unterdrückten hinzufügen
this.suppressedMessages.push({
message,
type,
timestamp: new Date().toISOString()
});
this.incrementSuppressedCount();
return true;
}
showSuppressedMessages() {
if (this.suppressedMessages.length === 0) return;
// Sammelnachricht über unterdrückte Benachrichtigungen
const count = this.suppressedMessages.length;
const summaryMessage = `${count} Benachrichtigung${count > 1 ? 'en' : ''} während "Nicht stören" erhalten`;
if (typeof showFlashMessage === 'function') {
showFlashMessage(summaryMessage, 'info', 4000);
}
// Optional: Alle einzelnen Nachrichten anzeigen (mit Verzögerung)
this.suppressedMessages.forEach((item, index) => {
setTimeout(() => {
if (typeof showFlashMessage === 'function') {
showFlashMessage(item.message, item.type, 3000);
}
}, (index + 1) * 500);
});
this.suppressedMessages = [];
}
incrementSuppressedCount() {
this.suppressedCount++;
this.saveSuppressedCount();
this.updateUI();
}
resetSuppressedCount() {
this.suppressedCount = 0;
this.saveSuppressedCount();
this.updateUI();
}
integrateWithNotificationSystem() {
// Überschreibe showFlashMessage wenn verfügbar
if (typeof window.showFlashMessage === 'function') {
const originalShowFlashMessage = window.showFlashMessage;
window.showFlashMessage = (message, type, duration) => {
if (this.shouldSuppressNotification(message, type)) {
console.log(`🔕 Benachrichtigung unterdrückt: ${message}`);
return;
}
return originalShowFlashMessage(message, type, duration);
};
}
}
loadDNDState() {
const saved = localStorage.getItem(this.storageKey);
return saved === 'true';
}
saveDNDState() {
localStorage.setItem(this.storageKey, this.isEnabled.toString());
}
loadSuppressedCount() {
const saved = localStorage.getItem(this.counterKey);
return saved ? parseInt(saved, 10) : 0;
}
saveSuppressedCount() {
localStorage.setItem(this.counterKey, this.suppressedCount.toString());
}
// Public API
getState() {
return {
enabled: this.isEnabled,
suppressedCount: this.suppressedCount,
suppressedMessages: this.suppressedMessages
};
}
}
// DND Manager global verfügbar machen
window.dndManager = new DoNotDisturbManager();
</script>
{% block scripts %}{% endblock %}

View File

@ -183,7 +183,7 @@ async function loadBasicStats() {
throw new Error(data.error || 'Fehler beim Laden der Statistiken');
}
// Statistiken aktualisieren
// Statistiken aktualisieren mit defensiven Checks
updateStatsCounter('total-jobs-count', data.total_jobs);
updateStatsCounter('completed-jobs-count', data.completed_jobs);
updateStatsCounter('online-printers-count', data.online_printers);
@ -192,6 +192,8 @@ async function loadBasicStats() {
updateStatsCounter('failed-jobs-count', data.failed_jobs);
updateStatsCounter('total-users-count', data.total_users);
console.log('✅ Basis-Statistiken erfolgreich geladen:', data);
} catch (error) {
console.error('Fehler beim Laden der Basis-Statistiken:', error);
showToast('Fehler beim Laden der Statistiken', 'error');
@ -200,7 +202,10 @@ async function loadBasicStats() {
function updateStatsCounter(elementId, value, animate = true) {
const element = document.getElementById(elementId);
if (!element) return;
if (!element) {
console.warn(`Element mit ID '${elementId}' nicht gefunden - wird übersprungen`);
return;
}
if (animate) {
// Animierte Zählung