Add dates/events section — loads from schedule webhook, shows cards with date/time

This commit is contained in:
Kato
2026-09-05 13:42:44 +00:00
parent 3df23371cf
commit f594543daa
3 changed files with 168 additions and 1 deletions
+74
View File
@@ -367,6 +367,80 @@ body {
transform: scale(1.1);
}
/* ========================================
DATES / EVENTS
*/
.dates-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 20px;
margin-top: 30px;
}
.date-card {
background: #fff;
border-radius: 12px;
padding: 24px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
border-left: 4px solid #0088cc;
}
.date-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.date-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.date-icon {
width: 44px;
height: 44px;
background: linear-gradient(135deg, #0088cc, #006699);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 20px;
flex-shrink: 0;
}
.date-headline {
font-size: 17px;
font-weight: 700;
color: #1a1a2e;
margin: 0;
}
.date-info {
display: flex;
flex-direction: column;
gap: 8px;
}
.date-row {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: #555;
}
.date-row svg {
width: 16px;
height: 16px;
fill: #0088cc;
flex-shrink: 0;
}
.no-events {
grid-column: 1 / -1;
text-align: center;
padding: 40px;
color: #888;
font-size: 15px;
}
/* ========================================
HERO — Focal Motion
======================================== */
+16
View File
@@ -424,6 +424,22 @@
</div>
</section>
<!-- Dates / Events Section -->
<section class="section fade-in-section" id="dates" style="display:none;">
<div class="container">
<h2 class="section-title">
<span class="hide-de">Termine</span>
<span class="hide-en">Dates & Events</span>
</h2>
<div class="dates-grid" id="dates-list">
<p class="loading-text">
<span class="hide-de">Lade Termine...</span>
<span class="hide-en">Loading events...</span>
</p>
</div>
</div>
</section>
</main>
<!-- Footer -->
+77
View File
@@ -8,6 +8,7 @@ const USER_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/user';
const PROFILE_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/profile';
const WIKI_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/wiki';
const COMMUNITY_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/community';
const SCHEDULE_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/schedule';
let currentLang = 'de';
@@ -283,6 +284,7 @@ function checkSession() {
document.getElementById('newsletter-section').style.display = 'block';
loadUsers();
loadWiki();
loadDates();
} else {
document.body.dataset.loggedIn = 'false';
document.getElementById('login-btn').style.display = 'inline-flex';
@@ -720,6 +722,81 @@ function searchWiki(term) {
renderWikiCards(filtered);
}
// ========================================
// DATES / EVENTS
// ========================================
async function loadDates() {
try {
const response = await fetch(SCHEDULE_URL);
if (!response.ok) throw new Error('Failed to fetch');
const result = await response.json();
if (result.data && Array.isArray(result.data) && result.data.length > 0) {
renderDates(result.data);
} else {
document.getElementById('dates-list').innerHTML =
`<p class="no-events">${isDE() ? 'Keine Termine geplant' : 'No events scheduled'}</p>`;
}
} catch (error) {
document.getElementById('dates-list').innerHTML =
`<p class="no-events">${isDE() ? 'Fehler beim Laden' : 'Error loading events'}</p>`;
}
}
function renderDates(events) {
const container = document.getElementById('dates-list');
container.innerHTML = '';
// Sort events by date
const sorted = events.sort((a, b) => new Date(a.start) - new Date(b.start));
sorted.forEach(event => {
const card = document.createElement('div');
card.className = 'date-card';
// Parse date/time from ISO string
const startDate = new Date(event.start);
const endDate = new Date(event.end);
// Format date: yyyy.mm.dd
const day = String(startDate.getDate()).padStart(2, '0');
const month = String(startDate.getMonth() + 1).padStart(2, '0');
const year = startDate.getFullYear();
const dateStr = `${year}.${month}.${day}`;
// Format time: HH:MM (local time)
const startHour = String(startDate.getHours()).padStart(2, '0');
const startMinute = String(startDate.getMinutes()).padStart(2, '0');
const endHour = String(endDate.getHours()).padStart(2, '0');
const endMinute = String(endDate.getMinutes()).padStart(2, '0');
const startStr = `${startHour}:${startMinute}`;
const endStr = `${endHour}:${endMinute}`;
card.innerHTML = `
<div class="date-header">
<div class="date-icon">📅</div>
<h3 class="date-headline">${escapeHtml(event.headline || 'Unbenanntes Event')}</h3>
</div>
<div class="date-info">
<div class="date-row">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
<span>${dateStr}</span>
</div>
<div class="date-row">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
<span>${isDE() ? 'Start' : 'Start'} ${startStr}</span>
</div>
<div class="date-row">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
<span>${isDE() ? 'Ende' : 'End'} ${endStr}</span>
</div>
</div>
`;
container.appendChild(card);
});
}
// ========================================
// COOKIES
// ========================================