/** * eventCard.js – Erstellt interaktive Event-Karten als DOM-Elemente. * Jede Karte zeigt Titel, Datum, Veranstaltungsort sowie Speichern- und Einladen-Buttons. */ /** * Erstellt eine vollständige Event-Karte als
-Element. * @param {Object} event - Event-Objekt mit id, name, date, time, venue, category * @returns {HTMLElement} Fertig aufgebautes Karten-Element */ export function createEventCard(event) { const article = document.createElement("article"); article.className = "event-card"; // --- TITEL --- const title = document.createElement("h3"); title.className = "event-card__title"; title.textContent = event.name; // --- DATUM & UHRZEIT formatieren (Schweizer Format: dd.mm.yyyy) --- const formattedDate = event.date ? new Date(event.date).toLocaleDateString("de-CH", { day: "2-digit", month: "2-digit", year: "numeric" }) : "Datum unbekannt"; const formattedTime = event.time ? event.time.slice(0, 5) : ""; const dateTime = formattedTime ? `${formattedDate}, ${formattedTime}` : formattedDate; const date = document.createElement("p"); date.className = "event-card__date"; date.textContent = dateTime; // --- VERANSTALTUNGSORT --- const venue = document.createElement("p"); venue.className = "event-card__venue"; venue.textContent = event.venue || "Ort unbekannt"; article.append(title, date, venue); if (event.url) { const link = document.createElement("a"); link.href = event.url; link.target = "_blank"; link.rel = "noopener noreferrer"; link.className = "btn btn-outline-secondary btn-sm mt-2"; link.textContent = "Event ansehen"; article.appendChild(link); } // Gäste sehen nur Event-Informationen. Speichern und Einladen sind Login-Funktionen. if (!window.currentUser) { return article; } // --- BUTTON-GRUPPE --- const buttonContainer = document.createElement("div"); buttonContainer.className = "d-flex gap-2 mt-2 flex-wrap"; // ========================= // SPEICHERN-BUTTON // Speichert das Event im localStorage, verhindert Duplikate // ========================= const saveBtn = document.createElement("button"); saveBtn.type = "button"; saveBtn.className = "btn btn-outline-primary btn-sm"; // Prüfen ob bereits gespeichert → Button-Text entsprechend setzen const alreadySaved = isAlreadySaved(event.id); saveBtn.textContent = alreadySaved ? "Gespeichert ✓" : "Speichern"; if (alreadySaved) saveBtn.disabled = true; saveBtn.addEventListener("click", () => { const saved = JSON.parse(localStorage.getItem("savedEvents") || "[]"); // Duplikat-Schutz if (saved.find(e => e.id === event.id)) { saveBtn.textContent = "Gespeichert ✓"; saveBtn.disabled = true; return; } saved.push(event); localStorage.setItem("savedEvents", JSON.stringify(saved)); // Visuelles Feedback statt alert() saveBtn.textContent = "Gespeichert ✓"; saveBtn.disabled = true; saveBtn.classList.replace("btn-outline-primary", "btn-success"); }); // ========================= // EINLADEN-BUTTON // Zeigt ein Inline-Formular an (kein browser-prompt()) // ========================= const inviteBtn = document.createElement("button"); inviteBtn.type = "button"; inviteBtn.textContent = "Einladen"; inviteBtn.className = "btn btn-primary btn-sm"; inviteBtn.disabled = false; inviteBtn.addEventListener("click", () => { if (!window.currentUser) { showCardMessage(article, "Bitte einloggen um Einladungen zu senden.", "warning"); return; } // Formular ein-/ausblenden (Toggle) const existing = article.querySelector(".invite-form"); if (existing) { existing.remove(); } else { article.appendChild(createInviteForm(event, article)); } }); buttonContainer.append(saveBtn, inviteBtn); article.appendChild(buttonContainer); return article; } // ========================= // HILFSFUNKTION – Einladungsformular // Erstellt ein kleines Inline-Formular mit Benutzername-Eingabe // ========================= function createInviteForm(event, card) { const form = document.createElement("div"); form.className = "invite-form mt-2 d-flex gap-2 align-items-center flex-wrap"; const input = document.createElement("input"); input.type = "text"; input.className = "form-control form-control-sm"; input.placeholder = "Benutzername eingeben"; input.setAttribute("aria-label", "Benutzername für Einladung"); const sendBtn = document.createElement("button"); sendBtn.type = "button"; sendBtn.textContent = "Senden"; sendBtn.className = "btn btn-primary btn-sm"; const cancelBtn = document.createElement("button"); cancelBtn.type = "button"; cancelBtn.textContent = "Abbrechen"; cancelBtn.className = "btn btn-outline-secondary btn-sm"; cancelBtn.addEventListener("click", () => form.remove()); sendBtn.addEventListener("click", async () => { const toUser = input.value.trim(); if (!toUser) { input.classList.add("is-invalid"); return; } input.classList.remove("is-invalid"); sendBtn.disabled = true; sendBtn.textContent = "Sende..."; try { const res = await fetch("http://localhost:3000/api/invitation", { method: "POST", headers: { "Content-Type": "application/json", "X-Username": window.currentUser }, body: JSON.stringify({ toUser, eventId: event.id, eventName: event.name, eventUrl: event.url || null }) }); if (!res.ok) { // Fehlermeldung vom Server auslesen (z.B. "Nutzer nicht registriert") const errData = await res.json().catch(() => ({})); throw new Error(errData.message || `Fehler ${res.status}`); } // Formular entfernen und Erfolgsmeldung anzeigen form.remove(); showCardMessage(card, `Einladung an "${toUser}" gesendet.`, "success"); } catch (err) { sendBtn.disabled = false; sendBtn.textContent = "Senden"; showCardMessage(card, err.message || "Fehler beim Senden der Einladung.", "danger"); } }); form.append(input, sendBtn, cancelBtn); return form; } // ========================= // HILFSFUNKTION – Status-Nachricht in Karte anzeigen // Zeigt eine kurze Meldung innerhalb der Karte an und blendet sie nach 3s aus // ========================= function showCardMessage(card, message, type) { // Alte Nachrichten entfernen card.querySelectorAll(".card-message").forEach(el => el.remove()); const msg = document.createElement("p"); msg.className = `card-message text-${type} mt-1 mb-0`; msg.textContent = message; card.appendChild(msg); setTimeout(() => msg.remove(), 3000); } // ========================= // HILFSFUNKTION – Prüft ob Event bereits gespeichert ist // ========================= function isAlreadySaved(eventId) { const saved = JSON.parse(localStorage.getItem("savedEvents") || "[]"); return saved.some(e => e.id === eventId); }