From 99098fa67817cef0878d625277342fc2d5e2af0b Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Sat, 22 Nov 2025 03:21:07 +0100 Subject: [PATCH] send --- partials/structure/header.php | 49 +++++++------ partials/structure/layout_end.php | 28 ++++++++ partials/structure/layout_start.php | 6 +- public/assets/js/header.js | 108 ++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 25 deletions(-) create mode 100644 public/assets/js/header.js diff --git a/partials/structure/header.php b/partials/structure/header.php index e24f6d8..763ce67 100644 --- a/partials/structure/header.php +++ b/partials/structure/header.php @@ -6,13 +6,13 @@ $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' $host = $_SERVER['HTTP_HOST'] ?? 'usbcheck.it'; $baseUrl = $scheme . '://' . $host; -// Wenn $navAnchors NICHT gesetzt ist → leeres Array +// Falls navAnchors nicht gesetzt sind → leeres Array if (!isset($navAnchors) || !is_array($navAnchors)) { $navAnchors = []; } // Session sollte in config/fileload.php bereits gestartet sein. -// Falls nicht, hier Fallback: +// Fallback: if (session_status() !== PHP_SESSION_ACTIVE) { @session_start(); } @@ -66,7 +66,7 @@ if ($isLoggedIn) { - +
@@ -119,19 +119,18 @@ if ($isLoggedIn) {
- - - - - - -
+ +
+ + + + +
-
- + + diff --git a/partials/structure/layout_end.php b/partials/structure/layout_end.php index fee4c6c..b86f1d0 100644 --- a/partials/structure/layout_end.php +++ b/partials/structure/layout_end.php @@ -47,6 +47,34 @@ foreach ($GLOBALS['page_footer_scripts'] as $script) { + + diff --git a/partials/structure/layout_start.php b/partials/structure/layout_start.php index f3610cb..eaf5b29 100644 --- a/partials/structure/layout_start.php +++ b/partials/structure/layout_start.php @@ -19,8 +19,10 @@ if (!isset($pageTitle) || !is_string($pageTitle) || $pageTitle === '') { if (!isset($pageDescription) || !is_string($pageDescription)) { $pageDescription = ''; } - -tpl_add_script('/assets/js/header-user-menu.js', 'footer', true, false, '', null); +if (function_exists('tpl_add_script')) { + tpl_add_script('/assets/js/header-user-menu.js', 'footer', true, false, '', null); + tpl_add_script('/assets/js/header.js', 'footer', true, false, '', null); +} // Kann später genutzt werden, falls du host-spezifische Sachen brauchst $host = $_SERVER['HTTP_HOST'] ?? ''; diff --git a/public/assets/js/header.js b/public/assets/js/header.js new file mode 100644 index 0000000..925c8df --- /dev/null +++ b/public/assets/js/header.js @@ -0,0 +1,108 @@ +// public/assets/js/header.js + +document.addEventListener('DOMContentLoaded', function () { + // ------------------------- + // Avatar-Menü ein-/ausblenden + // ------------------------- + const avatarBtn = document.getElementById('userAvatar'); + const userMenu = document.getElementById('userMenu'); + + if (avatarBtn && userMenu) { + avatarBtn.addEventListener('click', function (event) { + event.stopPropagation(); + userMenu.classList.toggle('hidden'); + + const expanded = avatarBtn.getAttribute('aria-expanded') === 'true'; + avatarBtn.setAttribute('aria-expanded', expanded ? 'false' : 'true'); + }); + + // Klick außerhalb schließt Menü + document.addEventListener('click', function (event) { + if (!userMenu.classList.contains('hidden')) { + const clickedInsideMenu = userMenu.contains(event.target); + const clickedAvatarButton = avatarBtn.contains(event.target); + + if (!clickedInsideMenu && !clickedAvatarButton) { + userMenu.classList.add('hidden'); + avatarBtn.setAttribute('aria-expanded', 'false'); + } + } + }); + } + + // ------------------------- + // Logout-Modal + // ------------------------- + const logoutButtons = document.querySelectorAll('[data-logout-link="true"]'); + const backdrop = document.getElementById('logoutModalBackdrop'); + const btnConfirm = document.getElementById('logoutConfirm'); + const btnCancel = document.getElementById('logoutCancel'); + + let logoutTarget = null; + + function showLogoutModal(targetHref) { + logoutTarget = targetHref || null; + if (!backdrop) return; + + backdrop.classList.remove('hidden'); + // kleine Fokushilfe: Escape schließt, Klick auf Hintergrund auch + document.body.classList.add('overflow-hidden'); + } + + function hideLogoutModal() { + if (!backdrop) return; + backdrop.classList.add('hidden'); + document.body.classList.remove('overflow-hidden'); + logoutTarget = null; + } + + // Logout-Link(s) abfangen + if (logoutButtons.length && backdrop && btnConfirm && btnCancel) { + logoutButtons.forEach(function (btn) { + btn.addEventListener('click', function (event) { + event.preventDefault(); + event.stopPropagation(); + + const href = btn.getAttribute('data-logout-href') || btn.getAttribute('href') || '/auth/logout'; + showLogoutModal(href); + + // Avatar-Menü beim Öffnen des Modals schließen + if (userMenu && !userMenu.classList.contains('hidden')) { + userMenu.classList.add('hidden'); + if (avatarBtn) { + avatarBtn.setAttribute('aria-expanded', 'false'); + } + } + }); + }); + + // Bestätigen → weiter zur Logout-URL + btnConfirm.addEventListener('click', function () { + if (logoutTarget) { + window.location.href = logoutTarget; + } else { + window.location.href = '/auth/logout'; + } + }); + + // Abbrechen → Modal schließen + btnCancel.addEventListener('click', function () { + hideLogoutModal(); + }); + + // Klick auf Hintergrund (außerhalb der Card) schließt ebenfalls + backdrop.addEventListener('click', function (event) { + const card = backdrop.querySelector('div.w-full.max-w-sm'); + if (card && !card.contains(event.target)) { + hideLogoutModal(); + } + }); + + // ESC-Taste schließt Modal + document.addEventListener('keydown', function (event) { + if (event.key === 'Escape' && !backdrop.classList.contains('hidden')) { + hideLogoutModal(); + } + }); + } +});