feat: Abmeldefrist-Hinweis auf Event-Detailseite, .hidden fix

This commit is contained in:
Estelle Köhler 2026-04-12 17:16:34 +02:00
parent e91cd8572e
commit 027f722d69
3 changed files with 60 additions and 7 deletions

View File

@ -782,6 +782,27 @@
font-weight: 600; font-weight: 600;
} }
.detail-action-btn-wrap {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.detail-dereg-hint {
display: block;
font-size: 11px;
font-weight: 400;
color: var(--olive);
opacity: 0.75;
}
.detail-dereg-hint--closed {
color: var(--tomato);
font-weight: 500;
opacity: 1;
}
.detail-primary-btn { .detail-primary-btn {
border-radius: var(--radius-pill); border-radius: var(--radius-pill);
color: var(--white); color: var(--white);

View File

@ -279,7 +279,7 @@ p {
} }
.hidden { .hidden {
display: none; display: none !important;
} }
/* Card Footer */ /* Card Footer */

View File

@ -117,6 +117,25 @@
return msUntilStart <= twelveHoursInMs; return msUntilStart <= twelveHoursInMs;
} }
// Abmeldefrist: 1 Tag (24 h) vor Eventstart.
function getDeregistrationInfo(event) {
const eventDateTime = parseEventDateTime(event);
if (!eventDateTime || Number.isNaN(eventDateTime.getTime())) {
return { daysLeft: null, isClosed: false };
}
const oneDayMs = 24 * 60 * 60 * 1000;
const deadlineMs = eventDateTime.getTime() - oneDayMs;
const msUntilDeadline = deadlineMs - Date.now();
if (msUntilDeadline <= 0) {
return { daysLeft: 0, isClosed: true };
}
const daysLeft = Math.ceil(msUntilDeadline / oneDayMs);
return { daysLeft, isClosed: false };
}
// Adresse ist nur im 12h-Fenster VOR Eventstart sichtbar. // Adresse ist nur im 12h-Fenster VOR Eventstart sichtbar.
function isAddressVisibleWindow(event) { function isAddressVisibleWindow(event) {
const eventDateTime = parseEventDateTime(event); const eventDateTime = parseEventDateTime(event);
@ -276,6 +295,7 @@
const isFull = freePlaces === 0; const isFull = freePlaces === 0;
const isRegistrationClosed = isRegistrationClosedForEvent(event); const isRegistrationClosed = isRegistrationClosedForEvent(event);
const isOwnEvent = isEventOwnedByCurrentUser(event, currentUser); const isOwnEvent = isEventOwnedByCurrentUser(event, currentUser);
const deregInfo = getDeregistrationInfo(event);
const userRegistrations = currentUser?.email && Array.isArray(registrationMap[currentUser.email]) const userRegistrations = currentUser?.email && Array.isArray(registrationMap[currentUser.email])
? registrationMap[currentUser.email].map(id => Number(id)) ? registrationMap[currentUser.email].map(id => Number(id))
: []; : [];
@ -287,11 +307,13 @@
: !currentUser : !currentUser
? 'Einloggen' ? 'Einloggen'
: isRegistered : isRegistered
? 'Abmelden' ? (deregInfo.isClosed ? 'Abmeldung geschlossen' : 'Abmelden')
: isRegistrationClosed : isRegistrationClosed
? 'Anmeldung geschlossen' ? 'Anmeldung geschlossen'
: 'Anmelden'; : 'Anmelden';
const actionButtonDisabled = isOwnEvent || (!isRegistered && (isFull || isRegistrationClosed)); const actionButtonDisabled = isOwnEvent
|| (!isRegistered && (isFull || isRegistrationClosed))
|| (isRegistered && deregInfo.isClosed);
const actionButtonVariantClass = isOwnEvent const actionButtonVariantClass = isOwnEvent
? ' detail-primary-btn-own' ? ' detail-primary-btn-own'
: isRegistered : isRegistered
@ -367,7 +389,6 @@
<div class="detail-participants-full hidden" data-participants-full> <div class="detail-participants-full hidden" data-participants-full>
${participants.map(name => ` ${participants.map(name => `
<div class="detail-participant-item"> <div class="detail-participant-item">
<span class="participant-avatar">${name.charAt(0).toUpperCase()}</span>
<span class="participant-name">${name}</span> <span class="participant-name">${name}</span>
</div> </div>
`).join('')} `).join('')}
@ -402,9 +423,20 @@
<span class="detail-spots-pill${isFull ? ' detail-spots-pill-full' : ''}"> <span class="detail-spots-pill${isFull ? ' detail-spots-pill-full' : ''}">
${isFull ? 'AUSGEBUCHT' : `${freePlaces} Plätze frei`} ${isFull ? 'AUSGEBUCHT' : `${freePlaces} Plätze frei`}
</span> </span>
<div class="detail-action-btn-wrap">
<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}
</button> </button>
${isRegistered && deregInfo.daysLeft !== null ? `
<small class="detail-dereg-hint${deregInfo.isClosed ? ' detail-dereg-hint--closed' : ''}">
${deregInfo.isClosed
? 'Abmeldefrist abgelaufen'
: deregInfo.daysLeft === 1
? 'Noch 1 Tag zur Abmeldung'
: `Noch ${deregInfo.daysLeft} Tage zur Abmeldung`}
</small>
` : ''}
</div>
</div> </div>
</section> </section>