document.addEventListener('DOMContentLoaded', () => { const EVENTS_STORAGE_KEY = 'socialCookingEvents'; const USERS_STORAGE_KEY = 'socialCookingUsers'; const CURRENT_USER_KEY = 'socialCookingCurrentUser'; const REGISTRATION_STORAGE_KEY = 'socialCookingRegistrations'; // Zentrale DOM-Referenzen fuer klare, testbare Funktionen. const loggedOutState = document.getElementById('logged-out-state'); const loggedInContent = document.getElementById('logged-in-content'); const profileHeadline = document.getElementById('profile-headline'); const profileSubline = document.getElementById('profile-subline'); const logoutButton = document.getElementById('logout-button'); const myEventsCount = document.getElementById('my-events-count'); const myRegistrationsCount = document.getElementById('my-registrations-count'); const myEventsList = document.getElementById('my-events-list'); const myRegistrationsList = document.getElementById('my-registrations-list'); const profileForm = document.getElementById('profile-form'); const profileFeedback = document.getElementById('profile-feedback'); const vornameInput = document.getElementById('vorname'); const nachnameInput = document.getElementById('nachname'); const emailInput = document.getElementById('email'); const passwortInput = document.getElementById('passwort'); let currentUser = getCurrentUser(); let allEvents = []; init(); async function init() { if (!currentUser) { renderLoggedOutState(); return; } renderLoggedInState(currentUser); bindFormHandlers(); allEvents = await loadAllEvents(); renderMyEvents(allEvents, currentUser); renderMyRegistrations(allEvents, currentUser); } // Liest den aktuell eingeloggten Benutzer robust aus dem Storage. function getCurrentUser() { try { const raw = localStorage.getItem(CURRENT_USER_KEY); return raw ? JSON.parse(raw) : null; } catch (error) { console.error('Der aktuelle Benutzer konnte nicht geladen werden.', error); return null; } } // Liest lokal erstellte Events aus dem Storage. function getStoredEvents() { try { const raw = localStorage.getItem(EVENTS_STORAGE_KEY); return raw ? JSON.parse(raw) : []; } catch (error) { console.error('Lokale Events konnten nicht gelesen werden.', error); return []; } } // Liest den Anmeldestatus pro Benutzer-E-Mail. function getRegistrationMap() { try { const raw = localStorage.getItem(REGISTRATION_STORAGE_KEY); return raw ? JSON.parse(raw) : {}; } catch (error) { console.error('Anmeldedaten konnten nicht gelesen werden.', error); return {}; } } // Schreibt den gesamten Registrierungszustand in localStorage. function setRegistrationMap(registrationMap) { localStorage.setItem(REGISTRATION_STORAGE_KEY, JSON.stringify(registrationMap)); } // Fuehrt JSON-Daten und lokal erstellte Events in einer Liste zusammen. async function loadAllEvents() { try { const response = await fetch('data/events.json'); const apiEvents = await response.json(); return [...getStoredEvents(), ...apiEvents]; } catch (error) { console.error('Events konnten nicht geladen werden.', error); return getStoredEvents(); } } // Schaltet in den ausgeloggten Zustand und blendet geschuetzte Inhalte aus. function renderLoggedOutState() { loggedOutState.classList.remove('hidden'); loggedInContent.classList.add('hidden'); logoutButton.classList.add('hidden'); profileHeadline.textContent = 'Mein Profil'; profileSubline.textContent = 'Bitte logge dich ein, um deinen Bereich zu sehen.'; } // Fuellt Ueberschriften und Formular mit den aktuellen Benutzerdaten. function renderLoggedInState(user) { loggedOutState.classList.add('hidden'); loggedInContent.classList.remove('hidden'); logoutButton.classList.remove('hidden'); profileHeadline.textContent = `Hallo ${user.vorname || 'Gast'}`; profileSubline.textContent = 'Hier kannst du deine Events und Anmeldungen verwalten.'; vornameInput.value = user.vorname || ''; nachnameInput.value = user.nachname || ''; emailInput.value = user.email || ''; } // Bindet Submit-, Input- und Logout-Verhalten an die Profilseite. function bindFormHandlers() { profileForm.addEventListener('submit', handleProfileSubmit); myRegistrationsList.addEventListener('click', handleRegistrationListClick); [vornameInput, nachnameInput, emailInput, passwortInput].forEach(input => { input.addEventListener('input', () => { input.parentElement.classList.remove('has-error'); profileFeedback.textContent = ''; }); }); logoutButton.addEventListener('click', () => { localStorage.removeItem(CURRENT_USER_KEY); window.location.href = 'login.html'; }); } // Reagiert auf Aktionen in der Liste "Meine Anmeldungen" per Event Delegation. function handleRegistrationListClick(event) { const target = event.target; if (!(target instanceof HTMLElement)) { return; } const unregisterButton = target.closest('[data-unregister-id]'); if (!unregisterButton || !currentUser?.email) { return; } const eventId = Number(unregisterButton.getAttribute('data-unregister-id')); if (!Number.isFinite(eventId)) { return; } unregisterFromEvent(eventId, currentUser.email); } // Entfernt eine Event-ID aus der Benutzerliste und aktualisiert die UI sofort. function unregisterFromEvent(eventId, userEmail) { const registrationMap = getRegistrationMap(); const currentIds = Array.isArray(registrationMap[userEmail]) ? registrationMap[userEmail] : []; const nextIds = currentIds .map(id => Number(id)) .filter(id => Number.isFinite(id) && id !== eventId); registrationMap[userEmail] = nextIds; setRegistrationMap(registrationMap); renderMyRegistrations(allEvents, currentUser); profileFeedback.textContent = 'Du wurdest von dem Event abgemeldet.'; } // Validiert Profildaten konsistent und liefert true/false zur Submit-Steuerung. function validateProfileForm() { let isValid = true; const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!vornameInput.value.trim()) { vornameInput.parentElement.classList.add('has-error'); isValid = false; } if (!nachnameInput.value.trim()) { nachnameInput.parentElement.classList.add('has-error'); isValid = false; } if (!emailRegex.test(emailInput.value.trim())) { emailInput.parentElement.classList.add('has-error'); isValid = false; } if (passwortInput.value && passwortInput.value.length < 6) { passwortInput.parentElement.classList.add('has-error'); isValid = false; } return isValid; } // Speichert Profilaenderungen lokal und synchronisiert auch den Benutzerkatalog. function handleProfileSubmit(event) { event.preventDefault(); if (!validateProfileForm()) { profileFeedback.textContent = 'Bitte pruefe die markierten Felder.'; return; } const previousEmail = currentUser.email; const nextUser = { ...currentUser, vorname: vornameInput.value.trim(), nachname: nachnameInput.value.trim(), email: emailInput.value.trim(), passwort: passwortInput.value ? passwortInput.value : currentUser.passwort, updatedAt: new Date().toISOString() }; currentUser = nextUser; localStorage.setItem(CURRENT_USER_KEY, JSON.stringify(nextUser)); syncUserInUserStore(previousEmail, nextUser); // Falls sich die E-Mail geaendert hat, verschieben wir bestehende Anmeldungen auf die neue E-Mail. migrateRegistrationEmail(previousEmail, nextUser.email); passwortInput.value = ''; profileHeadline.textContent = `Hallo ${nextUser.vorname}`; profileFeedback.textContent = 'Profil erfolgreich gespeichert.'; } // Synchronisiert einen Benutzer im zentralen User-Array. function syncUserInUserStore(previousEmail, nextUser) { let users = []; try { const raw = localStorage.getItem(USERS_STORAGE_KEY); users = raw ? JSON.parse(raw) : []; } catch (error) { console.error('Benutzerdaten konnten nicht gelesen werden.', error); } const nextUsers = users.filter(user => user.email !== previousEmail && user.email !== nextUser.email); nextUsers.unshift(nextUser); localStorage.setItem(USERS_STORAGE_KEY, JSON.stringify(nextUsers)); } // Migriert bestehende Registrierungen, falls die E-Mail aktualisiert wurde. function migrateRegistrationEmail(previousEmail, nextEmail) { if (!previousEmail || !nextEmail || previousEmail === nextEmail) { return; } const map = getRegistrationMap(); const existingRegistrations = Array.isArray(map[previousEmail]) ? map[previousEmail] : []; const alreadyPresent = Array.isArray(map[nextEmail]) ? map[nextEmail] : []; map[nextEmail] = Array.from(new Set([...alreadyPresent, ...existingRegistrations])); delete map[previousEmail]; localStorage.setItem(REGISTRATION_STORAGE_KEY, JSON.stringify(map)); } // Ermittelt gehostete Events anhand Host-E-Mail oder Host-Vorname. function getMyHostedEvents(events, user) { const userFirstName = normalizeText(user.vorname); return events.filter(event => { const hostEmail = normalizeText(event.hostEmail || ''); const hostName = normalizeText(event.host?.name || ''); if (hostEmail && hostEmail === normalizeText(user.email)) { return true; } return userFirstName && hostName === userFirstName; }); } // Ermittelt angemeldete Events ueber die Registration-Map. function getMyRegisteredEvents(events, user) { const registrationMap = getRegistrationMap(); const registeredIds = Array.isArray(registrationMap[user.email]) ? registrationMap[user.email] : []; const idSet = new Set(registeredIds.map(id => Number(id))); return events.filter(event => idSet.has(Number(event.id))); } // Rendert gehostete Events inkl. Zaehler. function renderMyEvents(events, user) { const hostedEvents = getMyHostedEvents(events, user); myEventsCount.textContent = String(hostedEvents.length); renderEventCards(myEventsList, hostedEvents, 'Du hast noch kein eigenes Event erstellt.', false); } // Rendert angemeldete Events inkl. Zaehler. function renderMyRegistrations(events, user) { const registeredEvents = getMyRegisteredEvents(events, user); myRegistrationsCount.textContent = String(registeredEvents.length); renderEventCards(myRegistrationsList, registeredEvents, 'Du bist aktuell bei keinem Event angemeldet.', true); } // Baut die Eventkarten fuer beide Listen in einheitlichem Markup. function renderEventCards(container, events, emptyText, withUnregisterButton) { container.innerHTML = ''; if (events.length === 0) { const emptyElement = document.createElement('p'); emptyElement.className = 'profile-empty'; emptyElement.textContent = emptyText; container.appendChild(emptyElement); return; } events.forEach(event => { const card = document.createElement('article'); card.className = 'profile-event-card'; const actionMarkup = withUnregisterButton ? `
Zum Event
` : `Zum Event`; card.innerHTML = `

${event.title}

${event.location} | ${formatEventDate(event.date)} | ${formatEventTime(event.time)}

${actionMarkup} `; container.appendChild(card); }); } // Formatiert ein Eventdatum konsistent fuer die Profilkarten. function formatEventDate(dateString) { if (!dateString) { return 'Kein Datum'; } if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) { const [year, month, day] = dateString.split('-'); const monthLabel = ['Januar', 'Februar', 'Maerz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'][Number(month) - 1]; return `${Number(day)}. ${monthLabel} ${year}`; } return dateString; } // Vereinheitlicht die Zeitanzeige fuer die Profilseite. function formatEventTime(timeString) { if (!timeString) { return 'Keine Uhrzeit'; } return timeString.includes('UHR') ? timeString.replace('UHR', 'Uhr').trim() : timeString; } // Normalisiert Vergleichswerte fuer robuste String-Matches. function normalizeText(value) { return String(value || '').trim().toLowerCase(); } });