feat: enhance termine.php with year/month filtering, sidebar grouping, and improved layout styling
This commit is contained in:
@@ -268,6 +268,9 @@
|
||||
.mx-auto {
|
||||
margin-inline: auto;
|
||||
}
|
||||
.mt-1 {
|
||||
margin-top: calc(var(--spacing) * 1);
|
||||
}
|
||||
.mt-2 {
|
||||
margin-top: calc(var(--spacing) * 2);
|
||||
}
|
||||
@@ -295,6 +298,9 @@
|
||||
.ml-1 {
|
||||
margin-left: calc(var(--spacing) * 1);
|
||||
}
|
||||
.ml-4 {
|
||||
margin-left: calc(var(--spacing) * 4);
|
||||
}
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
@@ -658,6 +664,9 @@
|
||||
.text-sf_blau-500 {
|
||||
color: var(--color-sf_blau-500);
|
||||
}
|
||||
.text-sf_blau-600 {
|
||||
color: var(--color-sf_blau-600);
|
||||
}
|
||||
.text-sf_blau-700 {
|
||||
color: var(--color-sf_blau-700);
|
||||
}
|
||||
@@ -753,6 +762,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.group-\[\.open\]\:rotate-90 {
|
||||
&:is(:where(.group):is(.open) *) {
|
||||
rotate: 90deg;
|
||||
}
|
||||
}
|
||||
.odd\:bg-white {
|
||||
&:nth-child(odd) {
|
||||
background-color: var(--color-white);
|
||||
@@ -855,6 +869,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:underline {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
.focus\:text-blue-600 {
|
||||
&:focus {
|
||||
color: var(--color-blue-600);
|
||||
@@ -907,6 +928,11 @@
|
||||
margin-top: calc(var(--spacing) * 8);
|
||||
}
|
||||
}
|
||||
.md\:mb-0 {
|
||||
@media (width >= 48rem) {
|
||||
margin-bottom: calc(var(--spacing) * 0);
|
||||
}
|
||||
}
|
||||
.md\:block {
|
||||
@media (width >= 48rem) {
|
||||
display: block;
|
||||
@@ -927,11 +953,26 @@
|
||||
width: calc(1/2 * 100%);
|
||||
}
|
||||
}
|
||||
.md\:w-1\/4 {
|
||||
@media (width >= 48rem) {
|
||||
width: calc(1/4 * 100%);
|
||||
}
|
||||
}
|
||||
.md\:w-3\/4 {
|
||||
@media (width >= 48rem) {
|
||||
width: calc(3/4 * 100%);
|
||||
}
|
||||
}
|
||||
.md\:w-36 {
|
||||
@media (width >= 48rem) {
|
||||
width: calc(var(--spacing) * 36);
|
||||
}
|
||||
}
|
||||
.md\:flex-row {
|
||||
@media (width >= 48rem) {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
.md\:px-10 {
|
||||
@media (width >= 48rem) {
|
||||
padding-inline: calc(var(--spacing) * 10);
|
||||
|
||||
+105
-9
@@ -67,11 +67,103 @@
|
||||
return isset($event['DTSTART']) && $event['DTSTART'] >= $today;
|
||||
});
|
||||
|
||||
// --- Deutsche Monatsnamen ---
|
||||
$de_months = [
|
||||
'01' => 'Januar', '02' => 'Februar', '03' => 'März', '04' => 'April', '05' => 'Mai', '06' => 'Juni',
|
||||
'07' => 'Juli', '08' => 'August', '09' => 'September', '10' => 'Oktober', '11' => 'November', '12' => 'Dezember'
|
||||
];
|
||||
|
||||
// --- Gruppierung aller Termine nach Jahr und Monat für die Sidebar ---
|
||||
function group_events_by_year_month($events) {
|
||||
$grouped = [];
|
||||
foreach ($events as $event) {
|
||||
if (!isset($event['DTSTART'])) continue;
|
||||
$date = $event['DTSTART'];
|
||||
$year = substr($date, 0, 4);
|
||||
$month = substr($date, 4, 2);
|
||||
$grouped[$year][$month][] = $event;
|
||||
}
|
||||
krsort($grouped); // Jahre absteigend
|
||||
foreach ($grouped as &$months) {
|
||||
krsort($months); // Monate absteigend
|
||||
}
|
||||
return $grouped;
|
||||
}
|
||||
$all_events_grouped = group_events_by_year_month($events);
|
||||
|
||||
// --- Filter aus URL ---
|
||||
$filter_jahr = $_GET['jahr'] ?? null;
|
||||
$filter_monat = $_GET['monat'] ?? null;
|
||||
if ($filter_jahr && $filter_monat) {
|
||||
$filtered_events = array_filter($events, function($event) use ($filter_jahr, $filter_monat) {
|
||||
$date = $event['DTSTART'] ?? '';
|
||||
return substr($date, 0, 4) === $filter_jahr && substr($date, 4, 2) === $filter_monat;
|
||||
});
|
||||
} elseif ($filter_jahr) {
|
||||
$filtered_events = array_filter($events, function($event) use ($filter_jahr) {
|
||||
$date = $event['DTSTART'] ?? '';
|
||||
return substr($date, 0, 4) === $filter_jahr;
|
||||
});
|
||||
} else {
|
||||
$filtered_events = $future_events;
|
||||
}
|
||||
?>
|
||||
<section class="py-24 bg-sf_grau-50">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<?php if (empty($future_events)): ?>
|
||||
<div class="text-gray-500">Keine bevorstehenden Termine gefunden.</div>
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row gap-8">
|
||||
<!-- Sidebar -->
|
||||
<aside class="md:w-1/4 w-full mb-8 md:mb-0">
|
||||
<div class="bg-white rounded-lg shadow p-4">
|
||||
<h2 class="text-lg font-semibold mb-3">Termine nach Jahr/Monat</h2>
|
||||
<ul class="space-y-1">
|
||||
<?php foreach ($all_events_grouped as $year => $months): ?>
|
||||
<li class="mb-2">
|
||||
<div class="flex items-center">
|
||||
<a href="?jahr=<?php echo $year; ?>" class="font-bold text-sf_blau-600 focus:outline-none flex items-center group<?php if ($filter_jahr === $year && !$filter_monat) echo ' underline'; ?><?php if ($filter_jahr === $year && !$filter_monat) echo ' selected'; ?>" onclick="event.stopPropagation(); openYear('<?php echo $year; ?>')">
|
||||
<span><?php echo $year; ?></span>
|
||||
</a>
|
||||
<button type="button" class="ml-1 focus:outline-none" onclick="toggleYear('<?php echo $year; ?>')">
|
||||
<svg class="w-4 h-4 transition-transform" id="arrow-<?php echo $year; ?>" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="ml-4 mt-1 hidden" id="months-<?php echo $year; ?>">
|
||||
<?php foreach ($months as $month => $evts): ?>
|
||||
<li>
|
||||
<a href="?jahr=<?php echo $year; ?>&monat=<?php echo $month; ?>" class="text-sf_blau-500 hover:underline<?php if ($filter_jahr === $year && $filter_monat === $month) echo ' font-bold underline selected'; ?>">
|
||||
<?php echo $de_months[$month]; ?> (<?php echo count($evts); ?>)
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<script>
|
||||
function toggleYear(year) {
|
||||
var ul = document.getElementById('months-' + year);
|
||||
var arrow = document.getElementById('arrow-' + year);
|
||||
if (ul.classList.contains('hidden')) {
|
||||
ul.classList.remove('hidden');
|
||||
arrow.style.transform = 'rotate(90deg)';
|
||||
} else {
|
||||
ul.classList.add('hidden');
|
||||
arrow.style.transform = '';
|
||||
}
|
||||
}
|
||||
function openYear(year) {
|
||||
var ul = document.getElementById('months-' + year);
|
||||
var arrow = document.getElementById('arrow-' + year);
|
||||
if (ul && ul.classList.contains('hidden')) {
|
||||
ul.classList.remove('hidden');
|
||||
arrow.style.transform = 'rotate(90deg)';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</aside>
|
||||
<!-- Hauptinhalt Termine -->
|
||||
<div class="md:w-3/4 w-full">
|
||||
<?php if (empty($filtered_events)): ?>
|
||||
<div class="text-gray-500">Keine Termine gefunden.</div>
|
||||
<?php else: ?>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full border border-gray-200 bg-white rounded-lg shadow">
|
||||
@@ -80,12 +172,10 @@
|
||||
<th class="py-2 px-4 border-b text-left">Datum</th>
|
||||
<th class="py-2 px-4 border-b text-left">Uhrzeit</th>
|
||||
<th class="py-2 px-4 border-b text-left">Titel</th>
|
||||
<th class="py-2 px-4 border-b text-left">Ort</th>
|
||||
<th class="py-2 px-4 border-b text-left">Beschreibung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($future_events as $event): ?>
|
||||
<?php foreach ($filtered_events as $event): ?>
|
||||
<?php
|
||||
$start = $event['DTSTART'] ?? '';
|
||||
$end = $event['DTEND'] ?? '';
|
||||
@@ -100,13 +190,19 @@
|
||||
<td class="py-2 px-4 border-b whitespace-nowrap"><?php echo htmlspecialchars($date); ?></td>
|
||||
<td class="py-2 px-4 border-b whitespace-nowrap"><?php echo htmlspecialchars($time); ?></td>
|
||||
<td class="py-2 px-4 border-b"><?php echo htmlspecialchars($summary); ?></td>
|
||||
<td class="py-2 px-4 border-b"><?php echo htmlspecialchars($location); ?></td>
|
||||
<td class="py-2 px-4 border-b"><?php echo nl2br(htmlspecialchars($desc)); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.selected {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</section>
|
||||
Reference in New Issue
Block a user