diff --git a/src/static/dashboard.html b/src/static/dashboard.html
index 6f19152..abfef81 100644
--- a/src/static/dashboard.html
+++ b/src/static/dashboard.html
@@ -764,7 +764,7 @@
-
+
diff --git a/src/static/js/tutorial.js b/src/static/js/tutorial.js
index 98e4e2e..6f4ed65 100644
--- a/src/static/js/tutorial.js
+++ b/src/static/js/tutorial.js
@@ -929,19 +929,19 @@ const Tutorial = {
}
},
},
- // 22 - Quellen Modal
+ // 22 - Quellen Modal (mit Cursor-Demo)
{
id: 'sources-modal',
target: '#modal-sources .modal',
title: 'Quellen verwalten',
- text: 'Die Quellenverwaltung zeigt alle konfigurierten Nachrichtenquellen. '
- + 'Hier sehen Sie für jede Quelle:
'
- + 'Name und URL - Die Quellbezeichnung und Adresse
'
- + 'Kategorie - Nachrichtenagentur, Qualitätszeitung, etc.
'
- + 'Sprache - Deutsch, Englisch oder Mehrsprachig
'
- + 'Status - Aktiv oder deaktiviert
'
- + 'Sie können Quellen auch für einzelne Lagen ausschließen, ohne sie global zu deaktivieren.',
+ text: 'Die Quellenverwaltung zeigt alle konfigurierten Nachrichtenquellen.
'
+ + 'Info-Symbol (i) - Zeigt Typ, Sprache und Ausrichtung der Quelle
'
+ + 'Kategorie-Badge - Farbige Kennzeichnung der Quellkategorie
'
+ + 'Ausschlie\u00dfen - Quelle f\u00fcr einzelne Lagen sperren
'
+ + '+ Quelle - Neue Quellen per URL hinzuf\u00fcgen
'
+ + 'Beobachten Sie, wie die Quellendetails angezeigt werden:',
position: 'left',
+ disableNav: true,
onEnter: function() {
var overlay = document.getElementById('modal-sources');
if (overlay && !overlay.classList.contains('active')) {
@@ -950,6 +950,10 @@ const Tutorial = {
}
}
if (overlay) overlay.style.zIndex = '9002';
+ // Warten bis Quellen geladen, dann Demo starten
+ Tutorial._stepTimeout(function() {
+ Tutorial._simulateSourcesDemo();
+ }, 1500);
},
onExit: function() {
var overlay = document.getElementById('modal-sources');
@@ -957,6 +961,10 @@ const Tutorial = {
overlay.classList.remove('active');
overlay.style.zIndex = '';
}
+ // Tooltip entfernen falls manuell erzeugt
+ var tip = document.getElementById('tutorial-tooltip');
+ if (tip) tip.remove();
+ Tutorial._clearSubHighlights();
},
},
// 23 - Chat
@@ -1903,6 +1911,92 @@ const Tutorial = {
this._enableNavAfterDemo();
},
+ // -----------------------------------------------------------------------
+ // Quellenverwaltung-Demo: Info-Icon hover + Tooltip zeigen
+ // -----------------------------------------------------------------------
+ async _simulateSourcesDemo() {
+ this._demoRunning = true;
+
+ // Warten bis Quellen geladen sind
+ var attempts = 0;
+ while (attempts < 10) {
+ var infoIcon = document.querySelector('#sources-list .info-icon');
+ if (infoIcon) break;
+ await this._wait(300);
+ attempts++;
+ }
+
+ var infoIcon = document.querySelector('#sources-list .info-icon');
+ if (!infoIcon) {
+ this._demoRunning = false;
+ this._enableNavAfterDemo();
+ return;
+ }
+
+ // 1. Cursor zum ersten Info-Icon
+ var rect = infoIcon.getBoundingClientRect();
+ var targetX = rect.left + rect.width / 2;
+ var targetY = rect.top + rect.height / 2;
+
+ this._showCursor(targetX - 80, targetY - 60, 'default');
+ await this._wait(300);
+ await this._animateCursor(targetX - 80, targetY - 60, targetX, targetY, 600);
+ await this._wait(200);
+
+ // 2. Info-Icon highlighten
+ this._highlightSub('#sources-list .info-icon');
+
+ // 3. Tooltip manuell anzeigen (da pointer-events blockiert sind)
+ var tooltipText = infoIcon.getAttribute('data-tooltip') || '';
+ if (tooltipText) {
+ var tooltip = document.createElement('div');
+ tooltip.id = 'tutorial-tooltip';
+ tooltip.style.cssText = 'position:fixed;z-index:9999;background:var(--bg-card);color:var(--text-primary);'
+ + 'border:1px solid var(--accent);border-radius:var(--radius);padding:8px 12px;font-size:12px;'
+ + 'line-height:1.5;max-width:250px;white-space:pre-line;box-shadow:var(--shadow-md);'
+ + 'pointer-events:none;';
+ tooltip.textContent = tooltipText;
+ document.body.appendChild(tooltip);
+
+ // Tooltip unter dem Icon positionieren
+ tooltip.style.left = Math.max(8, rect.left - 20) + 'px';
+ tooltip.style.top = (rect.bottom + 8) + 'px';
+ }
+
+ await this._wait(3000);
+
+ // 4. Tooltip entfernen
+ var tip = document.getElementById('tutorial-tooltip');
+ if (tip) tip.remove();
+ this._clearSubHighlights();
+
+ // 5. Zum "+ Quelle" Button
+ var addBtn = document.querySelector('.sources-toolbar-actions .btn-primary');
+ if (addBtn) {
+ var addRect = addBtn.getBoundingClientRect();
+ await this._animateCursor(targetX, targetY, addRect.left + addRect.width / 2, addRect.top + addRect.height / 2, 500);
+ this._highlightSub('.sources-toolbar-actions .btn-primary');
+ await this._wait(2000);
+ this._clearSubHighlights();
+ }
+
+ // 6. Zum "Ausschlie\u00dfen" Button der ersten Quelle
+ var excludeBtn = document.querySelector('#sources-list .source-group-actions .btn-secondary');
+ if (excludeBtn) {
+ var exRect = excludeBtn.getBoundingClientRect();
+ var prevRect = addBtn ? addBtn.getBoundingClientRect() : rect;
+ await this._animateCursor(prevRect.left + prevRect.width / 2, prevRect.top + prevRect.height / 2,
+ exRect.left + exRect.width / 2, exRect.top + exRect.height / 2, 500);
+ this._highlightSub('#sources-list .source-group-actions .btn-secondary');
+ await this._wait(2000);
+ this._clearSubHighlights();
+ }
+
+ this._hideCursor();
+ this._demoRunning = false;
+ this._enableNavAfterDemo();
+ },
+
// -----------------------------------------------------------------------
// Keyboard
// -----------------------------------------------------------------------