|
|
|
|
@@ -921,6 +921,9 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
<div class="card" id="entryKindQuickGuide">
|
|
|
|
|
<p class="muted small" style="margin:0;">Trage zuerst nur die wichtigsten Angaben ein. Alles Weitere ist optional und unten einklappbar.</p>
|
|
|
|
|
</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) ?>">
|
|
|
|
|
@@ -947,20 +950,16 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
<input id="categoryCustomTitle" name="category_custom_title" class="input" placeholder="z. B. Tierpark">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stack gap-6" id="placeLookupWrap">
|
|
|
|
|
<details id="placeLookupWrap" class="card">
|
|
|
|
|
<summary style="cursor:pointer; font-weight:600;">Vorhandenen Ort übernehmen</summary>
|
|
|
|
|
<div class="stack gap-6" style="margin-top:12px;">
|
|
|
|
|
<label class="label" for="existingPlaceLookup">Vorhandenen Ort suchen (optional)</label>
|
|
|
|
|
<div class="flex gap-8" style="flex-wrap:wrap;">
|
|
|
|
|
<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>
|
|
|
|
|
</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>
|
|
|
|
|
</details>
|
|
|
|
|
<div class="form-grid" id="eventDateRow">
|
|
|
|
|
<div class="stack gap-6">
|
|
|
|
|
<label class="label" for="evDate">Start / Termin</label>
|
|
|
|
|
@@ -1030,14 +1029,36 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
<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">
|
|
|
|
|
<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="flex gap-8" style="flex-wrap:wrap; align-items:center;">
|
|
|
|
|
<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 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>
|
|
|
|
|
<div id="mapContainer" class="map-container"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</details>
|
|
|
|
|
<details class="card" id="placeContactWrap">
|
|
|
|
|
<summary style="cursor:pointer; font-weight:600;">Kontaktangaben</summary>
|
|
|
|
|
<div class="form-grid" style="margin-top:12px;">
|
|
|
|
|
<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) ?>">
|
|
|
|
|
@@ -1047,8 +1068,10 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
<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">
|
|
|
|
|
</details>
|
|
|
|
|
<details class="card" id="placeOpeningHoursWrap">
|
|
|
|
|
<summary style="cursor:pointer; font-weight:600;">Öffnungszeiten / Zeitfenster</summary>
|
|
|
|
|
<div class="stack gap-6" style="margin-top:12px;">
|
|
|
|
|
<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>
|
|
|
|
|
@@ -1065,21 +1088,10 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
</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>
|
|
|
|
|
<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>
|
|
|
|
|
<div id="mapContainer" class="map-container"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="form-grid">
|
|
|
|
|
</details>
|
|
|
|
|
<details class="card" id="visibilityDetails">
|
|
|
|
|
<summary style="cursor:pointer; font-weight:600;">Weitere Optionen</summary>
|
|
|
|
|
<div class="form-grid" style="margin-top:12px;">
|
|
|
|
|
<div class="stack gap-6">
|
|
|
|
|
<label class="label" for="evVis">Sichtbarkeit</label>
|
|
|
|
|
<select id="evVis" name="visibility" class="select">
|
|
|
|
|
@@ -1088,9 +1100,22 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stack gap-10" id="eventPricingWrap">
|
|
|
|
|
</details>
|
|
|
|
|
<details class="card">
|
|
|
|
|
<summary style="cursor:pointer; font-weight:600;">Bild hinzufügen</summary>
|
|
|
|
|
<div class="stack gap-6" style="margin-top:12px;">
|
|
|
|
|
<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>
|
|
|
|
|
</details>
|
|
|
|
|
<details class="card" id="eventPricingWrap">
|
|
|
|
|
<summary style="cursor:pointer; font-weight:600;">Eintritt / Kosten</summary>
|
|
|
|
|
<div class="stack gap-10" style="margin-top:12px;">
|
|
|
|
|
<div class="flex between center-y">
|
|
|
|
|
<label class="label">Eintritt / Kosten</label>
|
|
|
|
|
<label class="label">Preisregeln</label>
|
|
|
|
|
<button class="btn ghost" type="button" id="btnAddPriceRow">Preisregel hinzufügen</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div id="priceRows" class="stack gap-8">
|
|
|
|
|
@@ -1128,6 +1153,7 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
<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>
|
|
|
|
|
</details>
|
|
|
|
|
<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>
|
|
|
|
|
@@ -1229,6 +1255,15 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setSectionState(element, visible) {
|
|
|
|
|
if (!element) return;
|
|
|
|
|
element.hidden = !visible;
|
|
|
|
|
element.querySelectorAll('input, select, textarea, button').forEach((field) => {
|
|
|
|
|
if (field.type === 'hidden') return;
|
|
|
|
|
field.disabled = !visible;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function syncEventEntryKind(nextKind) {
|
|
|
|
|
const kind = nextKind || entryKindInput?.value || 'event';
|
|
|
|
|
if (entryKindInput) entryKindInput.value = kind;
|
|
|
|
|
@@ -1249,17 +1284,17 @@ if (!empty($canManageSystemSettings)) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (eventDateRow) eventDateRow.hidden = kind === 'place';
|
|
|
|
|
setSectionState(eventDateRow, kind !== 'place');
|
|
|
|
|
if (eventDateInput) eventDateInput.required = kind !== 'place';
|
|
|
|
|
if (eventLocationLabelWrap) eventLocationLabelWrap.hidden = kind !== 'event';
|
|
|
|
|
setSectionState(eventLocationLabelWrap, 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 (placeContactWrap) placeContactWrap.hidden = kind === 'event';
|
|
|
|
|
if (placeOpeningHoursWrap) placeOpeningHoursWrap.hidden = kind === 'event';
|
|
|
|
|
if (eventRecurrenceWrap) eventRecurrenceWrap.hidden = kind !== 'editorial_event';
|
|
|
|
|
setSectionState(eventChildrenWrap, kind === 'event' || kind === 'editorial_event');
|
|
|
|
|
setSectionState(eventCapacityWrap, kind === 'event');
|
|
|
|
|
setSectionState(eventPricingWrap, kind === 'place' || kind === 'editorial_event');
|
|
|
|
|
setSectionState(placeLookupWrap, kind === 'place' || kind === 'editorial_event');
|
|
|
|
|
setSectionState(placeContactWrap, kind === 'place' || kind === 'editorial_event');
|
|
|
|
|
setSectionState(placeOpeningHoursWrap, kind === 'place' || kind === 'editorial_event');
|
|
|
|
|
setSectionState(eventRecurrenceWrap, kind === 'editorial_event');
|
|
|
|
|
syncRecurrenceVisibility();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|