573 lines
17 KiB
JavaScript

/**
* 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');
})();