feat: Vorschau-Seite v2 - Komplettes Redesign
- Hero mit rotierenden Hintergrund-Videos - Live-Demo Karussell mit Lagebild-Textauszug + Weiterlesen - Interaktive Leaflet-Karte mit Live-Markern - Weichere Hintergrundfarben (kein hartes Weiss) - SVG-Wellen-Divider zwischen Sektionen - Trust-Section ersetzt durch Unser Versprechen (4 Cards) - Quellenanalyse-Icon getauscht (cube statt globe) - Keine Emdashes - Deutsche Flagge korrekt angezeigt (kein Invert-Filter) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -1,16 +1,11 @@
|
||||
/* AegisSight Monitor - Product Page JS */
|
||||
|
||||
/* AegisSight Monitor - Product Page v2 */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/* ==================== NAVBAR SHADOW ==================== */
|
||||
/* ==================== NAVBAR ==================== */
|
||||
var navbar = document.getElementById('navbar');
|
||||
window.addEventListener('scroll', function () {
|
||||
if (window.scrollY > 10) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
navbar.classList.toggle('scrolled', window.scrollY > 10);
|
||||
});
|
||||
|
||||
/* ==================== MOBILE MENU ==================== */
|
||||
@@ -18,55 +13,86 @@
|
||||
var menu = document.getElementById('mobile-menu');
|
||||
var overlay = document.getElementById('mobile-overlay');
|
||||
|
||||
function openMenu() {
|
||||
toggle.classList.add('active');
|
||||
menu.classList.add('open');
|
||||
overlay.classList.add('open');
|
||||
toggle.setAttribute('aria-expanded', 'true');
|
||||
menu.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
toggle.classList.remove('active');
|
||||
menu.classList.remove('open');
|
||||
overlay.classList.remove('open');
|
||||
toggle.setAttribute('aria-expanded', 'false');
|
||||
menu.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
|
||||
toggle.addEventListener('click', function () {
|
||||
if (menu.classList.contains('open')) {
|
||||
closeMenu();
|
||||
} else {
|
||||
openMenu();
|
||||
var isOpen = menu.classList.contains('open');
|
||||
if (isOpen) { closeMenu(); } else {
|
||||
toggle.classList.add('active');
|
||||
menu.classList.add('open');
|
||||
overlay.classList.add('open');
|
||||
toggle.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
});
|
||||
|
||||
overlay.addEventListener('click', closeMenu);
|
||||
|
||||
// Close on link click
|
||||
menu.querySelectorAll('a').forEach(function (link) {
|
||||
link.addEventListener('click', closeMenu);
|
||||
});
|
||||
menu.querySelectorAll('a').forEach(function (l) { l.addEventListener('click', closeMenu); });
|
||||
|
||||
/* ==================== SMOOTH SCROLL ==================== */
|
||||
document.querySelectorAll('a[href^="#"]').forEach(function (link) {
|
||||
link.addEventListener('click', function (e) {
|
||||
var target = document.querySelector(this.getAttribute('href'));
|
||||
if (target) {
|
||||
e.preventDefault();
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
var t = document.querySelector(this.getAttribute('href'));
|
||||
if (t) { e.preventDefault(); t.scrollIntoView({ behavior: 'smooth' }); }
|
||||
});
|
||||
});
|
||||
|
||||
/* ==================== LIVE DATA FETCH ==================== */
|
||||
function timeAgo(dateStr) {
|
||||
var now = new Date();
|
||||
var then = new Date(dateStr);
|
||||
var diffMs = now - then;
|
||||
var diffMin = Math.floor(diffMs / 60000);
|
||||
/* ==================== HERO VIDEOS ==================== */
|
||||
var videos = document.querySelectorAll('.hero-video');
|
||||
var currentVideo = 0;
|
||||
var ROTATION_INTERVAL = 12000;
|
||||
var rotationTimer;
|
||||
|
||||
function switchVideo() {
|
||||
videos[currentVideo].classList.remove('active');
|
||||
currentVideo = (currentVideo + 1) % videos.length;
|
||||
var next = videos[currentVideo];
|
||||
next.currentTime = 0;
|
||||
next.play().catch(function () {});
|
||||
next.classList.add('active');
|
||||
}
|
||||
|
||||
function startRotation() {
|
||||
rotationTimer = setInterval(switchVideo, ROTATION_INTERVAL);
|
||||
}
|
||||
|
||||
// Pause when tab hidden
|
||||
document.addEventListener('visibilitychange', function () {
|
||||
if (document.hidden) {
|
||||
clearInterval(rotationTimer);
|
||||
videos.forEach(function (v) { v.pause(); });
|
||||
} else {
|
||||
videos.forEach(function (v) { if (v.classList.contains('active')) v.play().catch(function () {}); });
|
||||
startRotation();
|
||||
}
|
||||
});
|
||||
|
||||
if (videos.length > 1) startRotation();
|
||||
|
||||
/* ==================== SIMPLE MARKDOWN ==================== */
|
||||
function mdToText(md) {
|
||||
if (!md) return '';
|
||||
// Remove ## headers and bold markers, keep text
|
||||
return md
|
||||
.replace(/^## .+$/gm, '')
|
||||
.replace(/^### .+$/gm, '')
|
||||
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
||||
.replace(/\[(\d+[a-z]?)\]/g, '')
|
||||
.replace(/\n{3,}/g, '\n\n')
|
||||
.trim()
|
||||
.split('\n\n')
|
||||
.filter(function (p) { return p.trim().length > 0; })
|
||||
.map(function (p) { return '<p>' + p.trim().replace(/\n/g, ' ') + '</p>'; })
|
||||
.join('');
|
||||
}
|
||||
|
||||
/* ==================== LIVE DATA ==================== */
|
||||
function timeAgo(dateStr) {
|
||||
var diffMin = Math.floor((Date.now() - new Date(dateStr).getTime()) / 60000);
|
||||
if (diffMin < 1) return 'Gerade eben aktualisiert';
|
||||
if (diffMin < 60) return 'Aktualisiert vor ' + diffMin + ' Min.';
|
||||
var diffH = Math.floor(diffMin / 60);
|
||||
@@ -75,33 +101,103 @@
|
||||
return 'Aktualisiert vor ' + diffD + (diffD === 1 ? ' Tag' : ' Tagen');
|
||||
}
|
||||
|
||||
var liveData = null;
|
||||
|
||||
function loadLiveData() {
|
||||
fetch('/lagen/iran-konflikt/data/current.json?t=' + Date.now())
|
||||
.then(function (res) {
|
||||
if (!res.ok) throw new Error('HTTP ' + res.status);
|
||||
return res.json();
|
||||
})
|
||||
.then(function (r) { if (!r.ok) throw new Error(r.status); return r.json(); })
|
||||
.then(function (data) {
|
||||
var incident = data.incident || {};
|
||||
var lagebild = data.current_lagebild || {};
|
||||
liveData = data;
|
||||
var inc = data.incident || {};
|
||||
var lag = data.current_lagebild || {};
|
||||
|
||||
var elArticles = document.getElementById('stat-articles');
|
||||
var elSources = document.getElementById('stat-sources');
|
||||
var elFactchecks = document.getElementById('stat-factchecks');
|
||||
var elUpdated = document.getElementById('demo-updated');
|
||||
// Stats
|
||||
var ea = document.getElementById('stat-articles');
|
||||
var es = document.getElementById('stat-sources');
|
||||
var ef = document.getElementById('stat-factchecks');
|
||||
var eu = document.getElementById('demo-updated');
|
||||
if (ea) ea.textContent = inc.article_count || 0;
|
||||
if (es) es.textContent = inc.source_count || 0;
|
||||
if (ef) ef.textContent = inc.factcheck_count || 0;
|
||||
if (eu && lag.updated_at) eu.textContent = timeAgo(lag.updated_at);
|
||||
|
||||
if (elArticles) elArticles.textContent = incident.article_count || '—';
|
||||
if (elSources) elSources.textContent = incident.source_count || '—';
|
||||
if (elFactchecks) elFactchecks.textContent = incident.factcheck_count || '—';
|
||||
if (elUpdated && lagebild.updated_at) {
|
||||
elUpdated.textContent = timeAgo(lagebild.updated_at);
|
||||
// Excerpt
|
||||
var excerptEl = document.getElementById('excerpt-text');
|
||||
var toggleBtn = document.getElementById('excerpt-toggle');
|
||||
if (excerptEl && lag.summary_markdown) {
|
||||
var html = mdToText(lag.summary_markdown);
|
||||
excerptEl.innerHTML = html;
|
||||
toggleBtn.style.display = 'inline-block';
|
||||
|
||||
toggleBtn.addEventListener('click', function () {
|
||||
var expanded = excerptEl.classList.toggle('expanded');
|
||||
this.textContent = expanded ? 'Weniger anzeigen' : 'Weiterlesen';
|
||||
});
|
||||
}
|
||||
|
||||
// Map
|
||||
if (data.locations && data.locations.length > 0) {
|
||||
initMap(data.locations, data.category_labels || {});
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
var elUpdated = document.getElementById('demo-updated');
|
||||
if (elUpdated) elUpdated.textContent = 'Daten derzeit nicht verfügbar';
|
||||
var eu = document.getElementById('demo-updated');
|
||||
if (eu) eu.textContent = 'Daten derzeit nicht verfügbar';
|
||||
});
|
||||
}
|
||||
|
||||
/* ==================== LEAFLET MAP ==================== */
|
||||
function initMap(locations, categoryLabels) {
|
||||
var mapEl = document.getElementById('map-container');
|
||||
if (!mapEl || typeof L === 'undefined') return;
|
||||
|
||||
var map = L.map(mapEl, {
|
||||
center: [33.0, 48.0],
|
||||
zoom: 5,
|
||||
zoomControl: true,
|
||||
scrollWheelZoom: false
|
||||
});
|
||||
|
||||
L.tileLayer('https://tile.openstreetmap.de/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap',
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
var catColors = {
|
||||
primary: '#E74C3C',
|
||||
secondary: '#F39C12',
|
||||
tertiary: '#3498DB',
|
||||
mentioned: '#95A5A6'
|
||||
};
|
||||
|
||||
var bounds = [];
|
||||
|
||||
locations.forEach(function (loc) {
|
||||
if (!loc.lat || !loc.lon) return;
|
||||
var cat = loc.category || 'mentioned';
|
||||
var color = catColors[cat] || catColors.mentioned;
|
||||
var catClass = 'cat-' + cat;
|
||||
|
||||
var icon = L.divIcon({
|
||||
className: 'pulse-marker ' + catClass,
|
||||
iconSize: [12, 12],
|
||||
iconAnchor: [6, 6]
|
||||
});
|
||||
|
||||
var marker = L.marker([loc.lat, loc.lon], { icon: icon }).addTo(map);
|
||||
var label = categoryLabels[cat] || cat;
|
||||
marker.bindPopup('<strong>' + loc.name + '</strong><br>' + label + ' (' + (loc.article_count || 0) + ' Artikel)');
|
||||
bounds.push([loc.lat, loc.lon]);
|
||||
});
|
||||
|
||||
if (bounds.length > 0) {
|
||||
map.fitBounds(bounds, { padding: [30, 30], maxZoom: 7 });
|
||||
}
|
||||
|
||||
// Fix tile rendering on hidden tab / late load
|
||||
setTimeout(function () { map.invalidateSize(); }, 500);
|
||||
}
|
||||
|
||||
/* ==================== INIT ==================== */
|
||||
loadLiveData();
|
||||
})();
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren