diff --git a/assets/platzhalter_brunch.jpeg b/assets/platzhalter_brunch.jpeg new file mode 100644 index 0000000..c9a120f Binary files /dev/null and b/assets/platzhalter_brunch.jpeg differ diff --git a/assets/platzhalter_dinner.jpeg b/assets/platzhalter_dinner.jpeg new file mode 100644 index 0000000..813100c Binary files /dev/null and b/assets/platzhalter_dinner.jpeg differ diff --git a/assets/platzhalter_kaffee.jpeg b/assets/platzhalter_kaffee.jpeg new file mode 100644 index 0000000..7f23df8 Binary files /dev/null and b/assets/platzhalter_kaffee.jpeg differ diff --git a/assets/platzhalter_lunch.jpeg b/assets/platzhalter_lunch.jpeg new file mode 100644 index 0000000..7b681c5 Binary files /dev/null and b/assets/platzhalter_lunch.jpeg differ diff --git a/css/event_overview.css b/css/event_overview.css index 5750bd1..432bbaa 100644 --- a/css/event_overview.css +++ b/css/event_overview.css @@ -445,6 +445,30 @@ grid-row: 1 / 3; } +.detail-gallery-large--single { + grid-template-columns: 1fr 1fr; + grid-template-rows: auto; + align-items: start; +} + +.detail-gallery-large--single .detail-gallery-item { + grid-column: 1 / -1; + grid-row: auto; + align-self: start; +} + +.detail-gallery-large--single .detail-gallery-image { + height: auto; + min-height: 0; + object-fit: contain; + object-position: top center; + background: var(--butter-light); +} + +.detail-gallery-large--single img:first-child { + grid-row: auto; +} + .detail-lightbox { /* Full-screen overlay for enlarged gallery image view. */ position: fixed; @@ -847,6 +871,11 @@ grid-row: auto; } + .detail-gallery-large--single { + grid-template-columns: 1fr; + grid-template-rows: auto; + } + .detail-lightbox { padding: 12px; } diff --git a/js/event_create.js b/js/event_create.js index 162ecfd..51028bc 100644 --- a/js/event_create.js +++ b/js/event_create.js @@ -425,6 +425,42 @@ function mapEventTypeToCategory(value) { return categoryMap[value] || value.toUpperCase(); } +/** + * Liefert je Eventtyp ein passendes Platzhalterbild. + */ +function getPlaceholderImageByEventType(eventType) { + const normalizedType = String(eventType || "") + .trim() + .toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/[+&/_-]/g, " ") + .replace(/\s+/g, " "); + + if (normalizedType.includes("brunch")) { + return "assets/platzhalter_brunch.jpeg"; + } + + if (normalizedType.includes("lunch")) { + return "assets/platzhalter_lunch.jpeg"; + } + + if ( + normalizedType.includes("kaffee") + || normalizedType.includes("coffee") + || normalizedType.includes("cafe") + || normalizedType.includes("kuchen") + ) { + return "assets/platzhalter_kaffee.jpeg"; + } + + if (normalizedType.includes("dinner")) { + return "assets/platzhalter_dinner.jpeg"; + } + + return "assets/platzhalter_dinner.jpeg"; +} + /** * Baut aus den Formulardaten ein lokal speicherbares Event-Objekt. */ @@ -436,6 +472,8 @@ function buildStoredEvent() { const eventDate = form.elements.eventDate.value; const eventTime = form.elements.eventTime.value; const eventCity = form.elements.eventCity.value.trim(); + const fallbackGallery = [getPlaceholderImageByEventType(eventType)]; + const resolvedGallery = galleryImages.length > 0 ? [...galleryImages] : fallbackGallery; return { id: Date.now(), @@ -444,6 +482,7 @@ function buildStoredEvent() { address: form.elements.eventAddress.value.trim(), date: formatDateForStorage(eventDate), time: formatTimeForStorage(eventTime), + eventType, category: mapEventTypeToCategory(eventType), diet: dietType, spots: Number(form.elements.maxGuests.value), @@ -460,7 +499,7 @@ function buildStoredEvent() { allergiesNote: form.elements.allergiesOther.value.trim(), // Host wird separat geführt und nicht als angemeldeter Gast gezählt. participants: [], - gallery: [...galleryImages], + gallery: resolvedGallery, createdAt: new Date().toISOString(), source: "local" }; diff --git a/js/event_detail.js b/js/event_detail.js index a2ec1c1..cc68c87 100644 --- a/js/event_detail.js +++ b/js/event_detail.js @@ -198,6 +198,39 @@ return labels[diet] || diet; } + function getPlaceholderImageByEventType(event) { + const rawType = String(event?.eventType || event?.category || '') + .trim() + .toLowerCase() + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .replace(/[+&/_-]/g, ' ') + .replace(/\s+/g, ' '); + + if (rawType.includes('brunch')) { + return 'assets/platzhalter_brunch.jpeg'; + } + + if (rawType.includes('lunch')) { + return 'assets/platzhalter_lunch.jpeg'; + } + + if ( + rawType.includes('kaffee') + || rawType.includes('coffee') + || rawType.includes('cafe') + || rawType.includes('kuchen') + ) { + return 'assets/platzhalter_kaffee.jpeg'; + } + + if (rawType.includes('dinner')) { + return 'assets/platzhalter_dinner.jpeg'; + } + + return 'assets/platzhalter_dinner.jpeg'; + } + // Fetch data source and resolve the matching event record. try { const response = await fetch('data/events.json'); @@ -234,9 +267,15 @@ .map(name => getParticipantNameForViewer(name, isOwnEvent)) .filter(Boolean); const galleryImages = Array.isArray(event.gallery) ? event.gallery.filter(Boolean) : []; - const galleryMarkup = galleryImages.length > 0 - ? `