Eventupdate
All checks were successful
Deploy / deploy (push) Successful in 1m0s

This commit is contained in:
2026-08-04 22:00:43 +02:00
parent 9cfa26a031
commit ac32727dc6
12 changed files with 584 additions and 230 deletions

View File

@@ -17,7 +17,7 @@ if ($editingEvent && !empty($editEvent['starts_at'])) {
} elseif ($editingListing && !empty($editListing['starts_at'])) {
$startVal = date('Y-m-d\TH:i', strtotime((string)$editListing['starts_at']));
}
$allowNoKidsChecked = $editingEvent ? ((int)$editEvent['allow_kids'] === 0) : false;
$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');
$titleValue = $editingEvent ? (string)($editEvent['title'] ?? '') : (string)($editListing['title'] ?? '');
@@ -31,8 +31,14 @@ $regionValue = $editingEvent ? (string)($editEvent['region'] ?? '') : (string)($
$latValue = $editingEvent ? (string)($editEvent['lat'] ?? '') : (string)($editListing['lat'] ?? '');
$lngValue = $editingEvent ? (string)($editEvent['lng'] ?? '') : (string)($editListing['lng'] ?? '');
$visibilityValue = $editingEvent ? (string)($editEvent['visibility'] ?? 'public') : (string)($editListing['visibility'] ?? 'public');
$categorySlugValue = $editingListing ? (string)($editListing['category_slug'] ?? '') : '';
$categorySlugValue = $editingEvent ? (string)($editEvent['category_slug'] ?? '') : (string)($editListing['category_slug'] ?? '');
$imagePathValue = $editingEvent ? (string)($editEvent['image_path'] ?? '') : (string)($editListing['image_path'] ?? '');
$capacityValue = $editingEvent ? (string)($editEvent['max_participants'] ?? '') : (string)($editListing['capacity_total'] ?? '');
$phoneValue = $editingListing ? (string)($editListing['phone'] ?? '') : '';
$websiteValue = $editingListing ? (string)($editListing['website_url'] ?? '') : '';
$specialConditionsValue = $editingListing ? (string)($editListing['special_conditions_note'] ?? '') : '';
$openingHoursValue = $editingListing ? (string)($editListing['opening_hours_note'] ?? '') : '';
$openingHoursRows = $editingListing && !empty($editListing['opening_hours']) && is_array($editListing['opening_hours']) ? $editListing['opening_hours'] : [['day_label' => '', 'time_from' => '', 'time_to' => '', 'note' => '']];
$recurrenceRuleValue = $editingListing ? (string)($editListing['recurrence_rule'] ?? '') : '';
$recurrenceUntilValue = '';
if ($editingListing && !empty($editListing['recurrence_until'])) {
@@ -57,41 +63,14 @@ if (preg_match('/BYDAY=([A-Z,]+)/', $recurrenceRuleValue, $matches)) {
}
}
}
$priceModeValue = 'none';
$freeChildUntilAge = '';
$priceChildAmount = '';
$priceChildAgeFrom = '';
$priceChildAgeTo = '';
$priceAdultAmount = '';
$priceAdultAgeFrom = '';
if ($editingListing && !empty($editListing['prices']) && is_array($editListing['prices'])) {
foreach ($editListing['prices'] as $priceRow) {
$audience = (string)($priceRow['audience'] ?? '');
$priceType = (string)($priceRow['price_type'] ?? '');
$note = (string)($priceRow['note'] ?? '');
if ($priceType === 'free') {
$priceModeValue = 'free_child_rule';
if (preg_match('/bis\s+(\d+)/u', $note, $m)) {
$freeChildUntilAge = $m[1];
}
} elseif ($audience === 'child') {
$priceModeValue = 'paid';
$priceChildAmount = (string)($priceRow['amount'] ?? '');
if (preg_match('/ab\s+(\d+)/u', $note, $m)) {
$priceChildAgeFrom = $m[1];
}
if (preg_match('/bis\s+(\d+)/u', $note, $m)) {
$priceChildAgeTo = $m[1];
}
} elseif ($audience === 'adult') {
$priceModeValue = 'paid';
$priceAdultAmount = (string)($priceRow['amount'] ?? '');
if (preg_match('/ab\s+(\d+)/u', $note, $m)) {
$priceAdultAgeFrom = $m[1];
}
}
}
}
$priceRows = $editingListing && !empty($editListing['prices']) && is_array($editListing['prices']) ? $editListing['prices'] : [[
'label' => '',
'audience' => 'general',
'price_type' => 'fixed',
'amount' => '',
'amount_secondary' => '',
'note' => '',
]];
$editingChild = isset($editChild) && $editChild !== null;
$childAction = $editingChild ? 'child_update' : 'child_add';
$childModalTitle = $editingChild ? 'Kind bearbeiten' : 'Kind hinzufügen';
@@ -908,7 +887,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">
<form class="stack gap-12" style="margin-top: 10px;" method="post" action="/dashboard?section=events#events" 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): ?>
@@ -942,16 +921,31 @@ if (!empty($canManageSystemSettings)) {
</p>
</div>
<?php endif; ?>
<div class="form-grid" id="titleDescriptionRow">
<div class="stack gap-6">
<label class="label" for="evTitle">Titel</label>
<input id="evTitle" name="title" class="input" placeholder="z. B. Väter-Kaffee im Park" required value="<?= htmlspecialchars($titleValue, ENT_QUOTES) ?>">
</div>
<div class="stack gap-6">
<label class="label" for="evTitle">Titel</label>
<input id="evTitle" name="title" class="input" placeholder="z. B. Väter-Kaffee im Park" required value="<?= htmlspecialchars($titleValue, ENT_QUOTES) ?>">
</div>
<div class="stack gap-6">
<label class="label" for="evDesc">Beschreibung (voll)</label>
<textarea id="evDesc" name="description" class="textarea" rows="3" placeholder="Was soll passieren, was mitbringen?" required><?= htmlspecialchars($descriptionValue, ENT_QUOTES) ?></textarea>
<p class="muted small" style="margin:0;">Die Kurzbeschreibung wird intern automatisch aus deinem Text erzeugt.</p>
<label class="label" for="evDesc">Beschreibung</label>
<textarea id="evDesc" name="description" class="textarea" rows="4" placeholder="Was erwartet Familien vor Ort?" required><?= htmlspecialchars($descriptionValue, ENT_QUOTES) ?></textarea>
<p class="muted small" style="margin:0;">Die Kurzbeschreibung wird automatisch aus dem Text erzeugt.</p>
</div>
<div class="form-grid">
<div class="stack gap-6">
<label class="label" for="listingCategorySlug">Kategorie</label>
<select id="listingCategorySlug" name="category_slug" class="select">
<option value="">Bitte auswählen</option>
<?php foreach ($listingCategories as $category): ?>
<option value="<?= htmlspecialchars((string)$category['slug'], ENT_QUOTES) ?>" <?= $categorySlugValue === (string)$category['slug'] ? 'selected' : '' ?>>
<?= htmlspecialchars((string)$category['title'], ENT_QUOTES) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="stack gap-6">
<label class="label" for="categoryCustomTitle">Oder neue Kategorie</label>
<input id="categoryCustomTitle" name="category_custom_title" class="input" placeholder="z. B. Tierpark">
</div>
</div>
<div class="stack gap-6" id="placeLookupWrap">
<label class="label" for="existingPlaceLookup">Vorhandenen Ort suchen (optional)</label>
@@ -959,33 +953,36 @@ if (!empty($canManageSystemSettings)) {
<input id="existingPlaceLookup" class="input" list="existingPlacesList" placeholder="z. B. Tierpark, Café, Spielplatz" style="flex:1;">
<button class="btn ghost" type="button" id="btnUseExistingPlace">Ort übernehmen</button>
</div>
<p class="muted small" style="margin:0;">Wenn ein passender Ort schon existiert, kannst du ihn übernehmen. Falls nichts passt, legst du unten einfach einen neuen Ort an.</p>
</div>
<div class="stack gap-6">
<label class="label" for="imageFile">Bild (optional)</label>
<input id="imageFile" name="image_file" class="input" type="file" accept="image/jpeg,image/png,image/webp">
<?php if ($imagePathValue !== ''): ?>
<div class="muted small">Aktuelles Bild: <a href="<?= htmlspecialchars($imagePathValue, ENT_QUOTES) ?>" target="_blank" rel="noopener">Ansehen</a></div>
<?php endif; ?>
</div>
<div class="form-grid" id="eventDateRow">
<div class="stack gap-6">
<label class="label" for="evDate">Datum & Uhrzeit</label>
<label class="label" for="evDate">Start / Termin</label>
<input id="evDate" name="starts_at" class="input" type="datetime-local" required value="<?= htmlspecialchars($startVal, ENT_QUOTES) ?>">
</div>
<div class="stack gap-6" id="eventLocationLabelWrap">
<label class="label" for "evLoc">Ort/Label</label>
<input id="evLoc" name="location_label" class="input" placeholder="Park / Café" value="<?= htmlspecialchars($locationLabelValue, ENT_QUOTES) ?>">
<label class="label" for="evLoc">Ort-Label</label>
<input id="evLoc" name="location_label" class="input" placeholder="z. B. Café Sonnenseite" value="<?= htmlspecialchars($locationLabelValue, ENT_QUOTES) ?>">
</div>
</div>
<div class="stack gap-6" id="eventCategoryWrap">
<label class="label" for="listingCategorySlug">Kategorie</label>
<select id="listingCategorySlug" name="category_slug" class="select">
<option value="">Bitte auswählen</option>
<?php foreach ($listingCategories as $category): ?>
<option value="<?= htmlspecialchars((string)$category['slug'], ENT_QUOTES) ?>" <?= $categorySlugValue === (string)$category['slug'] ? 'selected' : '' ?>>
<?= htmlspecialchars((string)$category['title'], ENT_QUOTES) ?>
</option>
<?php endforeach; ?>
</select>
<p class="muted small" style="margin:0;">Für Orte und sonstige Veranstaltungen, damit Spielplatz, Café, Restaurant, Zoo oder Zirkus sauber unterscheidbar bleiben.</p>
</div>
<div class="stack gap-6" id="placeOpeningHoursWrap">
<label class="label" for="openingHoursNote">Öffnungszeiten / Hinweise</label>
<textarea id="openingHoursNote" name="opening_hours_note" class="textarea" rows="2" placeholder="z. B. täglich 10:00 bis 18:00 Uhr"><?= htmlspecialchars($openingHoursValue, ENT_QUOTES) ?></textarea>
<div class="form-grid" id="eventMetaRow">
<div class="stack gap-6" id="eventChildrenWrap">
<label class="label" for="withChildren">Mit Kindern</label>
<select id="withChildren" name="with_children" class="select">
<option value="yes" <?= $withChildrenValue === 'yes' ? 'selected' : '' ?>>Ja</option>
<option value="no" <?= $withChildrenValue === 'no' ? 'selected' : '' ?>>Nein</option>
</select>
</div>
<div class="stack gap-6" id="eventCapacityWrap">
<label class="label" for="maxParticipants">Platzzahl (optional)</label>
<input id="maxParticipants" name="max_participants" class="input" type="number" min="1" value="<?= htmlspecialchars($capacityValue, ENT_QUOTES) ?>" placeholder="leer = offen">
</div>
</div>
<div class="stack gap-6" id="eventRecurrenceWrap">
<label class="label" for="recurrenceMode">Wiederholung</label>
@@ -1005,7 +1002,7 @@ if (!empty($canManageSystemSettings)) {
<?php endforeach; ?>
</div>
<div class="stack gap-6">
<label class="label" for="recurrenceUntil">Wiederholen bis</label>
<label class="label" for="recurrenceUntil">Gültig bis</label>
<input id="recurrenceUntil" name="recurrence_until" class="input" type="datetime-local" value="<?= htmlspecialchars($recurrenceUntilValue, ENT_QUOTES) ?>">
</div>
</div>
@@ -1032,12 +1029,42 @@ if (!empty($canManageSystemSettings)) {
</div>
<div class="flex gap-8" style="flex-wrap:wrap; align-items:center;">
<button class="btn ghost" type="button" id="btnEventAddressSearch">Adresse suchen</button>
<button class="btn ghost" type="button" id="btnEventBrowserLocation">Browser-Adresse übernehmen</button>
<button class="btn ghost" type="button" id="btnAddrToMap">Adresse auf Karte setzen</button>
<span class="muted small">Hält Karte und Adresse synchron.</span>
</div>
<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) ?>">
<div class="stack gap-6" id="placeContactWrap">
<div class="form-grid">
<div class="stack gap-6">
<label class="label" for="placePhone">Telefon (optional)</label>
<input id="placePhone" name="phone" class="input" value="<?= htmlspecialchars($phoneValue, ENT_QUOTES) ?>">
</div>
<div class="stack gap-6">
<label class="label" for="placeWebsite">Webseite (optional)</label>
<input id="placeWebsite" name="website_url" class="input" type="url" placeholder="https://..." value="<?= htmlspecialchars($websiteValue, ENT_QUOTES) ?>">
</div>
</div>
</div>
<div class="stack gap-6" id="placeOpeningHoursWrap">
<div class="flex between center-y">
<label class="label" for="openingHoursNote">Öffnungszeiten / Zeitfenster</label>
<button class="btn ghost" type="button" id="btnAddOpeningRow">Zeit hinzufügen</button>
</div>
<div id="openingHoursRows" class="stack gap-8">
<?php foreach ($openingHoursRows as $openingRow): ?>
<div class="form-grid opening-row">
<input name="opening_day_label[]" class="input" placeholder="z. B. Montag oder täglich" value="<?= htmlspecialchars((string)($openingRow['day_label'] ?? ''), ENT_QUOTES) ?>">
<input name="opening_time_from[]" class="input" type="time" value="<?= htmlspecialchars((string)($openingRow['time_from'] ?? ''), ENT_QUOTES) ?>">
<input name="opening_time_to[]" class="input" type="time" value="<?= htmlspecialchars((string)($openingRow['time_to'] ?? ''), ENT_QUOTES) ?>">
<input name="opening_note[]" class="input" placeholder="Hinweis" value="<?= htmlspecialchars((string)($openingRow['note'] ?? ''), ENT_QUOTES) ?>">
</div>
<?php endforeach; ?>
</div>
<textarea id="openingHoursNote" name="opening_hours_note" class="textarea" rows="2" placeholder="Freitext-Hinweis zu Öffnungszeiten oder Besonderheiten"><?= htmlspecialchars($openingHoursValue, ENT_QUOTES) ?></textarea>
</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>
@@ -1062,48 +1089,45 @@ if (!empty($canManageSystemSettings)) {
</div>
</div>
<div class="stack gap-10" id="eventPricingWrap">
<label class="label" for="priceMode">Eintritt / Kosten</label>
<select id="priceMode" name="price_mode" class="select">
<option value="none" <?= $priceModeValue === 'none' ? 'selected' : '' ?>>Keine Preisangabe</option>
<option value="free_child_rule" <?= $priceModeValue === 'free_child_rule' ? 'selected' : '' ?>>Frei für Kinder bis zu einem Alter</option>
<option value="paid" <?= $priceModeValue === 'paid' ? 'selected' : '' ?>>Bezahlter Eintritt</option>
</select>
<div class="form-grid" id="freeChildRuleWrap">
<div class="stack gap-6">
<label class="label" for="freeChildUntilAge">Kinder frei bis Alter</label>
<input id="freeChildUntilAge" name="free_child_until_age" class="input" type="number" min="0" max="25" value="<?= htmlspecialchars($freeChildUntilAge, ENT_QUOTES) ?>">
</div>
<div class="flex between center-y">
<label class="label">Eintritt / Kosten</label>
<button class="btn ghost" type="button" id="btnAddPriceRow">Preisregel hinzufügen</button>
</div>
<div class="stack gap-12" id="paidPricingWrap">
<div class="form-grid">
<div class="stack gap-6">
<label class="label" for="priceChildAmount">Preis pro Kind</label>
<input id="priceChildAmount" name="price_child_amount" class="input" inputmode="decimal" placeholder="z. B. 12,50" value="<?= htmlspecialchars($priceChildAmount, ENT_QUOTES) ?>">
<div id="priceRows" class="stack gap-8">
<?php foreach ($priceRows as $priceRow): ?>
<div class="stack gap-8 price-row card">
<div class="form-grid">
<input name="price_label[]" class="input" placeholder="z. B. Kinder 4-7" value="<?= htmlspecialchars((string)($priceRow['label'] ?? ''), ENT_QUOTES) ?>">
<select name="price_audience[]" class="select">
<?php foreach (['general' => 'Allgemein', 'child' => 'Kinder', 'adult' => 'Erwachsene', 'family' => 'Familie', 'group' => 'Gruppe'] as $audienceValue => $audienceLabel): ?>
<option value="<?= htmlspecialchars($audienceValue, ENT_QUOTES) ?>" <?= (string)($priceRow['audience'] ?? 'general') === $audienceValue ? 'selected' : '' ?>><?= htmlspecialchars($audienceLabel, ENT_QUOTES) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-grid">
<select name="price_type[]" class="select">
<?php foreach (['free' => 'Frei', 'fixed' => 'Fester Preis', 'from' => 'Preis ab', 'up_to' => 'Preis bis', 'range' => 'Preisspanne', 'request' => 'Auf Anfrage'] as $typeValue => $typeLabel): ?>
<option value="<?= htmlspecialchars($typeValue, ENT_QUOTES) ?>" <?= (string)($priceRow['price_type'] ?? 'fixed') === $typeValue ? 'selected' : '' ?>><?= htmlspecialchars($typeLabel, ENT_QUOTES) ?></option>
<?php endforeach; ?>
</select>
<input name="price_amount[]" class="input" inputmode="decimal" placeholder="Preis" value="<?= htmlspecialchars((string)($priceRow['amount'] ?? ''), ENT_QUOTES) ?>">
</div>
<div class="form-grid">
<input name="price_amount_secondary[]" class="input" inputmode="decimal" placeholder="Zweiter Preis bei Spanne" value="<?= htmlspecialchars((string)($priceRow['amount_secondary'] ?? ''), ENT_QUOTES) ?>">
<input name="price_note[]" class="input" placeholder="Hinweis" value="<?= htmlspecialchars((string)($priceRow['note'] ?? ''), ENT_QUOTES) ?>">
</div>
<div class="form-grid">
<input name="price_age_from[]" class="input" type="number" min="0" max="99" placeholder="Alter von" value="">
<input name="price_age_to[]" class="input" type="number" min="0" max="99" placeholder="Alter bis" value="">
</div>
</div>
<div class="stack gap-6">
<label class="label" for="priceAdultAmount">Preis pro Erwachsener</label>
<input id="priceAdultAmount" name="price_adult_amount" class="input" inputmode="decimal" placeholder="z. B. 18,00" value="<?= htmlspecialchars($priceAdultAmount, ENT_QUOTES) ?>">
</div>
</div>
<div class="form-grid">
<div class="stack gap-6">
<label class="label" for="priceChildAgeFrom">Kind ab Alter</label>
<input id="priceChildAgeFrom" name="price_child_age_from" class="input" type="number" min="0" max="25" value="<?= htmlspecialchars($priceChildAgeFrom, ENT_QUOTES) ?>">
</div>
<div class="stack gap-6">
<label class="label" for="priceChildAgeTo">Kind bis Alter</label>
<input id="priceChildAgeTo" name="price_child_age_to" class="input" type="number" min="0" max="25" value="<?= htmlspecialchars($priceChildAgeTo, ENT_QUOTES) ?>">
</div>
</div>
<div class="stack gap-6">
<label class="label" for="priceAdultAgeFrom">Erwachsener ab Alter</label>
<input id="priceAdultAgeFrom" name="price_adult_age_from" class="input" type="number" min="0" max="25" value="<?= htmlspecialchars($priceAdultAgeFrom, ENT_QUOTES) ?>">
</div>
<?php endforeach; ?>
</div>
<div class="stack gap-6">
<label class="label" for="specialConditionsNote">Sonderkonditionen</label>
<textarea id="specialConditionsNote" name="special_conditions_note" class="textarea" rows="2" placeholder="z. B. Sonderkonditionen für Senioren oder Menschen mit Behinderung vorhanden"><?= htmlspecialchars($specialConditionsValue, ENT_QUOTES) ?></textarea>
</div>
</div>
<label class="label" id="eventKidsWrap" style="display:flex; align-items:center; gap:8px;">
<input type="checkbox" name="allow_kids" <?= $allowNoKidsChecked ? 'checked' : '' ?>> Event ohne Kinder
</label>
<div class="flex gap-12">
<button class="btn ghost" type="button" data-modal-close>Abbrechen</button>
<button class="btn" type="submit"><?= htmlspecialchars($submitLabel, ENT_QUOTES) ?></button>
@@ -1140,6 +1164,7 @@ if (!empty($canManageSystemSettings)) {
const btnMapSearch = document.getElementById('btnMapSearch');
const btnAddrToMap = document.getElementById('btnAddrToMap');
const btnEventAddressSearch = document.getElementById('btnEventAddressSearch');
const btnEventBrowserLocation = document.getElementById('btnEventBrowserLocation');
const eventAddressStatus = document.getElementById('eventAddressStatus');
const mapSearch = document.getElementById('mapSearch');
const latInput = document.getElementById('evLat');
@@ -1149,19 +1174,21 @@ if (!empty($canManageSystemSettings)) {
const entryKindButtons = document.querySelectorAll('[data-entry-kind-choice]');
const eventDateRow = document.getElementById('eventDateRow');
const eventLocationLabelWrap = document.getElementById('eventLocationLabelWrap');
const eventCategoryWrap = document.getElementById('eventCategoryWrap');
const eventKidsWrap = document.getElementById('eventKidsWrap');
const eventChildrenWrap = document.getElementById('eventChildrenWrap');
const eventCapacityWrap = document.getElementById('eventCapacityWrap');
const eventPricingWrap = document.getElementById('eventPricingWrap');
const placeContactWrap = document.getElementById('placeContactWrap');
const placeLookupWrap = document.getElementById('placeLookupWrap');
const placeOpeningHoursWrap = document.getElementById('placeOpeningHoursWrap');
const eventRecurrenceWrap = document.getElementById('eventRecurrenceWrap');
const eventDateInput = document.getElementById('evDate');
const categorySelect = document.getElementById('listingCategorySlug');
const priceModeSelect = document.getElementById('priceMode');
const freeChildRuleWrap = document.getElementById('freeChildRuleWrap');
const paidPricingWrap = document.getElementById('paidPricingWrap');
const recurrenceModeSelect = document.getElementById('recurrenceMode');
const recurrenceWeekdaysWrap = document.getElementById('recurrenceWeekdaysWrap');
const openingHoursRows = document.getElementById('openingHoursRows');
const priceRows = document.getElementById('priceRows');
const btnAddOpeningRow = document.getElementById('btnAddOpeningRow');
const btnAddPriceRow = document.getElementById('btnAddPriceRow');
const existingPlaceLookup = document.getElementById('existingPlaceLookup');
const btnUseExistingPlace = document.getElementById('btnUseExistingPlace');
const streetInput = document.getElementById('evStreet');
@@ -1225,23 +1252,17 @@ if (!empty($canManageSystemSettings)) {
if (eventDateRow) eventDateRow.hidden = kind === 'place';
if (eventDateInput) eventDateInput.required = kind !== 'place';
if (eventLocationLabelWrap) eventLocationLabelWrap.hidden = kind !== 'event';
if (eventCategoryWrap) eventCategoryWrap.hidden = kind === 'event';
if (categorySelect) categorySelect.required = kind !== 'event';
if (eventKidsWrap) eventKidsWrap.hidden = kind !== 'event';
if (categorySelect) categorySelect.required = true;
if (eventChildrenWrap) eventChildrenWrap.hidden = kind === 'place';
if (eventCapacityWrap) eventCapacityWrap.hidden = kind !== 'event';
if (eventPricingWrap) eventPricingWrap.hidden = kind === 'event';
if (placeLookupWrap) placeLookupWrap.hidden = kind === 'event';
if (placeOpeningHoursWrap) placeOpeningHoursWrap.hidden = kind !== 'place';
if (placeContactWrap) placeContactWrap.hidden = kind === 'event';
if (placeOpeningHoursWrap) placeOpeningHoursWrap.hidden = kind === 'event';
if (eventRecurrenceWrap) eventRecurrenceWrap.hidden = kind !== 'editorial_event';
syncPriceModeVisibility();
syncRecurrenceVisibility();
}
function syncPriceModeVisibility() {
const mode = priceModeSelect?.value || 'none';
if (freeChildRuleWrap) freeChildRuleWrap.hidden = mode !== 'free_child_rule';
if (paidPricingWrap) paidPricingWrap.hidden = mode !== 'paid';
}
function syncRecurrenceVisibility() {
const mode = recurrenceModeSelect?.value || 'single';
if (recurrenceWeekdaysWrap) recurrenceWeekdaysWrap.hidden = mode !== 'custom_weekdays';
@@ -1252,13 +1273,63 @@ if (!empty($canManageSystemSettings)) {
syncEventEntryKind(button.getAttribute('data-entry-kind-choice') || 'event');
});
});
priceModeSelect?.addEventListener('change', syncPriceModeVisibility);
recurrenceModeSelect?.addEventListener('change', syncRecurrenceVisibility);
syncEventEntryKind(entryKindInput?.value || 'event');
syncPriceModeVisibility();
syncRecurrenceVisibility();
function createOpeningRow() {
const row = document.createElement('div');
row.className = 'form-grid opening-row';
row.innerHTML = `
<input name="opening_day_label[]" class="input" placeholder="z. B. Montag oder täglich">
<input name="opening_time_from[]" class="input" type="time">
<input name="opening_time_to[]" class="input" type="time">
<input name="opening_note[]" class="input" placeholder="Hinweis">
`;
openingHoursRows?.appendChild(row);
}
function createPriceRow() {
const row = document.createElement('div');
row.className = 'stack gap-8 price-row card';
row.innerHTML = `
<div class="form-grid">
<input name="price_label[]" class="input" placeholder="z. B. Kinder 4-7">
<select name="price_audience[]" class="select">
<option value="general">Allgemein</option>
<option value="child">Kinder</option>
<option value="adult">Erwachsene</option>
<option value="family">Familie</option>
<option value="group">Gruppe</option>
</select>
</div>
<div class="form-grid">
<select name="price_type[]" class="select">
<option value="free">Frei</option>
<option value="fixed">Fester Preis</option>
<option value="from">Preis ab</option>
<option value="up_to">Preis bis</option>
<option value="range">Preisspanne</option>
<option value="request">Auf Anfrage</option>
</select>
<input name="price_amount[]" class="input" inputmode="decimal" placeholder="Preis">
</div>
<div class="form-grid">
<input name="price_amount_secondary[]" class="input" inputmode="decimal" placeholder="Zweiter Preis bei Spanne">
<input name="price_note[]" class="input" placeholder="Hinweis">
</div>
<div class="form-grid">
<input name="price_age_from[]" class="input" type="number" min="0" max="99" placeholder="Alter von">
<input name="price_age_to[]" class="input" type="number" min="0" max="99" placeholder="Alter bis">
</div>
`;
priceRows?.appendChild(row);
}
btnAddOpeningRow?.addEventListener('click', createOpeningRow);
btnAddPriceRow?.addEventListener('click', createPriceRow);
function applyExistingPlace(place) {
if (!place) return;
if (document.getElementById('evTitle') && !document.getElementById('evTitle').value.trim()) {
@@ -1490,6 +1561,34 @@ if (!empty($canManageSystemSettings)) {
});
});
btnEventBrowserLocation?.addEventListener('click', () => {
if (!window.PKTConsent || !window.PKTConsent.has('external_services')) {
alert('Für Browser-Standort und Adressübernahme bitte zuerst die externen Dienste in den Cookie-Einstellungen erlauben.');
window.PKTConsent?.openPreferences?.();
return;
}
if (!navigator.geolocation) {
alert('Dein Browser unterstützt keine Standortabfrage.');
return;
}
if (eventAddressStatus) eventAddressStatus.textContent = 'Browser-Standort wird abgerufen ...';
navigator.geolocation.getCurrentPosition((position) => {
reverseGeocodeProfileAddress(position.coords.latitude, position.coords.longitude, (data) => {
const normalized = normalizeGeoResult(data);
if (streetInput && normalized.street) streetInput.value = normalized.street;
if (zipInput && normalized.zip) zipInput.value = normalized.zip;
if (cityInput && normalized.city) cityInput.value = normalized.city;
if (regionInput) regionInput.value = normalized.region;
if (latInput) latInput.value = Number.isNaN(normalized.lat) ? '' : normalized.lat.toFixed(7);
if (lngInput) lngInput.value = Number.isNaN(normalized.lng) ? '' : normalized.lng.toFixed(7);
if (eventAddressStatus) eventAddressStatus.textContent = `Browser-Adresse übernommen: ${normalized.label || [normalized.street, `${normalized.zip} ${normalized.city}`.trim(), normalized.region].filter(Boolean).join(', ')}`;
});
}, () => {
if (eventAddressStatus) eventAddressStatus.textContent = '';
alert('Der Browser-Standort konnte nicht abgerufen werden.');
}, { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 });
});
(function(){
const setProfileStatus = (message = '') => {
if (!profileAddressStatus) return;