XyX
All checks were successful
Deploy / deploy (push) Successful in 53s

This commit is contained in:
2026-08-06 01:17:05 +02:00
parent 80f1ad6b99
commit fa40ca1a60
9 changed files with 165 additions and 81 deletions

View File

@@ -9,7 +9,7 @@ $dashboardUserId = (int)($_SESSION['user_id'] ?? 0);
$editingEvent = isset($editEvent) && $editEvent !== null;
$editingListing = isset($editListing) && $editListing !== null;
$editing = $editingEvent || $editingListing;
$currentEntryKind = $editingListing ? (string)($editListing['listing_type'] ?? 'editorial_event') : 'event';
$currentEntryKind = $editingListing ? (string)($editListing['listing_type'] ?? 'editorial_event') : (($section ?? 'events') === 'places' ? 'place' : 'event');
$actionEvent = $editing ? 'event_update' : 'event_add';
$startVal = '';
if ($editingEvent && !empty($editEvent['starts_at'])) {
@@ -18,8 +18,8 @@ if ($editingEvent && !empty($editEvent['starts_at'])) {
$startVal = date('Y-m-d', strtotime((string)$editListing['starts_at']));
}
$withChildrenValue = $editingEvent ? (((int)($editEvent['allow_kids'] ?? 1)) === 1 ? 'yes' : 'no') : (($editingListing && $currentEntryKind === 'editorial_event' && !empty($editListing['supports_registration'])) ? 'yes' : 'yes');
$eventTitle = $editingEvent ? 'Event bearbeiten' : ($editingListing ? ($currentEntryKind === 'place' ? 'Ort bearbeiten' : 'Veranstaltung bearbeiten') : 'Neuen Eintrag anlegen');
$submitLabel = $editingEvent ? 'Event speichern' : ($editingListing ? ($currentEntryKind === 'place' ? 'Ort speichern' : 'Veranstaltung speichern') : 'Eintrag anlegen');
$eventTitle = $editingEvent ? 'Event bearbeiten' : ($editingListing ? ($currentEntryKind === 'place' ? 'Ort bearbeiten' : 'Veranstaltung bearbeiten') : ((($section ?? 'events') === 'places') ? 'Ausflugsziel anlegen' : 'Neues Event anlegen'));
$submitLabel = $editingEvent ? 'Event speichern' : ($editingListing ? ($currentEntryKind === 'place' ? 'Ort speichern' : 'Veranstaltung speichern') : ((($section ?? 'events') === 'places') ? 'Ausflugsziel anlegen' : 'Event anlegen'));
$titleValue = $editingEvent ? (string)($editEvent['title'] ?? '') : (string)($editListing['title'] ?? '');
$teaserValue = $editingEvent ? (string)($editEvent['teaser_public'] ?? '') : (string)($editListing['teaser_public'] ?? '');
$descriptionValue = $editingEvent ? (string)($editEvent['description'] ?? '') : (string)($editListing['description'] ?? '');
@@ -87,9 +87,12 @@ $sectionLinks = [
'profile' => 'Profil',
'children' => 'Kinder',
'events' => 'Events',
'places' => 'Ausflugsziele',
'community' => 'Community',
'settings' => 'Einstellungen',
];
$showEventTypeChoice = !$editing && (($section ?? 'events') === 'places');
$modalSectionTarget = ($editingListing || ($section ?? '') === 'places') ? 'places' : 'events';
if (!empty($canManageSystemSettings)) {
$sectionLinks['system'] = 'System';
}
@@ -275,12 +278,12 @@ if (!empty($canManageSystemSettings)) {
<?php if ($section === 'events'): ?>
<section class="account-panel" id="events">
<div class="account-panel__head">
<h2>Deine Einträge</h2>
<p class="muted">Lege eigene Events, dauerhafte Orte und sonstige zeitlich begrenzte Veranstaltungen sauber getrennt an.</p>
<h2>Deine Events</h2>
<p class="muted">Hier verwaltest du nur echte eigene Events und Events, an denen du teilnimmst.</p>
</div>
<div class="account-panel__body">
<div class="flex gap-12" style="margin:0 0 16px 0; flex-wrap: wrap;">
<button class="btn" type="button" data-modal-open="modalEvent">Eintrag anlegen</button>
<button class="btn" type="button" data-modal-open="modalEvent">Eigenes Event anlegen</button>
</div>
<div class="card" style="margin-bottom:18px;">
<strong>Eigene Events</strong>
@@ -353,11 +356,72 @@ if (!empty($canManageSystemSettings)) {
</details>
<div class="card" style="margin:22px 0 14px;">
<strong>Orte und sonstige Veranstaltungen</strong>
<p class="muted small" style="margin:8px 0 0;">Hier erscheinen dauerhafte Orte wie Spielplätze, Cafés oder Restaurants sowie zeitlich begrenzte Hinweise wie Zirkus oder Aktionsflächen.</p>
<strong>Events mit deiner Teilnahme</strong>
<p class="muted small" style="margin:8px 0 0;">Events anderer Nutzer, bei denen du eingetragen bist.</p>
</div>
<?php if (!$eventsJoinedUpcoming): ?>
<p class="muted small">Aktuell nimmst du an keinen zukünftigen Events teil.</p>
<?php else: ?>
<ul class="dash-list" style="margin-top:10px;">
<?php foreach ($eventsJoinedUpcoming as $entry): ?>
<li>
<div style="display:flex; justify-content:space-between; gap:12px; align-items:center; flex-wrap: wrap;">
<div>
<strong><?= htmlspecialchars((string)$entry['title'], ENT_QUOTES) ?></strong>
<div class="muted small" style="margin-top:4px;">
<?= htmlspecialchars(trim(implode(' · ', array_filter([
(string)($entry['city'] ?? ''),
!empty($entry['starts_at']) ? (string)$entry['starts_at'] : null,
!empty($entry['host_name']) ? 'Von ' . (string)$entry['host_name'] : null,
!empty($entry['participation_status']) ? 'Status: ' . (string)$entry['participation_status'] : null,
]))), ENT_QUOTES) ?>
</div>
</div>
</div>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<details style="margin-top:12px;">
<summary style="cursor:pointer;">Vergangene Teilnahmen anzeigen</summary>
<?php if (!$eventsJoinedPast): ?>
<p class="muted small">Keine vergangenen Event-Teilnahmen.</p>
<?php else: ?>
<ul class="dash-list" style="margin-top:10px;">
<?php foreach ($eventsJoinedPast as $entry): ?>
<li>
<div>
<strong><?= htmlspecialchars((string)$entry['title'], ENT_QUOTES) ?></strong>
<div class="muted small" style="margin-top:4px;">
<?= htmlspecialchars(trim(implode(' · ', array_filter([
(string)($entry['city'] ?? ''),
!empty($entry['starts_at']) ? (string)$entry['starts_at'] : null,
!empty($entry['host_name']) ? 'Von ' . (string)$entry['host_name'] : null,
!empty($entry['participation_status']) ? 'Status: ' . (string)$entry['participation_status'] : null,
]))), ENT_QUOTES) ?>
</div>
</div>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</details>
</div>
</section>
<?php endif; ?>
<?php if ($section === 'places'): ?>
<section class="account-panel" id="places">
<div class="account-panel__head">
<h2>Ausflugsziele</h2>
<p class="muted">Hier pflegst du Orte und sonstige Veranstaltungen als mögliche Ausflugsziele.</p>
</div>
<div class="account-panel__body">
<div class="flex gap-12" style="margin:0 0 16px 0; flex-wrap: wrap;">
<button class="btn" type="button" data-modal-open="modalEvent">Ausflugsziel anlegen</button>
</div>
<?php if (!$otherListings): ?>
<p class="muted small">Noch keine Orte oder sonstigen Veranstaltungen angelegt.</p>
<p class="muted small">Noch keine Orte oder Veranstaltungen angelegt.</p>
<?php else: ?>
<ul class="dash-list" style="margin-top:10px;">
<?php foreach ($otherListings as $entry): ?>
@@ -365,7 +429,7 @@ if (!empty($canManageSystemSettings)) {
<div style="display:flex; justify-content:space-between; gap:12px; align-items:center; flex-wrap: wrap;">
<div>
<strong><?= htmlspecialchars((string)$entry['title'], ENT_QUOTES) ?></strong>
<span class="badge"><?= ($entry['listing_type'] ?? '') === 'place' ? 'Ort' : 'Sonstige Veranstaltung' ?></span>
<span class="badge"><?= ($entry['listing_type'] ?? '') === 'place' ? 'Ort' : 'Veranstaltung' ?></span>
<?php if (!empty($entry['category_title'])): ?>
<span class="badge"><?= htmlspecialchars((string)$entry['category_title'], ENT_QUOTES) ?></span>
<?php endif; ?>
@@ -373,13 +437,12 @@ if (!empty($canManageSystemSettings)) {
<?= htmlspecialchars(trim(implode(' · ', array_filter([
(string)($entry['city'] ?? ''),
!empty($entry['starts_at']) ? (string)$entry['starts_at'] : null,
(string)($entry['visibility'] ?? ''),
]))), ENT_QUOTES) ?>
</div>
</div>
<div class="flex gap-8" style="flex-wrap: wrap;">
<a class="btn ghost" href="/dashboard?section=events&edit_listing=<?= (int)$entry['id'] ?>#events">Bearbeiten</a>
<form method="post" action="/dashboard?section=events#events" onsubmit="return confirm('Eintrag wirklich löschen?');">
<a class="btn ghost" href="/dashboard?section=places&edit_listing=<?= (int)$entry['id'] ?>#places">Bearbeiten</a>
<form method="post" action="/dashboard?section=places#places" onsubmit="return confirm('Eintrag wirklich löschen?');">
<input type="hidden" name="action" value="listing_delete">
<input type="hidden" name="listing_id" value="<?= (int)$entry['id'] ?>">
<button class="btn ghost" type="submit">Löschen</button>
@@ -934,7 +997,7 @@ if (!empty($canManageSystemSettings)) {
<h3><?= htmlspecialchars($eventTitle, ENT_QUOTES) ?></h3>
<button class="btn ghost" type="button" data-modal-close>✕</button>
</div>
<form class="stack gap-12" style="margin-top: 10px;" method="post" action="/dashboard?section=events#events" enctype="multipart/form-data">
<form class="stack gap-12" style="margin-top: 10px;" method="post" action="/dashboard?section=<?= htmlspecialchars($modalSectionTarget, ENT_QUOTES) ?>#<?= htmlspecialchars($modalSectionTarget, ENT_QUOTES) ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="<?= htmlspecialchars($actionEvent, ENT_QUOTES) ?>">
<input type="hidden" name="entry_kind" id="entryKind" value="<?= htmlspecialchars($currentEntryKind, ENT_QUOTES) ?>">
<?php if ($editingEvent && $editEvent): ?>
@@ -950,17 +1013,16 @@ if (!empty($canManageSystemSettings)) {
</option>
<?php endforeach; ?>
</datalist>
<?php if (!$editing): ?>
<?php if (!$editing && $showEventTypeChoice): ?>
<div class="stack gap-8">
<label class="label">Was möchtest du anlegen?</label>
<div class="chips" style="flex-wrap:wrap;">
<button class="btn ghost" type="button" data-entry-kind-choice="event">Eigenes Event</button>
<button class="btn ghost" type="button" data-entry-kind-choice="place">Ort</button>
<button class="btn ghost" type="button" data-entry-kind-choice="editorial_event">Sonstige Veranstaltung</button>
</div>
<p class="muted small" id="entryKindHint" style="margin:0;">Eigenes Event: von dir organisiert und mit konkretem Termin.</p>
<p class="muted small" id="entryKindHint" style="margin:0;">Ort: dauerhaft verfügbar oder Veranstaltung: zeitlich begrenzter Hinweis.</p>
</div>
<?php else: ?>
<?php elseif ($editing): ?>
<div class="card">
<strong>Eintragstyp</strong>
<p class="muted small" style="margin:8px 0 0;">
@@ -1047,28 +1109,25 @@ if (!empty($canManageSystemSettings)) {
<div id="eventAddressStatus" class="muted small" style="margin:0;"></div>
<input type="hidden" id="evLat" name="lat" value="<?= htmlspecialchars($latValue, ENT_QUOTES) ?>">
<input type="hidden" id="evLng" name="lng" value="<?= htmlspecialchars($lngValue, ENT_QUOTES) ?>">
<details class="card" id="mapDetails">
<summary style="cursor:pointer; font-weight:600;">Adresse auf Karte wählen</summary>
<div class="stack gap-6" style="margin-top:12px;">
<div class="card" id="mapDetails">
<div class="stack gap-6">
<div class="flex gap-8" style="flex-wrap:wrap; align-items:center;">
<strong>Karte</strong>
<button class="btn ghost" type="button" id="btnEventMapCurrentLocation">📍 Aktuellen Standort auf Karte zeigen</button>
</div>
<div class="stack gap-6">
<button class="btn ghost" type="button" id="btnMap">Auf Karte suchen</button>
<div id="mapWrapper" class="map-wrapper" hidden>
<div class="form-row">
<label class="label" for="mapSearch">Adresse suchen (optional)</label>
<div class="flex gap-8">
<input id="mapSearch" class="input" placeholder="Straße, PLZ, Ort">
<button class="btn ghost" type="button" id="btnMapSearch">Suchen</button>
</div>
<p class="muted small">Klick auf die Karte setzt den Treffpunkt. Zoom/Scroll möglich.</p>
<div id="mapWrapper" class="map-wrapper">
<div class="form-row">
<label class="label" for="mapSearch">Adresse suchen (optional)</label>
<div class="flex gap-8">
<input id="mapSearch" class="input" placeholder="Straße, PLZ, Ort">
<button class="btn ghost" type="button" id="btnMapSearch">Suchen</button>
</div>
<div id="mapContainer" class="map-container"></div>
<p class="muted small">Klick auf die Karte setzt den Treffpunkt. Änderungen an der Adresse aktualisieren die Karte automatisch.</p>
</div>
<div id="mapContainer" class="map-container"></div>
</div>
</div>
</details>
</div>
<details class="card" id="placeContactWrap">
<summary style="cursor:pointer; font-weight:600;">Kontaktangaben</summary>
<div class="form-grid" style="margin-top:12px;">
@@ -1165,6 +1224,11 @@ if (!empty($canManageSystemSettings)) {
const id = btn.getAttribute('data-modal-open');
const modal = document.getElementById(id);
if (modal) modal.classList.add('open');
if (id === 'modalEvent' && window.PKTConsent?.has?.('external_services')) {
ensureLeaflet(() => {
setTimeout(() => initMap(), 80);
});
}
});
});
document.querySelectorAll('[data-modal-close]').forEach(btn => {
@@ -1180,7 +1244,6 @@ if (!empty($canManageSystemSettings)) {
});
// Map picker for events (Leaflet)
const btnMap = document.getElementById('btnMap');
const mapWrapper = document.getElementById('mapWrapper');
const mapContainer = document.getElementById('mapContainer');
const btnMapSearch = document.getElementById('btnMapSearch');
@@ -1520,13 +1583,6 @@ if (!empty($canManageSystemSettings)) {
}
}
btnMap?.addEventListener('click', () => {
mapWrapper.hidden = false;
ensureLeaflet(() => {
setTimeout(() => initMap(), 50);
});
});
btnMapSearch?.addEventListener('click', () => {
const q = (mapSearch?.value || '').trim();
if (!q) return;