'use strict'; /** * tools/demo-video/capture.js: nimmt die Bilder für das Demo-Video auf (Weboberfläche mit erfundenen Beispieldaten). * 1. php tools/demo-video/seed_demo.php (Demo-Installation anlegen) * 2. php -S 127.0.0.1:8097 -t (im Hintergrund starten) * 3. electron tools/demo-video/capture.js * Danach baut build_video.sh aus den Bildern das Video. */ const { app, BrowserWindow } = require('electron'); const fs = require('fs'); const path = require('path'); const BASE = 'http://127.0.0.1:8097'; const OUT = path.resolve(process.argv[2] || path.join(__dirname, 'frames')); fs.mkdirSync(OUT, { recursive: true }); const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); let win, n = 0; const run = (js) => win.webContents.executeJavaScript(js, true); /** Seite laden und Hinweise entfernen, die nur zur Demo-Installation gehören (SQLite-Hinweis, Abmelde-Zähler). */ const load = async (url) => { await win.loadURL(BASE + url); await sleep(700); await run(`(() => { document.querySelectorAll('div,p,section').forEach((e) => { if (e.children.length < 6 && /SQLite-Modus aktiv/.test(e.textContent) && e.textContent.length < 260) e.remove(); }); document.getElementById('session-timer-bar')?.remove(); })()`); }; /** Bildunterschrift unten einblenden, Bild speichern, Unterschrift wieder entfernen. */ async function shot(caption, name) { n += 1; await run(`(() => { const d = document.createElement('div'); d.id = '__cap'; d.textContent = ${JSON.stringify(caption)}; d.style.cssText = 'position:fixed;left:50%;bottom:26px;transform:translateX(-50%);z-index:2147483647;background:rgba(10,30,45,.92);color:#fff;font:600 21px Segoe UI,Arial,sans-serif;padding:13px 26px;border-radius:40px;box-shadow:0 6px 24px rgba(0,0,0,.35);max-width:1180px;text-align:center'; document.body.appendChild(d); })()`); await sleep(450); const img = await win.webContents.capturePage(); fs.writeFileSync(path.join(OUT, `${String(n).padStart(2, '0')}_${name}.png`), img.toPNG()); await run(`document.getElementById('__cap')?.remove()`); } async function ask(question) { await run(`(() => { const i = document.getElementById('as-input'); i.value = ${JSON.stringify(question)}; document.getElementById('as-form').dispatchEvent(new Event('submit', { cancelable: true })); })()`); await sleep(1300); } app.whenReady().then(async () => { win = new BrowserWindow({ width: 1440, height: 900, show: true, useContentSize: true, webPreferences: { contextIsolation: true, backgroundThrottling: false } }); try { // ── Kundenportal ── await load('/home.php'); await shot('Kundenportal: Hilfe finden und Tickets verfolgen', 'portal'); await run(`document.getElementById('as-bubble').click()`); await sleep(900); await ask('Wie lange dauert der Versand?'); await shot('Der digitale Assistent antwortet aus der Wissensdatenbank', 'assistent'); await ask('Wann seid ihr erreichbar?'); await ask('Wie kann ich meinen Vertrag beenden?'); await shot('Und bietet ein Ticket an, wenn er nichts findet', 'assistent_ticket'); await load('/ticket_new.php'); await shot('Tickets mit Thema, Priorität und Anhängen erstellen', 'neues_ticket'); // ── Mitarbeiterbereich ── await load('/staff/login.php'); await run(`(() => { document.getElementById('email').value = 'lena@demo.example'; document.getElementById('password').value = 'Demo-Passwort-1234'; document.querySelector('form button[type=submit]').click(); })()`); await sleep(1500); await load('/staff/dashboard.php'); await shot('Übersicht: Zahlen, Status des Teams und priorisierte Tickets', 'uebersicht'); await load('/staff/tickets.php?tab=open'); await shot('Ticketliste mit Filtern, Tabs und gespeicherten Ansichten', 'tickets'); await load('/staff/ticket_view.php?n=260102'); await shot('Ticket bearbeiten: Verlauf, Antworten, interne Notizen', 'ticket'); await run(`(() => { const el = [...document.querySelectorAll('span')].find((s) => /Wiedervorlage/.test(s.textContent)); if (el) el.scrollIntoView({ block: 'center' }); })()`); await sleep(500); await shot('Wiedervorlage, Beobachter und passende Artikel zum Ticket', 'ticket_extras'); await load('/staff/tickets.php?tab=snoozed'); await shot('Wiedervorlage: Tickets später wieder vorlegen lassen', 'wiedervorlage'); // ── Digitaler Assistent (Verwaltung) ── await load('/staff/assistant.php'); await shot('Digitaler Assistent: Einstellungen, Name und Begrüßung', 'assistent_admin'); await load('/staff/assistant.php?tab=answers'); await shot('Eigene Antworten zusätzlich zur Wissensdatenbank', 'assistent_antworten'); await load('/staff/assistant.php?tab=log'); await shot('Fragen-Log: Was wurde gefragt, was blieb ohne Antwort?', 'assistent_log'); await load('/staff/reports.php'); await shot('Berichte mit Bericht-Baukasten und CSV-Export', 'berichte'); } catch (e) { console.error('Fehler:', e); process.exitCode = 1; } console.log(`${n} Bilder in ${OUT}`); app.quit(); });