first commit
This commit is contained in:
@@ -0,0 +1,277 @@
|
||||
<?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 !== '';
|
||||
$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 & 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'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => 'Finsternisse & 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'],
|
||||
];
|
||||
?>
|
||||
<!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="css/style.css">
|
||||
</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 = 'images/star16x16.png';
|
||||
imgRays.src = 'images/star16x16_rays.png';
|
||||
|
||||
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="index.php">Skyview & 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="admin_users.php" 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($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="settings.php">Einstellungen</a>
|
||||
<a href="my_favorites.php">Favoriten</a>
|
||||
<a href="satellitenhimmel.php">Satellitenhimmel</a>
|
||||
<a href="logout.php" class="nav-logout">Abmelden</a>
|
||||
<?php else: ?>
|
||||
<a href="login.php">Anmelden</a>
|
||||
<a href="register.php">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($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>
|
||||
Reference in New Issue
Block a user