diff --git a/src/static/dashboard.html b/src/static/dashboard.html index 351fce4..1347da4 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 b650705..31bf762 100644 --- a/src/static/js/tutorial.js +++ b/src/static/js/tutorial.js @@ -460,7 +460,7 @@ const Tutorial = { id: 'new-incident-btn', target: '#new-incident-btn', title: 'Neue Lage anlegen', - text: 'Hier starten Sie die Erstellung einer neuen Lage. Im nächsten Schritt zeigen wir Ihnen das Formular dazu.', + text: 'Mit diesem Button erstellen Sie eine neue Lage. Wir simulieren jetzt die Eingabe f\u00fcr Sie.', position: 'right', onEnter: function() { Tutorial._stepTimeout(function() { @@ -475,41 +475,29 @@ const Tutorial = { if (overlay) overlay.classList.remove('active'); }, }, - // 3 - Neue Lage Modal: Überblick + // 3 - Formular ausf\u00fcllen (Cursor-Demo) { id: 'new-incident-modal', target: '#modal-new .modal', title: 'Lage konfigurieren', - text: 'Das Formular zur Lage-Erstellung. Hier legen Sie fest:

' - + 'Titel - Kurze Bezeichnung des Vorfalls
' - + 'Beschreibung - Kontext und Hintergrundinformationen
' - + 'Art der Lage - Live-Monitoring oder Analyse/Recherche
' - + 'Quellen - Internationale und Telegram-Quellen ein/aus
' - + 'Sichtbarkeit - Öffentlich oder privat für Ihr Team
' - + 'Aktualisierung - Manuell oder automatisch mit Intervall', + text: 'Beobachten Sie, wie das Formular Schritt f\u00fcr Schritt ausgef\u00fcllt wird. ' + + 'So legen Sie eine neue Lage an.', position: 'left', + disableNav: true, onEnter: function() { var overlay = document.getElementById('modal-new'); if (overlay && !overlay.classList.contains('active')) { overlay.classList.add('active'); } if (overlay) overlay.style.zIndex = '9002'; - // Demo: Titel vorausfüllen - var titleInput = document.getElementById('inc-title'); - if (titleInput) titleInput.value = 'Explosion in Hamburger Hafen'; - var descInput = document.getElementById('inc-description'); - if (descInput) descInput.value = 'Schwere Explosion im Hamburger Hafengebiet, Burchardkai-Terminal'; + // Formular zuruecksetzen + var t = document.getElementById('inc-title'); if (t) t.value = ''; + var d = document.getElementById('inc-description'); if (d) d.value = ''; + var r = document.getElementById('inc-refresh-mode'); if (r) { r.value = 'manual'; try { r.dispatchEvent(new Event('change')); } catch(e) {} } + Tutorial._simulateFormFill(); }, onExit: function() { - var overlay = document.getElementById('modal-new'); - if (overlay) { - overlay.classList.remove('active'); - overlay.style.zIndex = ''; - } - var titleInput = document.getElementById('inc-title'); - if (titleInput) titleInput.value = ''; - var descInput = document.getElementById('inc-description'); - if (descInput) descInput.value = ''; + // Werte stehen lassen (werden in stop() aufgeraeumt) }, }, // 4 - Lage-Typ: Live vs Recherche (mit Cursor-Demo) @@ -531,8 +519,13 @@ const Tutorial = { overlay.classList.add('active'); } if (overlay) overlay.style.zIndex = '9002'; - Tutorial._highlightSub('#inc-type'); - Tutorial._simulateTypeSwitch(); + // Modal-Body nach oben scrollen zum Typ-Feld + var modalBody = document.querySelector('#modal-new .modal-body'); + if (modalBody) modalBody.scrollTo({ top: 0, behavior: 'smooth' }); + Tutorial._stepTimeout(function() { + Tutorial._highlightSub('#inc-type'); + Tutorial._simulateTypeSwitch(); + }, 500); }, onExit: function() { var overlay = document.getElementById('modal-new'); @@ -1295,6 +1288,100 @@ const Tutorial = { this._enableNavAfterDemo(); }, + // ----------------------------------------------------------------------- + // Tipp-Simulation: Text Zeichen fuer Zeichen eingeben + // ----------------------------------------------------------------------- + _simulateTyping(input, text, ms) { + var self = this; + var charDelay = ms / text.length; + return new Promise(function(resolve) { + var i = 0; + function typeNext() { + if (!self._isActive || i >= text.length) { resolve(); return; } + input.value += text[i]; + input.dispatchEvent(new Event('input', { bubbles: true })); + i++; + setTimeout(typeNext, charDelay); + } + typeNext(); + }); + }, + + // ----------------------------------------------------------------------- + // Formular-Ausf\u00fcll-Demo (Step 3) + // ----------------------------------------------------------------------- + async _simulateFormFill() { + this._demoRunning = true; + + var titleInput = document.getElementById('inc-title'); + var descInput = document.getElementById('inc-description'); + var refreshSelect = document.getElementById('inc-refresh-mode'); + var modal = document.querySelector('#modal-new .modal'); + + if (!titleInput || !modal) { + this._demoRunning = false; + this._enableNavAfterDemo(); + return; + } + + // Modal-Body scrollen wir nach oben + var modalBody = modal.querySelector('.modal-body'); + if (modalBody) modalBody.scrollTop = 0; + + // 1. Cursor zum Titel-Feld + var titleRect = titleInput.getBoundingClientRect(); + var startX = titleRect.left - 60; + var startY = titleRect.top - 40; + this._showCursor(startX, startY, 'default'); + await this._wait(300); + await this._animateCursor(startX, startY, titleRect.left + 20, titleRect.top + titleRect.height / 2, 600); + await this._wait(200); + + // Fokus + Tippen + titleInput.focus(); + this._highlightSub('#inc-title'); + await this._simulateTyping(titleInput, 'Explosion in Hamburger Hafen', 1200); + await this._wait(500); + this._clearSubHighlights(); + + // 2. Cursor zur Beschreibung + if (descInput) { + var descRect = descInput.getBoundingClientRect(); + await this._animateCursor(titleRect.left + 20, titleRect.top + titleRect.height / 2, descRect.left + 20, descRect.top + 12, 500); + await this._wait(200); + descInput.focus(); + this._highlightSub('#inc-description'); + await this._simulateTyping(descInput, 'Schwere Explosion im Hafengebiet', 1000); + await this._wait(500); + this._clearSubHighlights(); + } + + // 3. Modal-Body runterscrollen zum Refresh-Feld + if (refreshSelect && modalBody) { + // Sanft scrollen + modalBody.scrollTo({ top: modalBody.scrollHeight, behavior: 'smooth' }); + await this._wait(600); + + var refRect = refreshSelect.getBoundingClientRect(); + var prevRect = descInput ? descInput.getBoundingClientRect() : titleRect; + await this._animateCursor(prevRect.left + 20, prevRect.top + 12, refRect.left + refRect.width / 2, refRect.top + refRect.height / 2, 600); + await this._wait(200); + + this._highlightSub('#inc-refresh-mode'); + refreshSelect.value = 'auto'; + try { refreshSelect.dispatchEvent(new Event('change')); } catch(e) {} + await this._wait(1200); + this._clearSubHighlights(); + } + + // 4. Cursor verschwindet + this._hideCursor(); + await this._wait(300); + + this._demoRunning = false; + this._enableNavAfterDemo(); + }, + // ----------------------------------------------------------------------- // Typ-Wechsel-Demo (Step 4) // -----------------------------------------------------------------------