Finanzmanager/src/Views/layout/kopf.php
fds2610-bot 280664b8a3 Seitenleiste: Marke mit Münzstapel, ein Klick schiebt sie auf Symbolbreite
Die Marke oben in der Seitenleiste trägt jetzt das Coinstack-Symbol aus den
Altdaten und den zweifarbigen Schriftzug Finanz|manager – wie die
sidebar-brand im Steuerkram. Sie ist zugleich der Schalter: Ein Klick schiebt
die Leiste von 232 px auf 64 px zusammen, ein Klick auf das Symbol klappt sie
wieder auf. Die Menüpunkte behalten dabei Ziel und Symbol.

Der Zustand steht in einem Cookie und nicht im localStorage: So rendert der
Server die Leiste schon in der richtigen Breite, statt sie bei jedem
Seitenwechsel kurz breit aufblitzen zu lassen. Die Beschriftungen wandern
eingeklappt per clip-path aus dem Bild statt per display:none – sonst
verlören die Verweise ihren Namen für Vorleseprogramme.

Nebenbei: Die Marke hieß bisher .marke, wie die kleine Statusmarke weiter
unten im Stilblatt, deren Regeln sie überschrieben. Sie heißt jetzt
.seitenleisten-marke.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 11:45:45 +02:00

99 lines
4.8 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
use Finanzmanager\View;
/** @var string $titel */
/** @var array $flash */
/** @var string|null $aktuellerPfad */
/** @var array|null $benutzer */
$navigation = [
['pfad' => '/', 'name' => 'Cockpit', 'icon' => '⌂'],
['pfad' => '/konten', 'name' => 'Kontenübersicht', 'icon' => '▤'],
['pfad' => '/banking', 'name' => 'Online-Banking', 'icon' => '⇊'],
['pfad' => '/zahlungsverkehr', 'name' => 'Zahlungsverkehr', 'icon' => '⇄'],
['pfad' => '/auswertungen', 'name' => 'Auswertungen', 'icon' => '◱'],
['pfad' => '/planung', 'name' => 'Planung', 'icon' => '◷'],
['pfad' => '/wertpapiere', 'name' => 'Wertpapiere', 'icon' => '↗'],
// Termine und Verträge haben keinen eigenen Menüpunkt mehr, sind aber weiter
// erreichbar – deshalb leuchtet für sie die Verwaltung, unter der sie hängen.
['pfad' => '/verwaltung', 'name' => 'Verwaltung', 'icon' => '⚙', 'auch' => ['/termine', '/vertraege']],
];
// Ob die Seitenleiste eingeklappt ist, merkt sich ein Cookie. Das Skript
// setzt es beim Umschalten; hier entscheidet es schon beim Rendern, damit die
// breite Leiste nicht bei jedem Seitenwechsel kurz aufblitzt.
$eingeklappt = ($_COOKIE['seitenleiste'] ?? '') === 'eingeklappt';
/** @param list<string> $auch */
$istAktiv = static function (string $pfad, array $auch = []) use ($aktuellerPfad): bool {
if (!is_string($aktuellerPfad)) {
return false;
}
if ($pfad === '/') {
return $aktuellerPfad === '/' || $aktuellerPfad === '';
}
foreach ([$pfad, ...$auch] as $kandidat) {
if (str_starts_with($aktuellerPfad, $kandidat)) {
return true;
}
}
return false;
};
?>
<!DOCTYPE html>
<html lang="de"<?= ($thema = View::thema()) !== '' ? ' data-thema="' . View::h($thema) . '"' : '' ?>>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= View::h($titel ?? 'Finanzmanager') ?> – Finanzmanager</title>
<link rel="stylesheet" href="/static/app.css">
<!-- Nur hier eingebunden: Ein zweites Mal im Fuß ließe jeden Handler doppelt
laufen – Rückfragen kämen zweimal, Menüs entstünden zweimal. -->
<script src="/static/app.js" defer></script>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><text y='13' font-size='13'>€</text></svg>">
</head>
<body>
<?php include __DIR__ . '/meldungen.php'; ?>
<div class="rahmen<?= $eingeklappt ? ' eingeklappt' : '' ?>">
<nav class="seitenleiste" id="seitenleiste" aria-label="Hauptnavigation">
<!-- Die Marke ist zugleich der Schalter: Ein Klick schiebt die
Seitenleiste auf Symbolbreite zusammen und wieder auf. -->
<button type="button" class="seitenleisten-marke" data-seitenleiste-schalter
aria-controls="seitenleiste" aria-expanded="<?= $eingeklappt ? 'false' : 'true' ?>"
title="<?= $eingeklappt ? 'Seitenleiste ausklappen' : 'Seitenleiste einklappen' ?>">
<img src="/static/coinstack.png" alt="" class="marken-symbol">
<span class="marken-text">Finanz<span>manager</span></span>
</button>
<ul>
<?php foreach ($navigation as $eintrag): ?>
<li>
<?php /* title bleibt hinten: Der Navigationstest prüft href und
class in dieser Reihenfolge unmittelbar hintereinander. */ ?>
<a href="<?= View::h($eintrag['pfad']) ?>"
class="<?= $istAktiv($eintrag['pfad'], $eintrag['auch'] ?? []) ? 'aktiv' : '' ?>"
title="<?= View::h($eintrag['name']) ?>">
<span class="icon" aria-hidden="true"><?= $eintrag['icon'] ?></span>
<span class="beschriftung"><?= View::h($eintrag['name']) ?></span>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
<div class="hauptbereich">
<header class="werkzeugleiste">
<h1><?= View::h($titel ?? 'Finanzmanager') ?></h1>
<div class="werkzeuge">
<a href="/einstellungen" class="werkzeug" title="Einstellungen">⚙ Einstellungen</a>
<?php if (!empty($benutzer)): ?>
<span class="benutzer"><?= View::h($benutzer['anzeigename'] ?: $benutzer['benutzername']) ?></span>
<form method="post" action="/logout" class="inline">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken ?? '') ?>">
<button type="submit" class="werkzeug">Abmelden</button>
</form>
<?php endif; ?>
</div>
</header>
<main class="inhalt">