feat: lightbox gallery, event create UX improvements, cancel modal, footer consistency, Swiss German fixes

This commit is contained in:
Estelle Köhler 2026-04-12 15:18:40 +02:00
parent 4b54c48311
commit e805abbf12
16 changed files with 307 additions and 77 deletions

View File

@ -187,6 +187,7 @@ h2 {
font-size: clamp(2rem, 4vw, 4rem); font-size: clamp(2rem, 4vw, 4rem);
line-height: 1.03; line-height: 1.03;
letter-spacing: -0.03em; letter-spacing: -0.03em;
color: var(--brown);
} }
.step-text { .step-text {
@ -204,7 +205,6 @@ h2 {
} }
.intro-card { .intro-card {
max-width: 24rem;
padding: var(--space-6); padding: var(--space-6);
border-radius: 1.75rem; border-radius: 1.75rem;
background: linear-gradient(135deg, var(--color-surface), var(--color-surface-soft)); background: linear-gradient(135deg, var(--color-surface), var(--color-surface-soft));
@ -221,7 +221,7 @@ h2 {
.intro-image { .intro-image {
width: 100%; width: 100%;
aspect-ratio: 16 / 10; height: 100%;
display: block; display: block;
object-fit: cover; object-fit: cover;
border-radius: 1.875rem; border-radius: 1.875rem;
@ -457,57 +457,36 @@ textarea:focus {
} }
.progress-wrap { .progress-wrap {
position: relative;
width: min(100%, var(--content-width)); width: min(100%, var(--content-width));
margin: 0 auto; margin: 0 auto;
padding-top: 4.35rem; display: flex;
align-items: center;
gap: 0.75rem;
}
.progress-label {
flex-shrink: 0;
font-size: 0.8rem;
font-weight: 600;
color: var(--color-muted);
white-space: nowrap;
} }
.progress { .progress {
width: 100%; flex: 1;
height: 0.375rem; height: 0.3rem;
background: var(--color-progress-bg); background: var(--color-progress-bg);
border-radius: 999px;
overflow: hidden;
} }
.progress-bar { .progress-bar {
display: block; display: block;
width: 0; width: 0;
height: 100%; height: 100%;
background: var(--tomato); background: var(--olive);
transition: width 0.25s ease;
}
.progress-marker {
position: absolute;
top: 0;
transform: translateX(-50%);
display: grid;
justify-items: center;
gap: 0.2rem;
pointer-events: none;
}
.progress-marker::after {
content: "";
width: 0.125rem;
height: 1rem;
background: var(--tomato);
border-radius: 999px; border-radius: 999px;
} transition: width 0.25s ease;
.progress-marker__circle {
width: 2.9rem;
height: 2.9rem;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: var(--tomato);
color: var(--butter-light);
font-size: 1.35rem;
font-weight: 600;
line-height: 1;
box-shadow: 0 10px 24px rgba(212, 75, 36, 0.18);
} }
.flow-actions { .flow-actions {
@ -550,8 +529,15 @@ textarea:focus {
} }
.button--text { .button--text {
border: 0; border: 2px solid var(--olive);
padding-left: 0; color: var(--olive);
background: transparent;
padding-left: 1.35rem;
}
.button--text:hover {
background: var(--olive-light);
color: var(--black);
} }
.button--primary { .button--primary {
@ -625,7 +611,7 @@ textarea:focus-visible {
.step-layout--intro { .step-layout--intro {
width: min(100%, 56rem); width: min(100%, 56rem);
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
align-items: center; align-items: stretch;
gap: var(--space-8); gap: var(--space-8);
} }

View File

@ -492,6 +492,7 @@
color: var(--white); color: var(--white);
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center;
font-size: 13px; font-size: 13px;
} }
@ -668,6 +669,40 @@
opacity: 0.7; opacity: 0.7;
} }
.detail-participants-full {
display: flex;
flex-direction: column;
gap: 10px;
}
.detail-participant-item {
display: flex;
align-items: center;
gap: 10px;
}
.participant-name {
font-size: 0.95rem;
font-weight: 500;
color: var(--black);
}
.detail-participants-link {
background: none;
border: none;
color: var(--olive);
font-size: 0.85rem;
font-weight: 600;
cursor: pointer;
padding: 0;
text-decoration: underline;
text-underline-offset: 3px;
}
.detail-participants-link:hover {
color: var(--olive-dark);
}
.detail-action-bar { .detail-action-bar {
/* Sticky bottom CTA bar with summary and booking controls. */ /* Sticky bottom CTA bar with summary and booking controls. */
display: flex; display: flex;
@ -733,8 +768,8 @@
.detail-spots-pill { .detail-spots-pill {
border: 2px solid var(--olive-light); border: 2px solid var(--olive-light);
border-radius: var(--radius-pill); border-radius: var(--radius-pill);
opacity: 0.5;
font-size: 14px; font-size: 14px;
font-weight: 500;
letter-spacing: var(--ls-ui); letter-spacing: var(--ls-ui);
padding: 7px 14px; padding: 7px 14px;
color: var(--olive); color: var(--olive);

View File

@ -247,6 +247,7 @@
background: var(--white); background: var(--white);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.06); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.06);
aspect-ratio: 2 / 3; aspect-ratio: 2 / 3;
cursor: pointer;
} }
.gallery__item img { .gallery__item img {

View File

@ -435,6 +435,56 @@ p {
background: var(--tomato); background: var(--tomato);
} }
/* Lightbox */
.lightbox {
position: fixed;
inset: 0;
z-index: 200;
display: none;
align-items: center;
justify-content: center;
padding: 24px;
}
.lightbox.is-open {
display: flex;
}
.lightbox__backdrop {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.75);
}
.lightbox__content {
position: relative;
margin: 0;
max-width: min(96vw, 1100px);
max-height: 90vh;
z-index: 1;
}
.lightbox__image {
display: block;
width: 100%;
max-height: 90vh;
object-fit: contain;
border-radius: 16px;
background: #111;
}
.lightbox__close {
position: absolute;
top: -42px;
right: 0;
border: 0;
background: transparent;
color: var(--white);
font-size: 40px;
line-height: 1;
cursor: pointer;
}
/* Footer */ /* Footer */
.footer { .footer {
display: flex; display: flex;

View File

@ -57,7 +57,7 @@
"hostMessage": [ "hostMessage": [
"¡Hola a todos! Ich lade euch ein auf eine kulinarische Reise nach Peru.", "¡Hola a todos! Ich lade euch ein auf eine kulinarische Reise nach Peru.",
"Ich koche für euch ein authentisches peruanisches Sharing-Menü, das vor Lebensfreude nur so sprüht. Freut euch auf eine Explosion aus leuchtenden Farben, fein abgestimmter Schärfe und der unverwechselbaren Frische verschiedenster Kräuter.", "Ich koche für euch ein authentisches peruanisches Sharing-Menü, das vor Lebensfreude nur so sprüht. Freut euch auf eine Explosion aus leuchtenden Farben, fein abgestimmter Schärfe und der unverwechselbaren Frische verschiedenster Kräuter.",
"Wir genießen den Abend gemeinsam in mehreren kleinen Gängen, ganz nach dem Sharing-Prinzip. Dabei entdecken wir die klassischen Aromen meiner Heimatstadt Lima von traditionell bis modern interpretiert.", "Wir geniessen den Abend gemeinsam in mehreren kleinen Gängen, ganz nach dem Sharing-Prinzip. Dabei entdecken wir die klassischen Aromen meiner Heimatstadt Lima von traditionell bis modern interpretiert.",
"Es wird gesellig, aromatisch und ein echtes Erlebnis für alle Sinne. ¡Buen provecho!" "Es wird gesellig, aromatisch und ein echtes Erlebnis für alle Sinne. ¡Buen provecho!"
], ],
"menu": [ "menu": [

View File

@ -41,8 +41,8 @@
<p class="step-kicker">Event erstellen</p> <p class="step-kicker">Event erstellen</p>
<h1 id="intro-title">Hey <span id="username">{{username}}</span>, was hast du vor?</h1> <h1 id="intro-title">Hey <span id="username">{{username}}</span>, was hast du vor?</h1>
<p class="step-text"> <p class="step-text">
Erzähl uns von deiner Idee vom Essen bis zur Stimmung. Ob Dinner, Brunch Erzähl uns von deiner Idee, vom Essen bis zur Stimmung. Ob Dinner, Brunch
oder etwas ganz Eigenes wir helfen dir dabei, dein Event in sieben Schritten aufzubauen. oder etwas ganz Eigenes wir helfen dir dabei, dein Event in sieben Schritten aufzubauen.
</p> </p>
<button type="button" class="button button--primary button--intro" data-start-flow> <button type="button" class="button button--primary button--intro" data-start-flow>
Los gehts! Los gehts!
@ -66,7 +66,7 @@
<h2 id="step1-title">Was hast du vor?</h2> <h2 id="step1-title">Was hast du vor?</h2>
<p class="step-text"> <p class="step-text">
Erzähl uns, was für ein Event du planst. Ist es ein gemütlicher Brunch, Erzähl uns, was für ein Event du planst. Ist es ein gemütlicher Brunch,
ein Dinner mit Wow-Effekt oder einfach ein entspannter Abend mit gutem Essen? ein Dinner mit Wow-Effekt oder einfach ein entspanntes Mittagessen mit gutem Essen?
</p> </p>
</div> </div>
@ -277,12 +277,12 @@
<div class="step-fields"> <div class="step-fields">
<div class="form-field"> <div class="form-field">
<label for="eventTitle">Wie soll dein Event heißen?</label> <label for="eventTitle">Wie soll dein Event heissen?</label>
<input type="text" id="eventTitle" name="eventTitle" required /> <input type="text" id="eventTitle" name="eventTitle" required />
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="eventDescription">Beschreibung des Event-Abends</label> <label for="eventDescription">Beschreibung des Events</label>
<textarea id="eventDescription" name="eventDescription" rows="6" required></textarea> <textarea id="eventDescription" name="eventDescription" rows="6" required></textarea>
</div> </div>
</div> </div>
@ -363,9 +363,7 @@
<div class="flow-footer" id="flowFooter" hidden> <div class="flow-footer" id="flowFooter" hidden>
<div class="progress-wrap" aria-hidden="true"> <div class="progress-wrap" aria-hidden="true">
<div class="progress-marker" id="progressMarker"> <span class="progress-label" id="progressMarkerLabel">Schritt 1 von 7</span>
<span class="progress-marker__circle" id="progressMarkerLabel">1</span>
</div>
<div class="progress"> <div class="progress">
<span id="progressBar" class="progress-bar"></span> <span id="progressBar" class="progress-bar"></span>
</div> </div>
@ -400,7 +398,7 @@
<div class="review-card review-card--success"> <div class="review-card review-card--success">
<div class="submission-success-actions"> <div class="submission-success-actions">
<a class="button button--primary" href="event_overview.html">Weiter zu deinem Profil</a> <a class="button button--primary" href="my_profil.html">Weiter zu deinem Profil</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -35,6 +35,11 @@
<!-- Page logic: fetch by URL id, compose detail UI, handle gallery lightbox --> <!-- Page logic: fetch by URL id, compose detail UI, handle gallery lightbox -->
<script src="js/event_detail.js"></script> <script src="js/event_detail.js"></script>
<!-- Snackbar: Feedback bei An-/Abmeldung -->
<div class="snackbar" id="snackbar"></div>
<!-- Instagram Einladung -->
<div class="instagram-invite"> <div class="instagram-invite">
<a href="https://www.instagram.com" target="_blank" rel="noopener noreferrer" class="instagram-invite__link"> <a href="https://www.instagram.com" target="_blank" rel="noopener noreferrer" class="instagram-invite__link">
<img src="assets/Icon_instagram.png" alt="Instagram" class="instagram-invite__icon" /> <img src="assets/Icon_instagram.png" alt="Instagram" class="instagram-invite__icon" />

View File

@ -148,6 +148,15 @@
</section> </section>
</main> </main>
<!-- Lightbox: Bildansicht vergrössert -->
<div class="lightbox" id="gallery-lightbox" aria-hidden="true">
<div class="lightbox__backdrop" data-close-lightbox></div>
<figure class="lightbox__content" role="dialog" aria-modal="true" aria-label="Bildansicht">
<button class="lightbox__close" type="button" aria-label="Schliessen">&times;</button>
<img class="lightbox__image" src="" alt="Grossansicht">
</figure>
</div>
<script src="js/index-carousel.js"></script> <script src="js/index-carousel.js"></script>
<footer class="footer"> <footer class="footer">
<a href="impressum.html" class="footer__link">Impressum</a> <a href="impressum.html" class="footer__link">Impressum</a>

View File

@ -8,7 +8,6 @@ const steps = Array.from(document.querySelectorAll(".step"));
const backButton = document.getElementById("backButton"); const backButton = document.getElementById("backButton");
const nextButton = document.getElementById("nextButton"); const nextButton = document.getElementById("nextButton");
const progressBar = document.getElementById("progressBar"); const progressBar = document.getElementById("progressBar");
const progressMarker = document.getElementById("progressMarker");
const progressMarkerLabel = document.getElementById("progressMarkerLabel"); const progressMarkerLabel = document.getElementById("progressMarkerLabel");
const errorMessage = document.getElementById("errorMessage"); const errorMessage = document.getElementById("errorMessage");
const usernameElement = document.getElementById("username"); const usernameElement = document.getElementById("username");
@ -121,7 +120,7 @@ function markRadioGroupInvalid(group) {
* Zeigt den gewünschten Schritt an. * Zeigt den gewünschten Schritt an.
* Dabei werden auch Buttons, Progress Bar und Review aktualisiert. * Dabei werden auch Buttons, Progress Bar und Review aktualisiert.
*/ */
function showStep(index) { function showStep(index, pushHistory = true) {
currentStep = index; currentStep = index;
submissionSuccess.hidden = true; submissionSuccess.hidden = true;
clearStepInvalidState(index); clearStepInvalidState(index);
@ -136,6 +135,11 @@ function showStep(index) {
updateProgressBar(index, lastStep); updateProgressBar(index, lastStep);
setErrorMessage(""); setErrorMessage("");
// Browser-History aktualisieren, damit Zurück-Taste funktioniert
if (pushHistory) {
history.pushState({ step: index }, "");
}
// Für bessere UX: bei jedem Schritt wieder nach oben scrollen // Für bessere UX: bei jedem Schritt wieder nach oben scrollen
window.scrollTo({ top: 0, behavior: "smooth" }); window.scrollTo({ top: 0, behavior: "smooth" });
} }
@ -168,22 +172,17 @@ function updateFlowVisibility(stepIndex) {
* - letzter Schritt = 100% * - letzter Schritt = 100%
*/ */
function updateProgressBar(stepIndex, totalStepIndex) { function updateProgressBar(stepIndex, totalStepIndex) {
const totalFormSteps = totalStepIndex;
let progress = 0; let progress = 0;
let markerPosition = 0;
let markerStep = 1; let markerStep = 1;
let markerTransform = "translateX(-50%)";
if (stepIndex > 0) { if (stepIndex > 0) {
progress = ((stepIndex - 1) / (totalStepIndex - 1)) * 100; progress = ((stepIndex) / totalFormSteps) * 100;
markerPosition = ((stepIndex - 1) / (totalStepIndex - 1)) * 100;
markerStep = stepIndex; markerStep = stepIndex;
} }
progressBar.style.width = `${progress}%`; progressBar.style.width = `${progress}%`;
progressMarker.style.left = `${markerPosition}%`; progressMarkerLabel.textContent = `Schritt ${markerStep} von ${totalFormSteps}`;
progressMarker.style.transform = markerTransform;
progressMarker.hidden = stepIndex === 0;
progressMarkerLabel.textContent = String(markerStep);
} }
@ -767,9 +766,21 @@ function initEventCreationFlow() {
registerValidationFeedbackHandlers(); registerValidationFeedbackHandlers();
registerReviewEditHandlers(); registerReviewEditHandlers();
// Browser-Zurück-Taste: vorherigen Schritt wiederherstellen
window.addEventListener("popstate", (e) => {
if (e.state && typeof e.state.step === "number") {
showStep(e.state.step, false);
} else {
showStep(0, false);
}
});
// Startzustand: Intro anzeigen // Startzustand: Intro anzeigen
submissionSuccess.hidden = true; submissionSuccess.hidden = true;
showStep(0); showStep(0);
// Initialen History-Eintrag ersetzen, damit Step 0 im Verlauf ist
history.replaceState({ step: 0 }, "");
} }
// Startpunkt des Skripts // Startpunkt des Skripts

View File

@ -6,7 +6,7 @@ document.addEventListener('DOMContentLoaded', async () => {
// DOM entry point and shared asset path. // DOM entry point and shared asset path.
// ------------------------------------------------------------- // -------------------------------------------------------------
const detailContainer = document.getElementById('detail-view'); const detailContainer = document.getElementById('detail-view');
const locationIconPath = 'assets/location-pin.svg'; const locationIconPath = 'assets/icon_location-pin.svg';
const currentUser = getCurrentUser(); const currentUser = getCurrentUser();
// Read event id from query string (detail page deep-link support). // Read event id from query string (detail page deep-link support).
@ -358,12 +358,20 @@ document.addEventListener('DOMContentLoaded', async () => {
<article class="detail-panel detail-panel-compact"> <article class="detail-panel detail-panel-compact">
<div class="detail-participants-head"> <div class="detail-participants-head">
<h2 class="detail-section-title">Teilnehmer</h2> <h2 class="detail-section-title">Teilnehmer</h2>
<a href="#" class="detail-participants-link">Alle ansehen</a> <button type="button" class="detail-participants-link" data-show-all-participants>Alle ansehen</button>
</div> </div>
<div class="detail-avatar-row"> <div class="detail-avatar-row" data-participants-row>
${visibleParticipants.map(name => `<span class="participant-avatar">${name.charAt(0).toUpperCase()}</span>`).join('')} ${visibleParticipants.map(name => `<span class="participant-avatar">${name.charAt(0).toUpperCase()}</span>`).join('')}
${remainingParticipants > 0 ? `<span class="participant-more">+${remainingParticipants}</span>` : ''} ${remainingParticipants > 0 ? `<span class="participant-more">+${remainingParticipants}</span>` : ''}
</div> </div>
<div class="detail-participants-full hidden" data-participants-full>
${participants.map(name => `
<div class="detail-participant-item">
<span class="participant-avatar">${name.charAt(0).toUpperCase()}</span>
<span class="participant-name">${name}</span>
</div>
`).join('')}
</div>
</article> </article>
${addressPanelMarkup} ${addressPanelMarkup}
@ -392,7 +400,7 @@ document.addEventListener('DOMContentLoaded', async () => {
<div class="detail-action-buttons"> <div class="detail-action-buttons">
<span class="detail-spots-pill${isFull ? ' detail-spots-pill-full' : ''}"> <span class="detail-spots-pill${isFull ? ' detail-spots-pill-full' : ''}">
${isFull ? 'AUSGEBUCHT' : `${freePlaces} Plaetze frei`} ${isFull ? 'AUSGEBUCHT' : `${freePlaces} Plätze frei`}
</span> </span>
<button class="detail-primary-btn${actionButtonVariantClass}" type="button" data-register-button ${actionButtonDisabled ? 'disabled' : ''}> <button class="detail-primary-btn${actionButtonVariantClass}" type="button" data-register-button ${actionButtonDisabled ? 'disabled' : ''}>
${actionButtonLabel} ${actionButtonLabel}
@ -447,8 +455,27 @@ document.addEventListener('DOMContentLoaded', async () => {
if (registrationSet.has(Number(event.id))) { if (registrationSet.has(Number(event.id))) {
registrationSet.delete(Number(event.id)); registrationSet.delete(Number(event.id));
// Snackbar: Feedback bei Abmeldung.
const snackbar = document.getElementById('snackbar');
if (snackbar) {
snackbar.textContent = 'Du wurdest erfolgreich abgemeldet.';
snackbar.classList.add('snackbar--danger', 'snackbar--visible');
setTimeout(() => {
snackbar.classList.remove('snackbar--visible');
setTimeout(() => snackbar.classList.remove('snackbar--danger'), 400);
}, 3000);
}
} else if (!isFull && !isRegistrationClosed) { } else if (!isFull && !isRegistrationClosed) {
registrationSet.add(Number(event.id)); registrationSet.add(Number(event.id));
// Snackbar: Feedback bei Anmeldung.
const snackbar = document.getElementById('snackbar');
if (snackbar) {
snackbar.textContent = 'Du wurdest erfolgreich angemeldet.';
snackbar.classList.add('snackbar--visible');
setTimeout(() => snackbar.classList.remove('snackbar--visible'), 3000);
}
} }
nextRegistrationMap[currentUser.email] = Array.from(registrationSet); nextRegistrationMap[currentUser.email] = Array.from(registrationSet);
@ -459,6 +486,20 @@ document.addEventListener('DOMContentLoaded', async () => {
}); });
} }
// "Alle ansehen": Teilnehmerliste aufklappen / zuklappen.
const showAllBtn = detailContainer.querySelector('[data-show-all-participants]');
const avatarRow = detailContainer.querySelector('[data-participants-row]');
const fullList = detailContainer.querySelector('[data-participants-full]');
if (showAllBtn && avatarRow && fullList) {
showAllBtn.addEventListener('click', () => {
const isExpanded = !fullList.classList.contains('hidden');
fullList.classList.toggle('hidden');
avatarRow.classList.toggle('hidden');
showAllBtn.textContent = isExpanded ? 'Alle ansehen' : 'Weniger anzeigen';
});
}
// Central close helper to keep all close paths consistent. // Central close helper to keep all close paths consistent.
function closeLightbox() { function closeLightbox() {
if (!lightbox) { if (!lightbox) {

View File

@ -294,11 +294,6 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
const filtered = allEvents.filter(event => { const filtered = allEvents.filter(event => {
// Lokal erstellte Events werden nicht in der allgemeinen Event-Uebersicht angezeigt.
if (event.source === 'local') {
return false;
}
const categoryMatch = activeCategory === 'ALLE' || event.category === activeCategory; const categoryMatch = activeCategory === 'ALLE' || event.category === activeCategory;
const locationMatch = selectedLocation === 'ALLE_ORTE' || event.location === selectedLocation; const locationMatch = selectedLocation === 'ALLE_ORTE' || event.location === selectedLocation;
const eventDateIso = parseEventDateToIso(event.date); const eventDateIso = parseEventDateToIso(event.date);

View File

@ -97,4 +97,47 @@ if (carouselTrack) {
buildDots(); buildDots();
updateTrack(); updateTrack();
}); });
// =============================================
// Lightbox: Bild vergroessern bei Klick
// =============================================
const lightbox = document.getElementById('gallery-lightbox');
const lightboxImage = lightbox ? lightbox.querySelector('.lightbox__image') : null;
function openLightbox(src, alt) {
if (!lightbox || !lightboxImage) return;
lightboxImage.src = src;
lightboxImage.alt = alt || 'Grossansicht';
lightbox.classList.add('is-open');
lightbox.setAttribute('aria-hidden', 'false');
}
function closeLightbox() {
if (!lightbox) return;
lightbox.classList.remove('is-open');
lightbox.setAttribute('aria-hidden', 'true');
lightboxImage.src = '';
}
// Klick auf Galerie-Bild oeffnet die Lightbox.
items.forEach(function(item) {
var img = item.querySelector('img');
if (img) {
item.addEventListener('click', function() {
openLightbox(img.src, img.alt);
});
}
});
// Lightbox schliessen: Backdrop, Close-Button oder ESC-Taste.
if (lightbox) {
lightbox.querySelector('.lightbox__close').addEventListener('click', closeLightbox);
lightbox.querySelector('[data-close-lightbox]').addEventListener('click', closeLightbox);
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && lightbox.classList.contains('is-open')) {
closeLightbox();
}
});
}
} }

View File

@ -177,7 +177,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (cancelButton && currentUser?.email) { if (cancelButton && currentUser?.email) {
const eventId = Number(cancelButton.getAttribute('data-cancel-event-id')); const eventId = Number(cancelButton.getAttribute('data-cancel-event-id'));
if (Number.isFinite(eventId)) { if (Number.isFinite(eventId)) {
cancelHostedEvent(eventId, currentUser.email); openCancelEventModal(eventId);
} }
return; return;
} }
@ -265,6 +265,34 @@ document.addEventListener('DOMContentLoaded', () => {
// Sagt ein gehostetes Event ab (aus eigener Profilansicht entfernen). // Sagt ein gehostetes Event ab (aus eigener Profilansicht entfernen).
let pendingCancelEventId = null;
function openCancelEventModal(eventId) {
pendingCancelEventId = eventId;
const modal = document.getElementById('cancelEventModal');
modal.classList.add('show');
}
window.closeCancelEventModal = function() {
pendingCancelEventId = null;
const modal = document.getElementById('cancelEventModal');
modal.classList.remove('show');
};
document.getElementById('confirmCancelEventBtn').addEventListener('click', function() {
if (pendingCancelEventId !== null && currentUser?.email) {
cancelHostedEvent(pendingCancelEventId, currentUser.email);
}
closeCancelEventModal();
});
// Schliesst das Modal bei Klick ausserhalb des Inhalts.
document.getElementById('cancelEventModal').addEventListener('click', function(e) {
if (e.target === this) {
closeCancelEventModal();
}
});
function cancelHostedEvent(eventId, userEmail) { function cancelHostedEvent(eventId, userEmail) {
// Lokal erstellte, eigene Events werden direkt aus dem Storage geloescht. // Lokal erstellte, eigene Events werden direkt aus dem Storage geloescht.
const storedEvents = getStoredEvents(); const storedEvents = getStoredEvents();

View File

@ -42,7 +42,7 @@ function openWelcomeModal() {
document.body.style.overflow = 'hidden'; document.body.style.overflow = 'hidden';
} }
// Funktion zum Schließen des Welcome Modals // Funktion zum Schliessen des Welcome Modals
function closeWelcomeModal() { function closeWelcomeModal() {
welcomeModal.classList.remove('show'); welcomeModal.classList.remove('show');
document.body.style.overflow = 'auto'; document.body.style.overflow = 'auto';
@ -172,7 +172,7 @@ passwortInput.addEventListener('input', function() {
} }
}); });
// Modal schließen wenn außerhalb geklickt wird // Modal schliessen wenn ausserhalb geklickt wird
welcomeModal.addEventListener('click', function(event) { welcomeModal.addEventListener('click', function(event) {
if (event.target === welcomeModal) { if (event.target === welcomeModal) {
closeWelcomeModal(); closeWelcomeModal();

View File

@ -123,6 +123,34 @@
<!-- Snackbar: Feedback bei Abmeldung von Events --> <!-- Snackbar: Feedback bei Abmeldung von Events -->
<div class="snackbar" id="snackbar"></div> <div class="snackbar" id="snackbar"></div>
<!-- Event-Absage Confirmation Modal -->
<div id="cancelEventModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<button class="close-btn" onclick="closeCancelEventModal()">&times;</button>
<h2>Event absagen?</h2>
</div>
<div class="modal-body">
Bist du sicher, dass du dieses Event absagen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.
</div>
<div class="modal-footer">
<button class="button button--outline" type="button" onclick="closeCancelEventModal()">Abbrechen</button>
<button class="button" type="button" id="confirmCancelEventBtn" style="background-color: var(--tomato); border-color: var(--tomato);">Event absagen</button>
</div>
</div>
</div>
<div class="instagram-invite">
<a href="https://www.instagram.com" target="_blank" rel="noopener noreferrer" class="instagram-invite__link">
<img src="assets/Icon_instagram.png" alt="Instagram" class="instagram-invite__icon" />
<img src="assets/logo_invite.svg" alt="Invité Logo" class="instagram-invite__logo" />
</a>
</div>
<footer class="footer">
<a href="impressum.html" class="footer__link">Impressum</a>
<a href="datenschutz.html" class="footer__link">Datenschutz</a>
</footer>
<script src="js/my_profil.js"></script> <script src="js/my_profil.js"></script>
</body> </body>
</html> </html>

View File

@ -73,7 +73,7 @@
</form> </form>
</div> </div>
</div> </div>
</div> <!-- Schließt main-content --> </div> <!-- Schliesst main-content -->
<!-- Welcome Modal --> <!-- Welcome Modal -->
<div id="welcomeModal" class="modal"> <div id="welcomeModal" class="modal">