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 profileTabButtons = Array.from(document.querySelectorAll('[data-profile-tab]')); const profileTabPanels = Array.from(document.querySelectorAll('[data-profile-panel]')); 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(); activateProfileTab('hosting'); 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)); } // Schreibt die lokal erstellten Events in den Storage. function setStoredEvents(events) { localStorage.setItem(EVENTS_STORAGE_KEY, JSON.stringify(events)); } // 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); myEventsList.addEventListener('click', handleHostedListClick); profileTabButtons.forEach(button => { button.addEventListener('click', () => { const tabName = button.getAttribute('data-profile-tab'); if (!tabName) { return; } activateProfileTab(tabName); }); }); [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 Events" per Event Delegation. function handleHostedListClick(event) { const target = event.target; if (!(target instanceof HTMLElement)) { return; } const cancelButton = target.closest('[data-cancel-event-id]'); if (cancelButton && currentUser?.email) { const eventId = Number(cancelButton.getAttribute('data-cancel-event-id')); if (Number.isFinite(eventId)) { cancelHostedEvent(eventId, currentUser.email); } return; } if (target.closest('a, button')) { return; } const card = target.closest('[data-event-id]'); if (!card) { return; } const eventId = Number(card.getAttribute('data-event-id')); if (!Number.isFinite(eventId)) { return; } window.location.href = `event_detail.html?id=${eventId}`; } // Schaltet den sichtbaren Profilbereich per Tabname um. function activateProfileTab(tabName) { profileTabButtons.forEach(button => { const isActive = button.getAttribute('data-profile-tab') === tabName; button.classList.toggle('is-active', isActive); button.setAttribute('aria-selected', isActive ? 'true' : 'false'); }); profileTabPanels.forEach(panel => { const isActive = panel.getAttribute('data-profile-panel') === tabName; panel.classList.toggle('hidden', !isActive); }); } // 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) { if (!currentUser?.email) { return; } const eventId = Number(unregisterButton.getAttribute('data-unregister-id')); if (!Number.isFinite(eventId)) { return; } unregisterFromEvent(eventId, currentUser.email); return; } if (target.closest('a, button')) { return; } const card = target.closest('[data-event-id]'); if (!card) { return; } const eventId = Number(card.getAttribute('data-event-id')); if (!Number.isFinite(eventId)) { return; } window.location.href = `event_detail.html?id=${eventId}`; } // Sagt ein gehostetes Event ab (aus eigener Profilansicht entfernen). function cancelHostedEvent(eventId, userEmail) { // Lokal erstellte, eigene Events werden direkt aus dem Storage geloescht. const storedEvents = getStoredEvents(); const nextStoredEvents = storedEvents.filter(event => { const isTargetEvent = Number(event.id) === eventId; const isOwnedByUser = normalizeText(event.hostEmail || '') === normalizeText(userEmail) || normalizeText(event.host?.name || '') === normalizeText(currentUser?.vorname || ''); return !(isTargetEvent && isOwnedByUser); }); setStoredEvents(nextStoredEvents); // Event-ID fuer alle Benutzer aus den Anmeldungen entfernen. const registrationMap = getRegistrationMap(); Object.keys(registrationMap).forEach(email => { const ids = Array.isArray(registrationMap[email]) ? registrationMap[email].map(id => Number(id)).filter(Number.isFinite) : []; registrationMap[email] = ids.filter(id => id !== eventId); }); setRegistrationMap(registrationMap); allEvents = allEvents.filter(event => Number(event.id) !== eventId); renderMyEvents(allEvents, currentUser); renderMyRegistrations(allEvents, currentUser); profileFeedback.textContent = 'Event wurde abgesagt und aus deinem Hosting entfernt.'; } // 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 aus lokal erstellten Daten des aktuellen Benutzers. function getMyHostedEvents(events, user) { const userFirstName = normalizeText(user.vorname || ''); const userEmail = normalizeText(user.email || ''); return events.filter(event => { if (event.source !== 'local') { return false; } const hostEmail = normalizeText(event.hostEmail || ''); const hostName = normalizeText(event.host?.name || ''); if (hostEmail && hostEmail === userEmail) { 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, { title: 'Noch kein eigenes Event', text: 'Starte dein erstes Dinner und lade die Community an deinen Tisch ein.', buttonLabel: 'Event erstellen', href: 'event_create.html' }, 'hosting'); } // Rendert angemeldete Events inkl. Zaehler. function renderMyRegistrations(events, user) { const registeredEvents = getMyRegisteredEvents(events, user); myRegistrationsCount.textContent = String(registeredEvents.length); renderEventCards(myRegistrationsList, registeredEvents, { title: 'Noch keine Anmeldungen', text: 'Entdecke spannende Dinner in deiner Naehe und melde dich direkt an.', buttonLabel: 'Events entdecken', href: 'event_overview.html' }, 'registrations'); } // Baut die Eventkarten fuer beide Listen in einheitlichem Markup. function renderEventCards(container, events, emptyStateConfig, mode) { container.innerHTML = ''; if (events.length === 0) { const emptyElement = document.createElement('div'); emptyElement.className = 'profile-empty-state'; emptyElement.innerHTML = `
Keine Treffer
${emptyStateConfig.text}
${emptyStateConfig.buttonLabel} `; container.appendChild(emptyElement); return; } events.forEach(event => { const card = document.createElement('article'); card.className = 'profile-event-card profile-event-card-clickable'; card.setAttribute('data-event-id', String(event.id)); const addressMarkup = mode === 'registrations' && event.address && isAddressVisibleWindow(event) ? `Adresse
${event.address}