Files
usbcheck.it/partials/structure/header.php
2025-11-29 00:59:58 +01:00

254 lines
11 KiB
PHP

<?php
// partials/structure/header.php
// Aktuelle Domain + Protokoll
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? app_primary_domain();
$baseUrl = $scheme . '://' . $host;
// Aktueller Page-Key (z.B. 'landing', 'fakecheck', 'dashboard')
$pageKey = $GLOBALS['pageKey'] ?? null;
// Nav-Anker: wenn nicht explizit gesetzt, aus der i18n-JSON holen
if (!isset($navAnchors) || !is_array($navAnchors)) {
if ($pageKey && function_exists('app_get_nav_anchors')) {
$navAnchors = app_get_nav_anchors($pageKey); // ['href' => '#how', 'label' => '...']
} else {
$navAnchors = [];
}
}
// Session sollte in config/fileload.php bereits gestartet sein.
// Falls nicht, hier Fallback:
if (session_status() !== PHP_SESSION_ACTIVE) {
@session_start();
}
// aktuellen User aus der Session holen (wenn vorhanden)
$currentUser = $_SESSION['user'] ?? null;
$isLoggedIn = is_array($currentUser) && !empty($currentUser['id']);
// Initialen für Avatar bestimmen
$userInitials = null;
if ($isLoggedIn) {
if (!empty($currentUser['initials'])) {
$userInitials = $currentUser['initials'];
} else {
$firstName = $currentUser['first_name'] ?? '';
$lastName = $currentUser['last_name'] ?? '';
$username = $currentUser['username'] ?? ($currentUser['email'] ?? 'U');
$initials = '';
if ($firstName !== '') {
$initials .= mb_substr($firstName, 0, 1);
}
if ($lastName !== '') {
$initials .= mb_substr($lastName, 0, 1);
}
if ($initials === '') {
$initials = mb_substr($username, 0, 2);
}
$userInitials = mb_strtoupper($initials);
}
}
// -----------------------------------------
// Sprachkontext direkt aus fileload.php
// -----------------------------------------
$currentLang = $GLOBALS['lang'] ?? 'en';
$availableLangs = $GLOBALS['availableLangs'] ?? [];
// Sicherheits-Fallback: falls aus irgendeinem Grund leer
if (!is_array($availableLangs) || empty($availableLangs)) {
$availableLangs = [
$currentLang => [
'code' => $currentLang,
'label' => strtoupper($currentLang),
'flag' => '🏳️',
],
];
}
// Sicherstellen, dass currentLang eine gültige Sprache ist
if (!isset($availableLangs[$currentLang])) {
$keys = array_keys($availableLangs);
$currentLang = $keys[0] ?? 'en';
}
// aktuelle Sprache-Info
$currentLangInfo = $availableLangs[$currentLang] ?? ['code' => $currentLang];
$currentLangFlag = $currentLangInfo['flag'] ?? '🏳️';
$currentLangCode = strtoupper($currentLangInfo['code'] ?? $currentLang);
$currentLangLabel = $currentLangInfo['label'] ?? $currentLangCode;
// -----------------------------------------
// Helper: URL mit anderem ?lang=.. bauen
// -----------------------------------------
$currentPath = strtok($_SERVER['REQUEST_URI'] ?? '/', '?');
$currentQuery = $_GET ?? [];
function build_lang_url(string $code, string $path, array $query): string
{
$query['lang'] = $code;
$qs = http_build_query($query);
return $path . ($qs ? ('?' . $qs) : '');
}
?>
<header class="sticky top-0 z-40 border-b border-brand-border/70 backdrop-blur bg-brand-bg/85">
<div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 flex items-center justify-between min-h-16 py-2">
<!-- Logo -->
<div class="flex items-center gap-3">
<a href="<?= htmlspecialchars(build_lang_url($currentLang, '/', [])) ?>" class="flex items-center gap-3">
<img src="<?= $baseUrl ?>/assets/img/logo_slogan.png"
alt="<?= htmlspecialchars(app_primary_domain()) ?> Logo"
class="h-9 w-auto">
<div class="hidden sm:flex flex-col leading-tight">
<span class="font-heading font-bold text-sm uppercase tracking-[0.18em] text-brand-muted">
<?= htmlspecialchars(app_primary_domain()) ?>
</span>
<span class="text-xs text-brand-muted" data-i18n="header_slogan">
Test USB drives
</span>
</div>
</a>
</div>
<!-- Navigation + Controls -->
<div class="flex items-center gap-6">
<!-- Hauptnavigation -->
<!-- Hauptnavigation -->
<?php if (!empty($navAnchors)): ?>
<!--
<?php
echo "<pre>";
print_r($navAnchors);
echo "</pre>";
?> <div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 flex items-center justify-between min-h-16 py-2">
-->
<nav class="flex flex-wrap items-center gap-x-4 gap-y-1 sm:gap-x-6 text-xs font-medium text-brand-muted uppercase tracking-[0.18em]">
<?php foreach ($navAnchors as $item): ?>
<?php
$href = $item['href'] ?? '#';
$label = $item['label'] ?? '';
$i18nKey = $item['i18n'] ?? '';
?>
<a href="<?= htmlspecialchars($href) ?>"
class="hover:text-brand-primary transition-colors"
<?php if ($i18nKey !== ''): ?>
data-i18n="<?= htmlspecialchars($i18nKey) ?>"
<?php endif; ?>
><?= htmlspecialchars($label) ?></a>
<?php endforeach; ?>
</nav>
<?php endif; ?>
<!-- Language Switcher -->
<div class="relative">
<button id="langCurrent"
type="button"
class="flex items-center gap-1 text-xs uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary transition">
<span id="langCurrentLabel"><?= htmlspecialchars($currentLangCode) ?></span>
<svg class="w-3 h-3 opacity-70" viewBox="0 0 20 20" aria-hidden="true">
<path d="M5 7l5 6 5-6" fill="currentColor" />
</svg>
</button>
<div id="langMenu"
class="hidden absolute right-0 mt-2 w-32 rounded-xl bg-brand-surface border border-brand-border shadow-lg py-1 text-xs z-40">
<?php foreach ($availableLangs as $code => $info): ?>
<?php
// 👉 aktuelle Sprache NICHT noch einmal im Menü anzeigen
if ($code === $currentLang) {
continue;
}
$flag = $info['flag'] ?? '🏳️';
$label = strtoupper($info['code'] ?? $code);
$url = build_lang_url($code, $currentPath, $currentQuery);
?>
<a href="<?= htmlspecialchars($url) ?>"
class="lang-pill flex items-center gap-2 w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60">
<span class="text-base"><?= htmlspecialchars($flag) ?></span>
<span><?= htmlspecialchars($label) ?></span>
</a>
<?php endforeach; ?>
</div>
</div>
<!-- Login / Avatar -->
<div class="relative">
<?php if (!$isLoggedIn): ?>
<!-- Nicht eingeloggt: Login-Button -->
<button id="loginButton"
type="button"
class="relative inline-flex items-center justify-center rounded-full bg-brand-primary px-4 py-1.5 text-xs font-semibold uppercase tracking-[0.18em] text-brand-bg shadow-soft hover:bg-cyan-400 transition-colors"
data-i18n="header_btn_login"
data-login-url="/login/?lang=<?= htmlspecialchars($currentLang) ?>">
Login
</button>
<?php else: ?>
<!-- Eingeloggt: Avatar + Dropdown -->
<button id="userAvatar"
type="button"
class="h-9 w-9 rounded-full border border-brand-border bg-brand-surface flex items-center justify-center text-xs font-semibold text-brand-text shadow-soft hover:border-brand-primary transition"
aria-label="Mein Konto"
aria-expanded="false"
aria-haspopup="true">
<span><?= htmlspecialchars($userInitials) ?></span>
</button>
<div id="userMenu"
class="hidden absolute right-0 mt-2 w-44 rounded-xl bg-brand-surface border border-brand-border shadow-lg py-1 text-xs z-40">
<a href="/dashboard/?lang=<?= htmlspecialchars($currentLang) ?>"
class="flex items-center gap-2 px-3 py-2 text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60 transition-colors"
data-i18n="header_menu_dashboard">
Dashboard
</a>
<button type="button"
class="flex items-center gap-2 w-full text-left px-3 py-2 text-brand-muted hover:text-red-400 hover:bg-red-500/10 transition-colors"
data-logout-link="true"
data-logout-href="/auth/logout?lang=<?= htmlspecialchars($currentLang) ?>"
data-i18n="header_menu_logout">
Logout
</button>
</div>
<?php endif; ?>
</div>
</div>
</div>
</header>
<!-- Logout-Modal -->
<div id="logoutModalBackdrop"
class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/60">
<div class="w-full max-w-sm rounded-2xl border border-brand-border bg-brand-surface shadow-soft p-6 space-y-4">
<h2 class="font-heading text-lg font-semibold text-brand-text" data-i18n="logout_title">
Wirklich abmelden?
</h2>
<p class="text-sm text-brand-muted" data-i18n="logout_text">
Du wirst von deinem USBCheck-Konto abgemeldet. Aktive Tests im Browser-Modus sind davon nicht betroffen.
</p>
<div class="flex justify-end gap-3 pt-2">
<button id="logoutCancel"
type="button"
class="px-4 py-2 rounded-full border border-brand-border text-xs font-semibold uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:border-brand-primary transition-colors"
data-i18n="logout_cancel">
Abbrechen
</button>
<button id="logoutConfirm"
type="button"
class="px-4 py-2 rounded-full bg-red-500 text-xs font-semibold uppercase tracking-[0.18em] text-white hover:bg-red-400 transition-colors"
data-i18n="logout_confirm">
Ja, abmelden
</button>
</div>
</div>
</div>