/** * MYP Platform - UI Issues Fix * Behebt alle Klickbarkeits- und Interaktivitätsprobleme * Version: 1.0.0 */ (function() { 'use strict'; console.log('🔧 UI-Fix wird geladen...'); // Globale Variablen für bessere Kompatibilität window.MYP_UI_FIXED = false; /** * Hauptinitialisierung */ function initializeUIFixes() { if (window.MYP_UI_FIXED) { console.log('✅ UI bereits gefixt'); return; } console.log('🚀 Starte UI-Fixes...'); // 1. Event-Delegation für alle Klicks setupGlobalClickHandlers(); // 2. Navigation-Fixes fixNavigationClicks(); // 3. Button-Fixes fixButtonClicks(); // 4. Form-Fixes fixFormSubmissions(); // 5. Modal-Fixes fixModalInteractions(); // 6. Dark Mode Fix fixDarkModeToggle(); // 7. Mobile Menu Fix fixMobileMenu(); // 8. Dropdown-Fixes fixDropdowns(); // 9. CSRF-Token-Fixes fixCSRFTokens(); // 10. Auto-Refresh-Fixes setupAutoRefresh(); window.MYP_UI_FIXED = true; console.log('✅ Alle UI-Fixes erfolgreich angewendet!'); } /** * 1. Globale Click-Handler mit Event-Delegation */ function setupGlobalClickHandlers() { console.log('🎯 Richte globale Click-Handler ein...'); // Entferne alte Event-Listener document.removeEventListener('click', handleGlobalClick); // Füge neuen Event-Listener hinzu document.addEventListener('click', handleGlobalClick, true); function handleGlobalClick(event) { const target = event.target; const closest = target.closest('a, button, [role="button"], [data-action], .clickable'); if (!closest) return; // Verhindere doppelte Events if (event.defaultPrevented) return; console.log('👆 Klick erkannt auf:', closest); // Spezielle Handler für verschiedene Elemente if (closest.matches('a[href]')) { handleLinkClick(event, closest); } else if (closest.matches('button, [role="button"]')) { handleButtonClick(event, closest); } else if (closest.hasAttribute('data-action')) { handleDataActionClick(event, closest); } } } /** * Link-Klicks behandeln */ function handleLinkClick(event, link) { const href = link.getAttribute('href'); if (!href || href === '#') { event.preventDefault(); return; } // Externe Links in neuem Tab öffnen if (href.startsWith('http') && !href.includes(window.location.hostname)) { event.preventDefault(); window.open(href, '_blank', 'noopener,noreferrer'); return; } // Interne Navigation if (href.startsWith('/') || href.startsWith('./') || href.startsWith('../')) { console.log('🔗 Navigiere zu:', href); // Lass den Browser die Navigation normal handhaben return; } } /** * Button-Klicks behandeln */ function handleButtonClick(event, button) { // Verhindere doppelte Klicks if (button.disabled || button.classList.contains('loading')) { event.preventDefault(); return; } // Spezielle Button-Typen const buttonType = button.getAttribute('data-type') || button.type; switch (buttonType) { case 'logout': event.preventDefault(); handleLogoutClick(); break; case 'dark-mode-toggle': event.preventDefault(); handleDarkModeToggle(); break; case 'mobile-menu-toggle': event.preventDefault(); handleMobileMenuToggle(); break; case 'refresh': event.preventDefault(); handleRefreshClick(button); break; default: // Normale Button-Behandlung console.log('🔘 Button geklickt:', button); break; } } /** * Data-Action-Klicks behandeln */ function handleDataActionClick(event, element) { event.preventDefault(); const action = element.getAttribute('data-action'); const params = getDataActionParams(element); console.log('⚡ Data-Action ausgeführt:', action, params); switch (action) { case 'logout': handleLogoutClick(); break; case 'toggle-dark-mode': handleDarkModeToggle(); break; case 'toggle-mobile-menu': handleMobileMenuToggle(); break; case 'refresh-page': window.location.reload(); break; case 'go-back': window.history.back(); break; case 'close-modal': closeModal(params.target); break; default: console.warn('⚠️ Unbekannte Data-Action:', action); break; } } /** * Data-Action-Parameter extrahieren */ function getDataActionParams(element) { const params = {}; for (const attr of element.attributes) { if (attr.name.startsWith('data-action-')) { const key = attr.name.replace('data-action-', ''); params[key] = attr.value; } } return params; } /** * 2. Navigation-Fixes */ function fixNavigationClicks() { console.log('🧭 Fixe Navigation...'); // Alle Navigations-Links finden und reparieren const navLinks = document.querySelectorAll('nav a, .navbar a, .nav-item'); navLinks.forEach(link => { if (!link.href || link.href === '#') { link.style.cursor = 'pointer'; link.addEventListener('click', function(e) { e.preventDefault(); console.log('🔗 Navigation-Link geklickt:', this); }); } }); } /** * 3. Button-Fixes */ function fixButtonClicks() { console.log('🔘 Fixe Buttons...'); // Alle Buttons finden und Event-Listener hinzufügen const buttons = document.querySelectorAll('button, [role="button"], .btn'); buttons.forEach(button => { // Entferne alte Event-Listener button.removeEventListener('click', handleButtonClickFix); // Füge neuen Event-Listener hinzu button.addEventListener('click', handleButtonClickFix); }); function handleButtonClickFix(event) { console.log('🔘 Button-Fix aktiviert für:', this); // Verhindere doppelte Klicks if (this.disabled) { event.preventDefault(); return; } // Visuelles Feedback this.style.transform = 'scale(0.95)'; setTimeout(() => { this.style.transform = ''; }, 150); } } /** * 4. Form-Fixes */ function fixFormSubmissions() { console.log('📝 Fixe Formulare...'); const forms = document.querySelectorAll('form'); forms.forEach(form => { form.addEventListener('submit', function(event) { console.log('📤 Formular wird abgesendet:', this); // CSRF-Token prüfen const csrfToken = this.querySelector('input[name="csrf_token"]'); if (!csrfToken) { console.warn('⚠️ CSRF-Token fehlt in Formular'); addCSRFTokenToForm(this); } }); }); } /** * 5. Modal-Fixes */ function fixModalInteractions() { console.log('🪟 Fixe Modals...'); // Modal-Close-Buttons const closeButtons = document.querySelectorAll('[data-modal-close], .modal-close'); closeButtons.forEach(button => { button.addEventListener('click', function(event) { event.preventDefault(); const modal = this.closest('.modal, .fixed'); if (modal) { closeModal(modal); } }); }); // Modal-Backdrop-Klicks const modals = document.querySelectorAll('.modal, .fixed'); modals.forEach(modal => { modal.addEventListener('click', function(event) { if (event.target === this) { closeModal(this); } }); }); } /** * 6. Dark Mode Fix */ function fixDarkModeToggle() { console.log('🌙 Fixe Dark Mode...'); const darkModeToggle = document.getElementById('darkModeToggle') || document.querySelector('[data-action="toggle-dark-mode"]'); if (darkModeToggle) { darkModeToggle.addEventListener('click', handleDarkModeToggle); } } function handleDarkModeToggle() { console.log('🌙 Dark Mode Toggle aktiviert'); const html = document.documentElement; const isDark = html.classList.contains('dark'); if (isDark) { html.classList.remove('dark'); localStorage.setItem('myp-dark-mode', 'false'); } else { html.classList.add('dark'); localStorage.setItem('myp-dark-mode', 'true'); } // Icons aktualisieren updateDarkModeIcons(!isDark); } function updateDarkModeIcons(isDark) { const sunIcons = document.querySelectorAll('.sun-icon'); const moonIcons = document.querySelectorAll('.moon-icon'); sunIcons.forEach(icon => { icon.classList.toggle('hidden', isDark); }); moonIcons.forEach(icon => { icon.classList.toggle('hidden', !isDark); }); } /** * 7. Mobile Menu Fix */ function fixMobileMenu() { console.log('📱 Fixe Mobile Menu...'); const mobileMenuToggle = document.getElementById('mobileMenuToggle') || document.querySelector('[data-action="toggle-mobile-menu"]'); const mobileMenu = document.getElementById('mobileMenu'); if (mobileMenuToggle && mobileMenu) { mobileMenuToggle.addEventListener('click', handleMobileMenuToggle); } } function handleMobileMenuToggle() { console.log('📱 Mobile Menu Toggle aktiviert'); const mobileMenu = document.getElementById('mobileMenu'); if (mobileMenu) { mobileMenu.classList.toggle('hidden'); } } /** * 8. Dropdown-Fixes */ function fixDropdowns() { console.log('📋 Fixe Dropdowns...'); const dropdownToggles = document.querySelectorAll('[data-dropdown-toggle]'); dropdownToggles.forEach(toggle => { toggle.addEventListener('click', function(event) { event.preventDefault(); const targetId = this.getAttribute('data-dropdown-toggle'); const dropdown = document.getElementById(targetId); if (dropdown) { dropdown.classList.toggle('hidden'); } }); }); // Schließe Dropdowns bei Klick außerhalb document.addEventListener('click', function(event) { const dropdowns = document.querySelectorAll('[data-dropdown-menu]'); dropdowns.forEach(dropdown => { if (!dropdown.contains(event.target) && !event.target.matches('[data-dropdown-toggle]')) { dropdown.classList.add('hidden'); } }); }); } /** * 9. CSRF-Token-Fixes */ function fixCSRFTokens() { console.log('🔒 Fixe CSRF-Tokens...'); const csrfToken = document.querySelector('meta[name="csrf-token"]'); if (!csrfToken) { console.warn('⚠️ CSRF-Token Meta-Tag fehlt'); return; } const tokenValue = csrfToken.getAttribute('content'); // Füge CSRF-Token zu allen Formularen hinzu const forms = document.querySelectorAll('form'); forms.forEach(form => { if (!form.querySelector('input[name="csrf_token"]')) { addCSRFTokenToForm(form, tokenValue); } }); } function addCSRFTokenToForm(form, tokenValue = null) { if (!tokenValue) { const csrfMeta = document.querySelector('meta[name="csrf-token"]'); tokenValue = csrfMeta ? csrfMeta.getAttribute('content') : ''; } if (tokenValue) { const input = document.createElement('input'); input.type = 'hidden'; input.name = 'csrf_token'; input.value = tokenValue; form.appendChild(input); } } /** * 10. Auto-Refresh-Setup */ function setupAutoRefresh() { console.log('🔄 Richte Auto-Refresh ein...'); // Auto-Refresh für bestimmte Seiten const refreshInterval = 30000; // 30 Sekunden if (window.location.pathname.includes('/dashboard') || window.location.pathname.includes('/printers') || window.location.pathname.includes('/jobs')) { setInterval(() => { refreshPageData(); }, refreshInterval); } } function refreshPageData() { // Implementierung für spezifische Seiten-Refreshs console.log('🔄 Aktualisiere Seitendaten...'); } /** * Logout-Handler */ function handleLogoutClick() { console.log('👋 Logout-Prozess gestartet'); if (confirm('Möchten Sie sich wirklich abmelden?')) { // CSRF-Token holen const csrfToken = document.querySelector('meta[name="csrf-token"]'); // Logout-Form erstellen const form = document.createElement('form'); form.method = 'POST'; form.action = '/auth/logout'; form.style.display = 'none'; if (csrfToken) { const input = document.createElement('input'); input.type = 'hidden'; input.name = 'csrf_token'; input.value = csrfToken.getAttribute('content'); form.appendChild(input); } document.body.appendChild(form); form.submit(); } } /** * Refresh-Handler */ function handleRefreshClick(button) { console.log('🔄 Refresh-Button geklickt'); // Button-State ändern const originalText = button.textContent; button.textContent = 'Wird aktualisiert...'; button.disabled = true; // Seite neu laden setTimeout(() => { window.location.reload(); }, 500); } /** * Modal schließen */ function closeModal(modal) { if (typeof modal === 'string') { modal = document.getElementById(modal) || document.querySelector(modal); } if (modal) { modal.classList.add('hidden'); modal.style.display = 'none'; } } /** * Initialisierung bei DOM-Ready */ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeUIFixes); } else { initializeUIFixes(); } // Backup-Initialisierung nach 1 Sekunde setTimeout(initializeUIFixes, 1000); // Globale Funktionen für Kompatibilität window.MYP_UI_FIXES = { init: initializeUIFixes, handleLogout: handleLogoutClick, handleDarkMode: handleDarkModeToggle, handleMobileMenu: handleMobileMenuToggle, closeModal: closeModal }; console.log('✅ UI-Fix-Script geladen'); })();