🎉 Improved backend structure & logs organization 🎉

This commit is contained in:
2025-06-01 03:25:55 +02:00
parent 8969cf6df6
commit 09462724e0
63 changed files with 2014 additions and 491 deletions

View File

@ -92,17 +92,14 @@
}
}
// User-Dropdown-Funktionalität initialisieren
initializeUserDropdown();
// Mobile Menu Toggle initialisieren
initializeMobileMenu();
// MYP App für Offline-Funktionalität initialisieren
if (typeof MYPApp !== 'undefined') {
window.mypApp = new MYPApp();
}
// User-Dropdown-Funktionalität initialisieren
initUserDropdown();
// Flask Flash Messages über das Glassmorphism-System anzeigen
const flashContainer = document.getElementById('flask-flash-messages');
if (flashContainer) {
@ -733,7 +730,7 @@
</button>
</div>
<!-- DND Status und Counter -->
<!-- DND Status -->
<div id="dndStatus" class="text-xs text-slate-500 dark:text-slate-400">
<span class="dnd-status-text">Alle Benachrichtigungen aktiv</span>
</div>
@ -812,17 +809,14 @@
* Initialisierung aller UI-Komponenten nach DOM-Load
*/
document.addEventListener('DOMContentLoaded', function() {
// User-Dropdown-Funktionalität initialisieren
initializeUserDropdown();
// Mobile Menu Toggle initialisieren
initializeMobileMenu();
// MYP App für Offline-Funktionalität initialisieren
if (typeof MYPApp !== 'undefined') {
window.mypApp = new MYPApp();
}
// User-Dropdown-Funktionalität initialisieren
initUserDropdown();
// Flask Flash Messages über das Glassmorphism-System anzeigen
const flashContainer = document.getElementById('flask-flash-messages');
if (flashContainer) {
@ -857,154 +851,139 @@
/**
* User-Dropdown-Funktionalität
*/
function initializeUserDropdown() {
function initUserDropdown() {
const userMenuButton = document.getElementById('user-menu-button');
const userDropdown = document.getElementById('user-dropdown');
const userMenuContainer = document.getElementById('user-menu-container');
if (!userMenuButton || !userDropdown) return;
console.log('🔍 User-Dropdown Init:', { userMenuButton, userDropdown });
if (!userMenuButton || !userDropdown) {
console.warn('⚠️ User-Dropdown-Elemente nicht gefunden:', {
button: !!userMenuButton,
dropdown: !!userDropdown
});
return; // Nicht angemeldet oder Elemente nicht gefunden
}
let isDropdownOpen = false;
// Toggle-Funktion
function toggleDropdown(e) {
e.stopPropagation();
const isExpanded = userMenuButton.getAttribute('aria-expanded') === 'true';
function toggleDropdown(event) {
if (event) {
event.preventDefault();
event.stopPropagation();
}
if (isExpanded) {
closeDropdown();
} else {
isDropdownOpen = !isDropdownOpen;
console.log('🔄 Toggle Dropdown:', isDropdownOpen);
if (isDropdownOpen) {
openDropdown();
} else {
closeDropdown();
}
}
// Dropdown öffnen
function openDropdown() {
userDropdown.classList.remove('hidden');
userMenuButton.setAttribute('aria-expanded', 'true');
// Animation für bessere UX
// Reset any existing styles
userDropdown.style.transition = '';
userDropdown.style.opacity = '0';
userDropdown.style.transform = 'scale(0.95) translateY(-5px)';
userDropdown.style.transform = 'translateY(-10px) scale(0.95)';
// Kleine Verzögerung für Animation
// Force reflow
userDropdown.offsetHeight;
// Apply opening animation
requestAnimationFrame(() => {
userDropdown.style.transition = 'all 0.15s ease-out';
userDropdown.style.transition = 'all 0.2s ease-out';
userDropdown.style.opacity = '1';
userDropdown.style.transform = 'scale(1) translateY(0)';
userDropdown.style.transform = 'translateY(0) scale(1)';
});
console.log('✅ Dropdown geöffnet');
}
// Dropdown schließen
function closeDropdown() {
userDropdown.style.transition = 'all 0.15s ease-in';
userDropdown.style.opacity = '0';
userDropdown.style.transform = 'scale(0.95) translateY(-5px)';
userDropdown.style.transform = 'translateY(-10px) scale(0.95)';
setTimeout(() => {
userDropdown.classList.add('hidden');
userMenuButton.setAttribute('aria-expanded', 'false');
// Reset inline styles
userDropdown.style.transition = '';
userDropdown.style.opacity = '';
userDropdown.style.transform = '';
}, 150);
isDropdownOpen = false;
console.log('❌ Dropdown geschlossen');
}
// Event-Listener
// Event-Listener für Button-Click
userMenuButton.addEventListener('click', toggleDropdown);
// Außerhalb des Dropdowns klicken schließt es
// Alternative: Auch auf touchstart für mobile Geräte
userMenuButton.addEventListener('touchstart', function(e) {
e.preventDefault();
toggleDropdown(e);
}, { passive: false });
// Event-Listener für Klicks außerhalb des Dropdowns
document.addEventListener('click', function(e) {
if (!userMenuContainer.contains(e.target)) {
closeDropdown();
if (!userMenuButton.contains(e.target) && !userDropdown.contains(e.target)) {
if (isDropdownOpen) {
closeDropdown();
}
}
});
// Escape-Taste schließt das Dropdown
// Touch-Events für mobile Geräte
document.addEventListener('touchstart', function(e) {
if (!userMenuButton.contains(e.target) && !userDropdown.contains(e.target)) {
if (isDropdownOpen) {
closeDropdown();
}
}
});
// Escape-Taste zum Schließen
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && userMenuButton.getAttribute('aria-expanded') === 'true') {
if (e.key === 'Escape' && isDropdownOpen) {
closeDropdown();
userMenuButton.focus();
}
});
// Keyboard-Navigation im Dropdown
// Fokus-Management für bessere Accessibility
userDropdown.addEventListener('keydown', function(e) {
const focusableElements = userDropdown.querySelectorAll('a, button');
const currentIndex = Array.from(focusableElements).indexOf(document.activeElement);
switch(e.key) {
case 'ArrowDown':
e.preventDefault();
const nextIndex = (currentIndex + 1) % focusableElements.length;
focusableElements[nextIndex].focus();
break;
case 'ArrowUp':
e.preventDefault();
const prevIndex = currentIndex === 0 ? focusableElements.length - 1 : currentIndex - 1;
focusableElements[prevIndex].focus();
break;
case 'Tab':
// Tab schließt das Dropdown
if (!e.shiftKey && currentIndex === focusableElements.length - 1) {
closeDropdown();
} else if (e.shiftKey && currentIndex === 0) {
closeDropdown();
}
break;
}
});
}
/**
* Mobile Menu Toggle Funktionalität
*/
function initializeMobileMenu() {
const mobileMenuToggle = document.getElementById('mobileMenuToggle');
const mobileMenu = document.getElementById('mobileMenu');
if (!mobileMenuToggle || !mobileMenu) return;
mobileMenuToggle.addEventListener('click', function() {
const isExpanded = mobileMenuToggle.getAttribute('aria-expanded') === 'true';
if (isExpanded) {
// Menü schließen
mobileMenu.classList.add('hidden');
mobileMenuToggle.setAttribute('aria-expanded', 'false');
mobileMenuToggle.setAttribute('aria-label', 'Menü öffnen');
if (e.key === 'Tab') {
const focusableElements = userDropdown.querySelectorAll('a, button');
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
// Icon zu Hamburger ändern
mobileMenuToggle.innerHTML = `
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
`;
} else {
// Menü öffnen
mobileMenu.classList.remove('hidden');
mobileMenuToggle.setAttribute('aria-expanded', 'true');
mobileMenuToggle.setAttribute('aria-label', 'Menü schließen');
// Icon zu X ändern
mobileMenuToggle.innerHTML = `
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
`;
if (e.shiftKey && document.activeElement === firstElement) {
e.preventDefault();
lastElement.focus();
} else if (!e.shiftKey && document.activeElement === lastElement) {
e.preventDefault();
firstElement.focus();
}
}
});
// Mobile Menu bei Resize auf Desktop schließen
// Window resize handler
window.addEventListener('resize', function() {
if (window.innerWidth >= 1024) { // lg breakpoint
mobileMenu.classList.add('hidden');
mobileMenuToggle.setAttribute('aria-expanded', 'false');
mobileMenuToggle.setAttribute('aria-label', 'Menü öffnen');
// Icon zurück zu Hamburger
mobileMenuToggle.innerHTML = `
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
`;
if (isDropdownOpen) {
closeDropdown();
}
});
console.log('✅ User-Dropdown erfolgreich initialisiert');
}
/**