diff --git a/public/assets/js/ui-user.js b/public/assets/js/ui-user.js index 0612014..6fa1d12 100644 --- a/public/assets/js/ui-user.js +++ b/public/assets/js/ui-user.js @@ -13,6 +13,8 @@ const state = { }; const pageType = document.body?.dataset?.page || 'account'; +const DEBUG_EMAIL = 'madmin@papa-kind-treff.info'; +const MAX_CONSOLE_LINES = 200; let avatarBtn; let userMenuPanel; @@ -27,12 +29,22 @@ let bridgePreview; let validateBridgeBtn; let menuInitialized = false; let menuOpen = false; +let debugButton; +let debugDialog; +let debugPhpLoaded = false; +let debugPhpLoading = false; +let debugActiveTab = 'php'; +let phpInfoContainer; +let consoleContainer; +let debugStylesInjected = false; +let consolePatched = false; +const consoleBuffer = []; export function initUserPanel() { avatarBtn = document.getElementById('btn-user'); userMenuPanel = document.getElementById('userMenuPanel'); - updateAvatar(); - updateRoleVisibility(); + ensureConsoleCapture(); + handleUserContextChange(); if (!menuInitialized && avatarBtn && userMenuPanel) { avatarBtn.addEventListener('click', toggleUserMenu); document.addEventListener('click', handleDocumentClick, true); @@ -112,6 +124,13 @@ function enforcePageAccess() { window.location.href = '/account.php'; } +function handleUserContextChange() { + updateAvatar(); + updateRoleVisibility(); + enforcePageAccess(); + refreshDebugAccess(); +} + function updateAvatar() { const target = document.getElementById('userAvatar'); if (!target) return; @@ -191,9 +210,7 @@ async function loadAccountData() { if (!res?.ok) throw new Error(res?.error || 'Profil konnte nicht geladen werden'); if (res.user) { window.__currentUser = res.user; - updateAvatar(); - updateRoleVisibility(); - enforcePageAccess(); + handleUserContextChange(); } fillProfileForm(res.user); fillSettingsForm(res.settings || {}); @@ -246,7 +263,7 @@ async function submitProfileForm(ev) { const res = await apiAction('account.profile.update', { method: 'POST', data }); if (!res?.ok) throw new Error(res?.error || 'Profil konnte nicht gespeichert werden'); window.__currentUser = res.user; - updateAvatar(); + handleUserContextChange(); toast('Profil aktualisiert', true); } catch (err) { toast(err.message || 'Fehler beim Speichern', false); @@ -591,3 +608,183 @@ function escapeHtml(str) { .replace(/"/g, '"') .replace(/'/g, '''); } + +function refreshDebugAccess() { + const allowed = (window.__currentUser?.email || '').toLowerCase() === DEBUG_EMAIL; + if (!allowed) { + debugButton?.remove(); + debugButton = null; + if (debugDialog?.open) { + debugDialog.close(); + } + return; + } + ensureDebugStyles(); + ensureConsoleCapture(); + ensureDebugDialog(); + if (!debugButton) { + debugButton = document.createElement('button'); + debugButton.id = 'debugToggleButton'; + debugButton.className = 'debug-floating-btn'; + debugButton.type = 'button'; + debugButton.textContent = 'Debug'; + debugButton.addEventListener('click', () => openDebugDialog('php')); + document.body.appendChild(debugButton); + } +} + +function ensureDebugStyles() { + if (debugStylesInjected) return; + const style = document.createElement('style'); + style.id = 'debugStyles'; + style.textContent = ` + .debug-floating-btn{position:fixed;left:16px;bottom:16px;padding:.5rem 1rem;border-radius:999px;border:none;background:#0ea5e9;color:#fff;font-weight:600;box-shadow:0 10px 25px rgba(15,23,42,.25);z-index:60;cursor:pointer} + .debug-floating-btn:hover{background:#0284c7} + dialog#debugDialog::backdrop{background:rgba(15,23,42,.45)} + #debugDialog{border:none;border-radius:1rem;padding:0;width:80vw;max-width:960px} + .debug-shell{display:flex;flex-direction:column;height:80vh} + .debug-header{display:flex;align-items:center;justify-content:space-between;padding:1rem;border-bottom:1px solid #e2e8f0} + .debug-tabs{display:flex;border-bottom:1px solid #e2e8f0} + .debug-tabs button{flex:1;padding:.75rem 1rem;border:none;background:transparent;cursor:pointer;font-weight:600} + .debug-tabs button.active{background:#e0f2fe;color:#0c4a6e} + .debug-panel{flex:1;overflow:auto;padding:1rem;background:#f8fafc} + #debugConsoleContent{font-family:monospace;font-size:.85rem;white-space:pre-wrap} + .debug-console-entry{margin-bottom:.35rem} + .debug-console-entry.log{color:#15803d} + .debug-console-entry.warn{color:#b45309} + .debug-console-entry.error{color:#b91c1c} + `; + document.head.appendChild(style); + debugStylesInjected = true; +} + +function ensureDebugDialog() { + if (debugDialog) return; + debugDialog = document.createElement('dialog'); + debugDialog.id = 'debugDialog'; + debugDialog.innerHTML = ` +
Keine Daten
'; + phpInfoContainer.innerHTML = ''; + phpInfoContainer.appendChild(frame); + debugPhpLoaded = true; + } catch (err) { + phpInfoContainer.textContent = err.message || 'Fehler beim Laden'; + } finally { + debugPhpLoading = false; + } +} + +function renderConsolePanel() { + if (!consoleContainer) return; + if (!consoleBuffer.length) { + consoleContainer.textContent = 'Noch keine Konsolenmeldungen in dieser Sitzung.'; + return; + } + const lines = consoleBuffer.map(entry => { + const time = entry.time.toLocaleTimeString(); + return `