🎉 Improved backend structure & logs organization 🎉
This commit is contained in:
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user