Files
skyview.astronomiemuseum.de/public/header.php
T

283 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
$title = isset($pageTitle) && is_string($pageTitle) && $pageTitle !== ''
? $pageTitle
: 'Skyview & AstroTools — Astronomiemuseum der Sternwarte Sonneberg';
$bodyClassAttr = '';
if (isset($bodyClass) && is_string($bodyClass) && trim($bodyClass) !== '') {
$bodyClassAttr = ' class="' . htmlspecialchars(trim($bodyClass), ENT_QUOTES, 'UTF-8') . '"';
}
$headerIntroPre = isset($headerIntroPre) && is_string($headerIntroPre) ? trim($headerIntroPre) : '';
$headerIntroTitle = isset($headerIntroTitle) && is_string($headerIntroTitle) ? trim($headerIntroTitle) : '';
$headerIntroSub = isset($headerIntroSub) && is_string($headerIntroSub) ? trim($headerIntroSub) : '';
$showHeaderIntro = $headerIntroPre !== '' || $headerIntroTitle !== '' || $headerIntroSub !== '';
$publicBasePath = isset($publicBasePath) && is_string($publicBasePath) ? rtrim($publicBasePath, '/') . '/' : '';
$pdoHeader = isset($pdo) ? $pdo : null;
$isAdmin = $loggedIn && (($_SESSION['role'] ?? '') === 'admin');
$pendingApprovals = 0;
if (($loggedIn || $isAdmin) && $pdoHeader === null) {
$cfgHeader = require __DIR__ . '/../config/database.php';
$pdoHeader = new PDO(
sprintf('mysql:host=%s;dbname=%s;charset=%s', $cfgHeader['host'], $cfgHeader['dbname'], $cfgHeader['charset'] ?? 'utf8mb4'),
$cfgHeader['user'],
$cfgHeader['pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);
}
// Standard-Standort des eingeloggten Benutzers laden
$currentLocation = null;
if (!empty($defaultLocation)) {
// Seite hat den Standort bereits geladen – direkt übernehmen
$currentLocation = $defaultLocation;
} elseif ($loggedIn && isset($_SESSION['user_id'])) {
// Eigene DB-Verbindung aufbauen falls die Seite keine bereitstellt
$stmtLoc = $pdoHeader->prepare(
'SELECT id, name, latitude, longitude, elevation, timezone
FROM app_user_locations
WHERE user_id = ? AND is_default = 1
LIMIT 1'
);
$stmtLoc->execute([(int)$_SESSION['user_id']]);
$currentLocation = $stmtLoc->fetch() ?: null;
}
if ($isAdmin && $pdoHeader !== null) {
$stmtPendingUsers = $pdoHeader->query('SELECT COUNT(*) FROM app_users WHERE is_active = 0');
$pendingApprovals = (int)$stmtPendingUsers->fetchColumn();
}
$menuGroups = [
[
'title' => 'Himmel &amp; Planeten',
'links' => [
['href' => 'moonphase.php', 'label' => 'Mondphase'],
['href' => 'index_py.php', 'label' => 'Sonne & Mond'],
['href' => 'planetensichtbarkeit.php', 'label' => 'Planetensichtbarkeit'],
['href' => 'solarsystem.php', 'label' => 'Sonnensystem'],
['href' => 'jupitersystem.php', 'label' => 'Jupitersystem'],
['href' => 'tagbogen.php', 'label' => 'Tagbogen'],
['href' => 'sternenhimmel.php', 'label' => 'Sternenhimmel'],
['href' => 'geocron/index.php', 'label' => 'Geocron'],
['href' => 'geocron3d.php', 'label' => 'Geocron 3D'],
],
],
[
'title' => 'Finsternisse &amp; Bedeckungen',
'links' => [
['href' => 'mondfinsternis.php', 'label' => 'Mondfinsternis'],
['href' => 'sonnenfinsternis.php', 'label' => 'Sonnenfinsternis'],
['href' => 'bedeckung.php', 'label' => 'Bedeckungsphänomene'],
['href' => 'sternbedeckungen.php', 'label' => 'Mond-Stern-Bedeckungen'],
],
],
];
$adminLinks = [
['href' => 'admin_users.php', 'label' => 'Benutzerverwaltung'],
['href' => 'monatsvorhersage.php', 'label' => 'Monatsvorhersage'],
];
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($title, ENT_QUOTES, 'UTF-8') ?></title>
<link rel="stylesheet" href="<?= htmlspecialchars($publicBasePath . 'css/style.css', ENT_QUOTES, 'UTF-8') ?>">
</head>
<body<?= $bodyClassAttr ?>>
<!-- Sternenhimmel -->
<canvas id="starfield"></canvas>
<script>
(function () {
const canvas = document.getElementById('starfield');
const ctx = canvas.getContext('2d');
let stars = [];
// Bilder vorladen
const imgRound = new Image();
const imgRays = new Image();
imgRound.src = <?= json_encode($publicBasePath . 'images/star16x16.png', JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>;
imgRays.src = <?= json_encode($publicBasePath . 'images/star16x16_rays.png', JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>;
function resize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
function generateStars() {
stars = [];
const count = Math.floor((canvas.width * canvas.height) / 2800);
for (let i = 0; i < count; i++) {
const r = Math.random();
// Klassen: 80% klein-rund, 17% mittel-rund, 3% mit Strahlen
const hasRays = r > 0.97;
const size = hasRays ? (Math.random() * 6 + 8) // 8–14 px
: r > 0.80 ? (Math.random() * 4 + 5) // 5–9 px
: (Math.random() * 3 + 2); // 2–5 px
stars.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size,
img: hasRays ? imgRays : imgRound,
base: hasRays ? Math.random() * 0.20 + 0.12
: Math.random() * 0.18 + 0.04,
amp: Math.random() * 0.08 + 0.01,
phase: Math.random() * Math.PI * 2,
speed: Math.random() * 0.0003 + 0.00008,
});
}
}
let t = 0;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
t++;
for (const s of stars) {
const a = s.base + s.amp * Math.sin(s.phase + t * s.speed * Math.PI * 2);
ctx.globalAlpha = a;
ctx.drawImage(s.img, s.x - s.size / 2, s.y - s.size / 2, s.size, s.size);
}
ctx.globalAlpha = 1;
requestAnimationFrame(draw);
}
// Erst zeichnen wenn beide Bilder geladen sind
let loaded = 0;
function onLoad() { if (++loaded === 2) { resize(); generateStars(); draw(); } }
imgRound.onload = onLoad;
imgRays.onload = onLoad;
window.addEventListener('resize', () => { resize(); generateStars(); });
})();
</script>
<header>
<div class="container">
<div class="header-inner">
<div class="header-brand">
<a href="<?= htmlspecialchars($publicBasePath . 'index.php', ENT_QUOTES, 'UTF-8') ?>">Skyview &amp; AstroTools</a>
<span class="header-sub"><a href="https://www.astronomiemuseum.de" target="_blank" rel="noopener">Astronomiemuseum der Sternwarte Sonneberg</a></span>
</div>
<?php if ($isAdmin && $pendingApprovals > 0): ?>
<a href="<?= htmlspecialchars($publicBasePath . 'admin_users.php', ENT_QUOTES, 'UTF-8') ?>" class="admin-alert" aria-live="polite">
<span class="admin-alert-icon" aria-hidden="true">!</span>
<span class="admin-alert-text">Achtung: <?= $pendingApprovals ?> <?= $pendingApprovals === 1 ? 'Benutzer wartet' : 'Benutzer warten' ?> auf Freischaltung</span>
</a>
<?php endif; ?>
<div class="header-menu">
<button type="button" class="menu-toggle" id="menuToggle" aria-expanded="false" aria-controls="headerMenuPanel" aria-label="Menue oeffnen">
<span></span>
<span></span>
<span></span>
</button>
<nav class="menu-panel" id="headerMenuPanel" hidden>
<div class="menu-cols">
<?php foreach ($menuGroups as $group): ?>
<div class="menu-group">
<div class="menu-title"><?= $group['title'] ?></div>
<?php foreach ($group['links'] as $link): ?>
<a href="<?= htmlspecialchars($publicBasePath . $link['href'], ENT_QUOTES, 'UTF-8') ?>">
<?= htmlspecialchars($link['label'], ENT_QUOTES, 'UTF-8') ?>
</a>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
<div class="menu-divider"></div>
<div class="menu-bottom">
<div class="menu-group">
<div class="menu-title">Konto</div>
<?php if ($loggedIn): ?>
<a href="<?= htmlspecialchars($publicBasePath . 'settings.php', ENT_QUOTES, 'UTF-8') ?>">Einstellungen</a>
<a href="<?= htmlspecialchars($publicBasePath . 'my_favorites.php', ENT_QUOTES, 'UTF-8') ?>">Favoriten</a>
<a href="<?= htmlspecialchars($publicBasePath . 'satellitenhimmel.php', ENT_QUOTES, 'UTF-8') ?>">Satellitenhimmel</a>
<a href="<?= htmlspecialchars($publicBasePath . 'logout.php', ENT_QUOTES, 'UTF-8') ?>" class="nav-logout">Abmelden</a>
<?php else: ?>
<a href="<?= htmlspecialchars($publicBasePath . 'login.php', ENT_QUOTES, 'UTF-8') ?>">Anmelden</a>
<a href="<?= htmlspecialchars($publicBasePath . 'register.php', ENT_QUOTES, 'UTF-8') ?>">Registrieren</a>
<?php endif; ?>
</div>
<?php if ($isAdmin): ?>
<div class="menu-group">
<div class="menu-title">Administration</div>
<?php foreach ($adminLinks as $adminLink): ?>
<a href="<?= htmlspecialchars($publicBasePath . $adminLink['href'], ENT_QUOTES, 'UTF-8') ?>">
<?= htmlspecialchars($adminLink['label'], ENT_QUOTES, 'UTF-8') ?>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</nav>
</div>
</div>
<?php if ($showHeaderIntro): ?>
<div class="page-header-intro">
<?php if ($headerIntroPre !== ''): ?>
<div class="page-header-pre"><?= htmlspecialchars($headerIntroPre, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($headerIntroTitle !== ''): ?>
<h1 class="page-header-title"><?= htmlspecialchars($headerIntroTitle, ENT_QUOTES, 'UTF-8') ?></h1>
<?php endif; ?>
<?php if ($headerIntroSub !== ''): ?>
<div class="page-header-sub"><?= htmlspecialchars($headerIntroSub, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</header>
<main>
<div class="container">
<script>
(function () {
const toggle = document.getElementById('menuToggle');
const panel = document.getElementById('headerMenuPanel');
if (!toggle || !panel) {
return;
}
function closeMenu() {
toggle.setAttribute('aria-expanded', 'false');
panel.hidden = true;
document.body.classList.remove('menu-open');
}
function openMenu() {
toggle.setAttribute('aria-expanded', 'true');
panel.hidden = false;
document.body.classList.add('menu-open');
}
toggle.addEventListener('click', function () {
if (toggle.getAttribute('aria-expanded') === 'true') {
closeMenu();
return;
}
openMenu();
});
document.addEventListener('click', function (event) {
if (panel.hidden) {
return;
}
if (!panel.contains(event.target) && !toggle.contains(event.target)) {
closeMenu();
}
});
document.addEventListener('keydown', function (event) {
if (event.key === 'Escape') {
closeMenu();
}
});
})();
</script>