* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix * fix: track native source modules with root-anchored runtime ignores
2374 lines
173 KiB
HTML
2374 lines
173 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="vendoo-build" content="1.41.2">
|
||
<title>Vendoo</title>
|
||
<link rel="icon" href="/brand/favicons/favicon.ico" sizes="any">
|
||
<link rel="icon" type="image/png" sizes="16x16" href="/brand/favicons/favicon-16x16.png">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/brand/favicons/favicon-32x32.png">
|
||
<link rel="icon" type="image/png" sizes="48x48" href="/brand/favicons/favicon-48x48.png">
|
||
<link rel="apple-touch-icon" sizes="180x180" href="/brand/favicons/apple-touch-icon.png">
|
||
<link rel="manifest" href="/brand/favicons/site.webmanifest">
|
||
<meta name="msapplication-config" content="/brand/favicons/browserconfig.xml">
|
||
<meta name="theme-color" content="#FAF6F2">
|
||
<link rel="stylesheet" href="style.css?v=1.41.2">
|
||
<link rel="stylesheet" href="modules/theme-manager/theme-manager.css?v=1.41.2">
|
||
<link rel="stylesheet" href="modules/module-manager/module-manager.css?v=1.41.2">
|
||
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.snow.css" rel="stylesheet">
|
||
</head>
|
||
<body>
|
||
<aside class="sidebar" id="sidebar" aria-label="Hauptnavigation">
|
||
<div class="sidebar-header">
|
||
<div class="sidebar-logo" aria-label="Vendoo">
|
||
<img class="brand-logo-full" src="/brand/logo/vendoo-logo-transparent.png" alt="Vendoo">
|
||
<img class="brand-logo-icon" src="/brand/icons/vendoo-icon-64x64.png" alt="" aria-hidden="true">
|
||
</div>
|
||
<button class="sidebar-close" id="sidebar-close" type="button" aria-label="Navigation schließen">
|
||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="m6 6 12 12M18 6 6 18"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<nav class="sidebar-nav">
|
||
<div class="nav-group nav-group-primary">
|
||
<button class="nav-item active" data-tab="dashboard">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
|
||
<span>Dashboard</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="generator">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12h14"/><rect x="3" y="3" width="18" height="18" rx="3"/></svg>
|
||
<span>Neuer Artikel</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="today">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11.5 12 4l9 7.5"/><path d="M5.5 10.5V20h13v-9.5"/><path d="M9.5 20v-6h5v6"/></svg>
|
||
<span>Heute</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="history">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 7h8M8 11h8M8 15h5"/></svg>
|
||
<span>Artikel</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="quality-center">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 20 7v5c0 5-3.4 8.3-8 10-4.6-1.7-8-5-8-10V7Z"/><path d="m8.5 12 2.2 2.2 4.8-5"/></svg>
|
||
<span>Qualitätscenter</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="publish">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>
|
||
<span>Publish</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="inventory">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m4 7 8-4 8 4-8 4Z"/><path d="m4 7 8 4 8-4v10l-8 4-8-4Z"/><path d="M12 11v10"/></svg>
|
||
<span>Lager</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="templates">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 8h8M8 12h8M8 16h5"/></svg>
|
||
<span>Vorlagen</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="flux-studio">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 9.8 8.2 4 10l5 3.2L8 19l4-3 4 3-1-5.8 5-3.2-5.8-1.8Z"/><path d="M18 3v4M16 5h4"/></svg>
|
||
<span>FLUX Studio</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="media-library">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="8.5" cy="9" r="1.5"/><path d="m4 17 5-5 4 4 2-2 5 5"/></svg>
|
||
<span>Bilder</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="image-factory">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4z"/><path d="M14 17h6M17 14v6"/></svg>
|
||
<span>Bildproduktion</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="extensions">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 3v4M15.5 3v4M6 7h12v4a6 6 0 0 1-12 0Z"/><path d="M12 17v4M9 21h6"/></svg>
|
||
<span>Extensions</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="settings">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.05.05-2.83 2.83-.05-.05a1.7 1.7 0 0 0-1.87-.34 1.7 1.7 0 0 0-1.04 1.57V21h-4v-.07a1.7 1.7 0 0 0-1.04-1.57 1.7 1.7 0 0 0-1.87.34l-.05.05-2.83-2.83.05-.05A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.57-1.04H3v-4h.07A1.7 1.7 0 0 0 4.64 8.9a1.7 1.7 0 0 0-.34-1.87l-.05-.05 2.83-2.83.05.05A1.7 1.7 0 0 0 9 4.54 1.7 1.7 0 0 0 10.04 3H10V3h4v.07A1.7 1.7 0 0 0 15.04 4.6a1.7 1.7 0 0 0 1.87-.34l.05-.05 2.83 2.83-.05.05A1.7 1.7 0 0 0 19.4 9c.24.63.85 1.04 1.53 1.04H21v4h-.07c-.68 0-1.29.41-1.53 1.04Z"/></svg>
|
||
<span>Einstellungen</span>
|
||
</button>
|
||
<button class="nav-item" data-tab="admin" data-admin-tab="users" id="nav-admin-main">
|
||
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/><path d="M9 12h6M12 9v6"/></svg>
|
||
<span>Admin</span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="nav-group nav-group-tools" id="nav-system-group">
|
||
<div class="nav-divider"></div>
|
||
<button class="nav-item nav-item-quiet" data-tab="fees">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 7h8M8 11h3M8 15h3M15 11v5M13 13.5h4"/></svg>
|
||
<span>Gebühren</span>
|
||
</button>
|
||
<button class="nav-item nav-item-quiet" data-tab="trash">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h16M9 7V4h6v3M7 7l1 14h8l1-14"/></svg>
|
||
<span>Papierkorb</span>
|
||
<span id="trash-badge" class="nav-badge hidden">0</span>
|
||
</button>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="sidebar-footer">
|
||
<div class="sidebar-user" id="sidebar-user">
|
||
<div class="sidebar-user-avatar" id="sidebar-avatar"></div>
|
||
<div class="sidebar-user-info">
|
||
<div class="sidebar-user-name" id="sidebar-name"></div>
|
||
<div class="sidebar-user-role" id="sidebar-role"></div>
|
||
</div>
|
||
<button class="sidebar-logout" id="sidebar-logout-btn" title="Abmelden" aria-label="Abmelden">
|
||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 17l5-5-5-5M15 12H3M15 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4"/></svg>
|
||
</button>
|
||
</div>
|
||
<button id="theme-toggle" class="theme-toggle" title="Darstellung wechseln" aria-label="Darstellung wechseln">
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.42 1.42M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.42-1.42M17.66 6.34l1.41-1.41"/></svg>
|
||
<span>Darstellung</span>
|
||
</button>
|
||
</div>
|
||
</aside>
|
||
|
||
<div class="sidebar-overlay" id="sidebar-overlay"></div>
|
||
<div class="main-wrapper">
|
||
<header class="topbar" id="topbar">
|
||
<div class="topbar-context">
|
||
<button class="sidebar-toggle" id="sidebar-toggle" type="button" aria-label="Menü" aria-controls="sidebar" aria-expanded="false">
|
||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
|
||
</button>
|
||
<div class="topbar-context-icon" aria-hidden="true">
|
||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 4 7v10l8 4 8-4V7Z"/><path d="m4 7 8 4 8-4M12 11v10"/></svg>
|
||
</div>
|
||
<div class="topbar-heading">
|
||
<h1 class="topbar-title" id="topbar-title">Dashboard</h1>
|
||
<span class="topbar-kicker" id="topbar-kicker">Analytics</span>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="command-search" id="topbar-search-btn" type="button" aria-label="Globale Suche öffnen">
|
||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg>
|
||
<span>Suche oder Befehl eingeben…</span>
|
||
<kbd>⌘ K</kbd>
|
||
</button>
|
||
|
||
<div class="topbar-actions">
|
||
<button class="topbar-btn primary" id="topbar-new-btn">
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="M12 5v14M5 12h14"/></svg>
|
||
<span>Neuer Artikel</span>
|
||
</button>
|
||
<button class="topbar-icon-btn" type="button" aria-label="Benachrichtigungen">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9"/><path d="M10 21h4"/></svg>
|
||
<span class="topbar-dot" aria-hidden="true"></span>
|
||
</button>
|
||
<div class="topbar-avatar" id="topbar-avatar" aria-hidden="true">V</div>
|
||
</div>
|
||
</header>
|
||
<div class="connection-banner hidden" id="connection-banner" role="status" aria-live="polite">
|
||
<span class="connection-banner-dot" aria-hidden="true"></span>
|
||
<strong id="connection-banner-title">Vendoo ist nicht erreichbar</strong>
|
||
<span id="connection-banner-detail">Verbindung wird automatisch erneut geprüft.</span>
|
||
<button type="button" id="connection-retry-btn">Erneut prüfen</button>
|
||
</div>
|
||
|
||
<main>
|
||
<!-- ANALYTICS DASHBOARD -->
|
||
<section id="dashboard" class="tab-content active dashboard-page">
|
||
<header class="page-heading dashboard-heading">
|
||
<div>
|
||
<p class="eyebrow">Business Intelligence</p>
|
||
<h2>Dashboard</h2>
|
||
<p>Dein Überblick über Umsatz, Artikel, Lagerbestand und Performance.</p>
|
||
</div>
|
||
<div class="dashboard-controls">
|
||
<select id="dashboard-period" aria-label="Zeitraum">
|
||
<option value="7">Letzte 7 Tage</option>
|
||
<option value="30" selected>Letzte 30 Tage</option>
|
||
<option value="90">Letzte 90 Tage</option>
|
||
</select>
|
||
<button id="dashboard-refresh" class="vd-button" type="button">Aktualisieren</button>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="dashboard-layout">
|
||
<div class="dashboard-main">
|
||
<section class="dashboard-kpis" aria-label="Kennzahlen">
|
||
<article class="dashboard-kpi"><span class="dashboard-kpi-icon">€</span><div><small>Umsatz heute</small><strong id="dash-revenue-today">—</strong><em>Aktueller Tageswert</em></div><svg id="spark-revenue" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
|
||
<article class="dashboard-kpi"><span class="dashboard-kpi-icon">✓</span><div><small>Verkäufe 7 Tage</small><strong id="dash-sales-week">—</strong><em>Abgeschlossene Verkäufe</em></div><svg id="spark-sales" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
|
||
<article class="dashboard-kpi"><span class="dashboard-kpi-icon">□</span><div><small>Aktive Artikel</small><strong id="dash-active-listings">—</strong><em>Aktuell im Bestand</em></div><svg id="spark-active" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
|
||
<article class="dashboard-kpi"><span class="dashboard-kpi-icon">◫</span><div><small>Entwürfe</small><strong id="dash-drafts">—</strong><em>Noch nicht veröffentlicht</em></div><svg id="spark-drafts" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
|
||
<article class="dashboard-kpi"><span class="dashboard-kpi-icon">▤</span><div><small>Lagerwert</small><strong id="dash-inventory-value">—</strong><em>Geschätzter Gesamtwert</em></div><svg id="spark-inventory" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
|
||
<article class="dashboard-kpi"><span class="dashboard-kpi-icon">◎</span><div><small>Publish-Erfolgsquote</small><strong id="dash-publish-rate">—</strong><em>Erfolgreiche Versuche</em></div><svg id="spark-publish" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
|
||
</section>
|
||
|
||
<section class="dashboard-chart-grid">
|
||
<article class="dashboard-card dashboard-line-card">
|
||
<header><div><span>Umsatzentwicklung</span><strong id="dash-period-revenue">—</strong></div><small id="dash-period-label">Letzte 30 Tage</small></header>
|
||
<div id="dashboard-line-chart" class="dashboard-chart" aria-label="Umsatzentwicklung"></div>
|
||
</article>
|
||
<article class="dashboard-card">
|
||
<header><div><span>Umsatz nach Plattform</span><strong id="dash-platform-total">—</strong></div></header>
|
||
<div id="dashboard-platform-chart" class="dashboard-bar-chart" aria-label="Umsatz nach Plattform"></div>
|
||
</article>
|
||
<article class="dashboard-card">
|
||
<header><div><span>Umsatz nach Kategorie</span><strong>Verteilung</strong></div></header>
|
||
<div id="dashboard-category-chart" class="dashboard-category-chart" aria-label="Umsatz nach Kategorie"></div>
|
||
</article>
|
||
</section>
|
||
|
||
<section class="dashboard-card dashboard-focus-card">
|
||
<header><div><span>Heute im Fokus</span><strong>Direkt handlungsrelevant</strong></div></header>
|
||
<div id="dashboard-focus" class="dashboard-focus-grid"></div>
|
||
</section>
|
||
|
||
<section class="dashboard-lower-grid">
|
||
<article class="dashboard-card dashboard-sellers-card">
|
||
<header><div><span>Top Seller / Bestseller</span><strong>Nach Umsatz</strong></div><button class="text-action" type="button" data-tab-target="history">Alle anzeigen</button></header>
|
||
<div class="dashboard-table-wrap"><table class="dashboard-table"><thead><tr><th>Artikel</th><th>SKU</th><th>Plattform</th><th>Umsatz</th><th>Verkäufe</th><th>Status</th></tr></thead><tbody id="dashboard-top-sellers"></tbody></table></div>
|
||
</article>
|
||
<article class="dashboard-card dashboard-actions-card">
|
||
<header><div><span>Schnellaktionen</span><strong>Häufige Aufgaben</strong></div></header>
|
||
<div class="dashboard-actions">
|
||
<button type="button" class="primary" data-dashboard-action="new">+ Neuer Artikel</button>
|
||
<button type="button" data-dashboard-action="qr">QR-Upload starten</button>
|
||
<button type="button" data-dashboard-action="photos">Fotos als ZIP laden</button>
|
||
<button type="button" data-dashboard-action="publish">Bulk Publish</button>
|
||
<button type="button" data-dashboard-action="template">Vorlage anwenden</button>
|
||
</div>
|
||
</article>
|
||
</section>
|
||
</div>
|
||
|
||
<aside class="dashboard-rail">
|
||
<section class="dashboard-card dashboard-quality-card">
|
||
<header><div><span>AI & Qualität</span><strong>Listing-Qualität</strong></div></header>
|
||
<div class="dashboard-quality"><div id="dashboard-quality-ring" class="confidence-ring"><span id="dashboard-quality-value">—</span></div><div><strong id="dashboard-quality-label">Wird berechnet</strong><p>Durchschnittliche Vollständigkeit deiner Artikel.</p></div></div>
|
||
<button class="vd-button full" type="button" data-tab-target="history">Analyse öffnen</button>
|
||
</section>
|
||
<section class="dashboard-card"><header><div><span>Aktivität</span><strong>Letzte Ereignisse</strong></div></header><div id="dashboard-activity" class="dashboard-feed"></div></section>
|
||
<section class="dashboard-card"><header><div><span>Benachrichtigungen</span><strong>Benötigt Aufmerksamkeit</strong></div></header><div id="dashboard-notifications" class="dashboard-feed"></div></section>
|
||
<section class="dashboard-card dashboard-system"><header><div><span>Systemstatus</span><strong id="dashboard-system-state">Wird geprüft</strong></div></header><p id="dashboard-system-copy">Verbindungen und Warteschlangen werden geladen.</p><button class="vd-button full" type="button" data-tab-target="settings">Verbindungen prüfen</button></section>
|
||
</aside>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- STUDIO FLOW / HEUTE -->
|
||
<section id="today" class="tab-content studio-flow-page studio-flow-v2">
|
||
<header class="page-heading studio-heading">
|
||
<div>
|
||
<p class="eyebrow">Commerce Workbench</p>
|
||
<h2>Studio Flow</h2>
|
||
<p>Deine nächsten Schritte – klar priorisiert und ohne Kartenüberladung.</p>
|
||
</div>
|
||
</header>
|
||
|
||
<section class="today-summary-grid" aria-label="Studio-Flow-Status">
|
||
<button type="button" data-today-filter="ready"><span>✓</span><strong id="today-count-ready">0</strong><small>Bereit</small><em>Prüfbereit</em></button>
|
||
<button type="button" data-today-filter="scheduled"><span>◷</span><strong id="today-count-scheduled">0</strong><small>Geplant</small><em>In Warteschlange</em></button>
|
||
<button type="button" data-today-filter="published"><span>↗</span><strong id="today-count-published">0</strong><small>Veröffentlicht</small><em>Aktuell live</em></button>
|
||
<button type="button" data-today-filter="sold"><span>◇</span><strong id="today-count-sold">0</strong><small>Verkauft</small><em>Abgeschlossen</em></button>
|
||
<button type="button" data-today-filter="attention"><span>!</span><strong id="today-count-attention">0</strong><small>Benötigt</small><em>Aufmerksamkeit</em></button>
|
||
</section>
|
||
|
||
<div class="today-filterbar">
|
||
<div class="today-filter-tabs" role="tablist">
|
||
<button class="active" type="button" data-today-filter="all">Alle</button>
|
||
<button type="button" data-today-filter="ready">Bereit</button>
|
||
<button type="button" data-today-filter="scheduled">Geplant</button>
|
||
<button type="button" data-today-filter="attention">Probleme</button>
|
||
<button type="button" data-today-filter="sold">Verkauft</button>
|
||
</div>
|
||
<select id="today-sort" aria-label="Sortierung"><option value="priority">Sortieren: Priorität</option><option value="newest">Neueste zuerst</option><option value="price">Preis absteigend</option></select>
|
||
</div>
|
||
|
||
<div class="studio-layout studio-layout-v2">
|
||
<div class="studio-workspace">
|
||
<section class="work-panel today-ready-panel">
|
||
<div class="work-panel-header"><div><h3>Bereit für den nächsten Schritt</h3><span class="panel-count" id="today-ready-total">0</span></div><button class="text-action" type="button" data-tab-target="history">Alle Bereit anzeigen</button></div>
|
||
<div id="today-ready-grid" class="today-ready-grid"></div>
|
||
</section>
|
||
|
||
<div class="today-middle-grid">
|
||
<section class="work-panel today-scheduled-panel">
|
||
<div class="work-panel-header"><div><h3>Geplant & in Warteschlange</h3><span class="panel-count" id="today-scheduled-total">0</span></div><button class="text-action" type="button" data-tab-target="publish">Alle Planungen</button></div>
|
||
<div class="today-table-wrap"><table class="today-table"><thead><tr><th>Artikel</th><th>Plattform</th><th>Geplant am</th><th>Status</th><th>Aktion</th></tr></thead><tbody id="today-scheduled-list"></tbody></table></div>
|
||
</section>
|
||
<section class="work-panel attention-panel">
|
||
<div class="work-panel-header"><div><span class="panel-icon panel-icon-warning">!</span><h3>Benötigt Aufmerksamkeit</h3></div><span class="panel-count" id="attention-count">0</span></div>
|
||
<div id="studio-attention" class="attention-list compact"></div>
|
||
<button class="text-action today-panel-footer" type="button" data-today-filter="attention">Alle Probleme anzeigen</button>
|
||
</section>
|
||
</div>
|
||
|
||
<section class="work-panel activity-panel today-activity-panel">
|
||
<div class="work-panel-header"><div><h3>Aktivität</h3></div><button class="text-action" type="button" data-tab-target="history">Alle Aktivitäten</button></div>
|
||
<div class="today-activity-grid"><div><h4>Letzte Aktivitäten</h4><div id="studio-activity" class="activity-list"></div></div><div><h4>Abgeschlossene Aktionen</h4><div id="studio-completed" class="activity-list"></div></div></div>
|
||
</section>
|
||
</div>
|
||
|
||
<aside class="studio-inspector" id="studio-inspector" aria-label="Artikelkontext">
|
||
<div class="inspector-empty" id="studio-inspector-empty"><div class="inspector-empty-mark">□</div><h3>Artikel auswählen</h3><p>Wähle ein Listing, um Details und nächste Aktionen zu sehen.</p></div>
|
||
<div class="inspector-content hidden" id="studio-inspector-content"></div>
|
||
</aside>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- GENERATOR -->
|
||
<section id="generator" class="tab-content generator-studio-page">
|
||
<header class="page-heading generator-heading">
|
||
<div>
|
||
<p class="eyebrow">Listing Studio</p>
|
||
<h2>Neuer Artikel</h2>
|
||
<p>Fotos erfassen, AI gezielt steuern und das Ergebnis ohne Kontextwechsel fertigstellen.</p>
|
||
</div>
|
||
<div class="generator-heading-actions">
|
||
<div class="generator-stepper" aria-label="Arbeitsfortschritt">
|
||
<span class="generator-step is-active" id="generator-step-photos"><b>1</b> Fotos</span>
|
||
<span class="generator-step" id="generator-step-ai"><b>2</b> AI</span>
|
||
<span class="generator-step" id="generator-step-result"><b>3</b> Prüfen</span>
|
||
</div>
|
||
<button id="reset-generator-btn" class="vd-button secondary" type="button">
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M3 12a9 9 0 1 0 3-6.7L3 8"/><path d="M3 3v5h5"/></svg>
|
||
Zurücksetzen
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="generator-studio-layout">
|
||
<section class="generator-panel media-workbench" aria-labelledby="generator-media-title">
|
||
<div class="generator-panel-header">
|
||
<div>
|
||
<span class="generator-panel-index">01</span>
|
||
<div>
|
||
<h3 id="generator-media-title">Fotos & Medien</h3>
|
||
<p>Das erste Bild wird als Cover verwendet.</p>
|
||
</div>
|
||
</div>
|
||
<span id="generator-photo-count" class="generator-count">0 / 10</span>
|
||
</div>
|
||
|
||
<div id="generator-photo-stage" class="generator-photo-stage">
|
||
<div id="generator-photo-empty" class="generator-photo-empty">
|
||
<div class="generator-photo-empty-mark">
|
||
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="9" cy="10" r="2"/><path d="m21 15-5-5L5 20"/></svg>
|
||
</div>
|
||
<strong>Noch keine Produktfotos</strong>
|
||
<span>Gute Bilder erhöhen Erkennungsqualität und Verkaufschance.</span>
|
||
</div>
|
||
<img id="generator-cover" class="generator-cover hidden" alt="Coverfoto des Artikels">
|
||
<span id="generator-cover-badge" class="generator-cover-badge hidden">Cover</span>
|
||
</div>
|
||
|
||
<div id="dropzone" class="dropzone generator-dropzone">
|
||
<input type="file" id="file-input" multiple accept="image/*" hidden>
|
||
<div class="generator-dropzone-icon">
|
||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 16V4"/><path d="m7 9 5-5 5 5"/><path d="M20 15v4a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-4"/></svg>
|
||
</div>
|
||
<p><strong>Fotos hierher ziehen</strong><br>oder klicken zum Auswählen</p>
|
||
<small>JPG, PNG, WEBP oder GIF · maximal 10 Bilder</small>
|
||
</div>
|
||
|
||
<button id="generator-mobile-upload" class="mobile-upload-trigger" type="button">
|
||
<span class="mobile-upload-trigger-icon">⌁</span>
|
||
<span><strong>Mit dem Handy fotografieren</strong><small>QR-Code scannen und Bilder direkt übertragen</small></span>
|
||
<b>QR</b>
|
||
</button>
|
||
|
||
<div id="photo-preview" class="photo-preview generator-photo-strip" aria-label="Hochgeladene Fotos"></div>
|
||
|
||
<div id="image-tools" class="image-tools generator-image-tools hidden">
|
||
<button id="advanced-image-editor-btn" class="small-btn advanced-editor-entry" type="button">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/><path d="m15 5 3 3"/></svg>
|
||
Advanced Editor öffnen
|
||
</button>
|
||
<button id="generator-download-photos" class="small-btn" type="button">Fotos herunterladen</button>
|
||
</div>
|
||
|
||
|
||
<section id="generator-ai-model-card" class="ai-model-card generator-ai-model-card">
|
||
<div class="ai-model-card-head">
|
||
<div>
|
||
<span class="generator-panel-index">AI</span>
|
||
<div>
|
||
<h4>Produktbild-Werkzeuge</h4>
|
||
<p>Erzeuge Ghost-Mannequin- oder Flatlay-Varianten aus dem vorhandenen Produktfoto. Freie Prompt-Bilder findest du im separaten FLUX Studio.</p>
|
||
</div>
|
||
</div>
|
||
<span id="generator-ai-model-badge" class="generator-beta">Safe</span>
|
||
</div>
|
||
<div class="ai-model-controls">
|
||
<label>Look
|
||
<select id="generator-ai-model-preset" class="model-select">
|
||
<option value="mixed">Mix</option>
|
||
<option value="studio">Studio</option>
|
||
<option value="indoor">Indoor</option>
|
||
<option value="outdoor">Outdoor</option>
|
||
</select>
|
||
</label>
|
||
<label>Modus
|
||
<select id="generator-ai-model-mode" class="model-select">
|
||
<option value="ghost_mannequin">Ghost Mannequin</option>
|
||
<option value="flatlay" selected>Flatlay</option>
|
||
</select>
|
||
</label>
|
||
<label>Varianten
|
||
<select id="generator-ai-model-variants" class="model-select">
|
||
<option value="1" selected>1 Bild</option>
|
||
<option value="2">2 Bilder</option>
|
||
<option value="3">3 Bilder</option>
|
||
</select>
|
||
</label>
|
||
<button id="generator-ai-model-prompt-btn" class="small-btn ghost" type="button">Prompt…</button>
|
||
<button id="generator-ai-model-btn" class="small-btn" type="button">Bild erzeugen</button>
|
||
</div>
|
||
<div id="generator-ai-model-status" class="ai-model-status">Wartet auf Produktfotos.</div>
|
||
<div id="generator-ai-model-grid" class="ai-model-grid hidden"></div>
|
||
</section>
|
||
|
||
<div class="generator-photo-quality">
|
||
<div class="generator-photo-quality-head">
|
||
<div>
|
||
<span class="quality-spark">✦</span>
|
||
<strong>Foto-Check</strong>
|
||
</div>
|
||
<span id="generator-photo-quality-score">0 / 5</span>
|
||
</div>
|
||
<ul id="generator-photo-tips">
|
||
<li data-photo-tip="count"><span></span>Mindestens drei Perspektiven</li>
|
||
<li data-photo-tip="cover"><span></span>Klares Coverfoto</li>
|
||
<li data-photo-tip="details"><span></span>Detail- und Etikettfoto</li>
|
||
<li data-photo-tip="background"><span></span>Ruhiger Hintergrund empfohlen</li>
|
||
<li data-photo-tip="order"><span></span>Reihenfolge per Drag & Drop</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="generator-panel generator-config-panel" aria-labelledby="generator-ai-title">
|
||
<div class="generator-panel-header">
|
||
<div>
|
||
<span class="generator-panel-index">02</span>
|
||
<div>
|
||
<h3 id="generator-ai-title">AI-Generator</h3>
|
||
<p>Lege Ziel, Sprache und Tonalität fest.</p>
|
||
</div>
|
||
</div>
|
||
<span class="generator-beta">Assistiert</span>
|
||
</div>
|
||
|
||
<div class="generator-config-stack">
|
||
<div class="generator-config-card">
|
||
<div class="generator-config-copy">
|
||
<label>Plattform</label>
|
||
<span>Optimiert Aufbau, Ton und Pflichtfelder.</span>
|
||
</div>
|
||
<div id="platform-buttons" class="button-group generator-choice-group"></div>
|
||
</div>
|
||
|
||
<div class="generator-config-card">
|
||
<div class="generator-config-copy">
|
||
<label>AI Provider</label>
|
||
<span>Wähle den bevorzugten Analyse-Dienst.</span>
|
||
</div>
|
||
<div id="provider-buttons" class="button-group generator-choice-group"></div>
|
||
</div>
|
||
|
||
<div id="model-select-wrap" class="generator-config-card hidden">
|
||
<div class="generator-config-copy">
|
||
<label for="model-select">Modell</label>
|
||
<span>Steuert Qualität, Geschwindigkeit und Kosten.</span>
|
||
</div>
|
||
<select id="model-select" class="model-select"></select>
|
||
</div>
|
||
|
||
<div class="generator-config-pair">
|
||
<div class="generator-config-card compact">
|
||
<div class="generator-config-copy">
|
||
<label for="language-select">Sprache</label>
|
||
</div>
|
||
<select id="language-select" class="model-select">
|
||
<option value="de">Deutsch</option>
|
||
<option value="en">English</option>
|
||
<option value="fr">Français</option>
|
||
<option value="nl">Nederlands</option>
|
||
<option value="pl">Polski</option>
|
||
<option value="es">Español</option>
|
||
<option value="it">Italiano</option>
|
||
<option value="pt">Português</option>
|
||
</select>
|
||
</div>
|
||
<div class="generator-config-card compact">
|
||
<div class="generator-config-copy">
|
||
<label for="variants-select">Varianten</label>
|
||
</div>
|
||
<select id="variants-select" class="model-select">
|
||
<option value="1">1 Variante</option>
|
||
<option value="2">2 Varianten</option>
|
||
<option value="3">3 Varianten</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="generator-config-card">
|
||
<div class="generator-config-copy">
|
||
<label for="template-select">Vorlage</label>
|
||
<span>Übernimmt Plattform, Sprache, Hinweise und Standard-Tags.</span>
|
||
</div>
|
||
<select id="template-select" class="model-select">
|
||
<option value="">Keine Vorlage</option>
|
||
</select>
|
||
<div id="generator-template-tags" class="generator-template-tags hidden"></div>
|
||
</div>
|
||
|
||
<div class="generator-notes-card">
|
||
<div class="generator-notes-head">
|
||
<div>
|
||
<label for="generator-seller-notes">Verkäufer-Notizen</label>
|
||
<span>Nur relevante Besonderheiten für diesen Artikel.</span>
|
||
</div>
|
||
<span id="generator-notes-count">0 / 500</span>
|
||
</div>
|
||
<textarea id="generator-seller-notes" maxlength="500" rows="5" placeholder="Zum Beispiel: leichte Gebrauchsspur am Ärmel, Originalverpackung vorhanden, Nichtraucherhaushalt …"></textarea>
|
||
<div class="generator-tone-row">
|
||
<span>Ton: freundlich & präzise</span>
|
||
<span>Detailgrad: hoch</span>
|
||
<span>Keine Übertreibungen</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="loading" class="loading generator-loading hidden" aria-live="polite">
|
||
<div class="spinner"></div>
|
||
<p><strong>AI analysiert deine Fotos</strong><br><span id="generator-loading-copy">Produkt, Zustand und Marktplatzdaten werden vorbereitet.</span></p>
|
||
</div>
|
||
|
||
<div class="generator-action-zone">
|
||
<div class="generator-readiness">
|
||
<span id="generator-readiness-dot"></span>
|
||
<div>
|
||
<strong id="generator-readiness-title">Fotos fehlen</strong>
|
||
<small id="generator-readiness-copy">Lade mindestens ein Produktfoto hoch.</small>
|
||
</div>
|
||
</div>
|
||
<button id="generate-btn" class="primary-btn generator-primary-action" disabled>
|
||
<span>✦</span>
|
||
Artikel generieren
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<aside class="generator-panel generator-preview-panel" aria-labelledby="generator-preview-title">
|
||
<div class="generator-panel-header generator-preview-header">
|
||
<div>
|
||
<span class="generator-panel-index">03</span>
|
||
<div>
|
||
<h3 id="generator-preview-title">Vorschau & Bearbeiten</h3>
|
||
<p>Prüfe jeden Vorschlag vor dem Speichern.</p>
|
||
</div>
|
||
</div>
|
||
<span id="generator-preview-status" class="generator-preview-status">Wartet</span>
|
||
</div>
|
||
|
||
<div id="generator-preview-empty" class="generator-preview-empty">
|
||
<div class="generator-preview-empty-mark">VD</div>
|
||
<h3>Dein Listing entsteht hier</h3>
|
||
<p>Sobald Fotos hochgeladen und analysiert wurden, kannst du Titel, Text, Attribute und Preis direkt bearbeiten.</p>
|
||
<div class="generator-preview-skeleton" aria-hidden="true">
|
||
<span></span><span></span><span></span><span></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="variants-section" class="hidden generator-variant-wrap">
|
||
<div class="generator-section-label">Textvarianten</div>
|
||
<div id="variant-tabs" class="variant-tabs"></div>
|
||
</div>
|
||
|
||
<div id="result-section" class="result-section generator-result hidden">
|
||
<div class="generator-result-score">
|
||
<div>
|
||
<span>Listing-Qualität</span>
|
||
<strong id="generator-quality-label">Sehr gut</strong>
|
||
</div>
|
||
<div class="generator-quality-ring" id="generator-quality-ring" style="--quality: 0%"><span id="generator-quality-score">0%</span></div>
|
||
</div>
|
||
|
||
<div class="result-field">
|
||
<div class="field-header">
|
||
<label for="result-title">Titel</label>
|
||
<div><span id="result-title-count" class="field-count">0 / 80</span><button class="copy-btn" data-target="result-title">Kopieren</button></div>
|
||
</div>
|
||
<input type="text" id="result-title" class="result-input" maxlength="120">
|
||
</div>
|
||
|
||
<div class="result-field">
|
||
<div class="field-header">
|
||
<label>Beschreibung</label>
|
||
<div><span id="result-description-count" class="field-count">0 Zeichen</span><button class="copy-btn" id="copy-desc-text">Text kopieren</button></div>
|
||
</div>
|
||
<div id="result-description-editor"></div>
|
||
</div>
|
||
|
||
<div class="result-field">
|
||
<div class="field-header">
|
||
<label id="tags-label" for="result-tags">Tags</label>
|
||
<div><span id="result-tags-count" class="field-count">0</span><button class="copy-btn" data-target="result-tags">Kopieren</button></div>
|
||
</div>
|
||
<input type="text" id="result-tags" class="result-input" placeholder="Tags durch Komma trennen">
|
||
</div>
|
||
|
||
<div id="meta-section" class="meta-section generator-meta-section hidden">
|
||
<div class="generator-section-label">Erkannte Eigenschaften</div>
|
||
<div class="meta-grid-edit">
|
||
<div class="meta-edit-item"><label class="meta-label" for="meta-sku">Artikelnr. (SKU)</label><input type="text" id="meta-sku" class="meta-input" readonly></div>
|
||
<div class="meta-edit-item"><label class="meta-label" for="meta-brand">Marke</label><input type="text" id="meta-brand" class="meta-input"></div>
|
||
<div class="meta-edit-item meta-category-item"><label class="meta-label">Kategorie</label><div id="meta-category-picker" class="cat-picker"></div></div>
|
||
<div class="meta-edit-item"><label class="meta-label" for="meta-size">Größe</label><input type="text" id="meta-size" class="meta-input"></div>
|
||
<div class="meta-edit-item"><label class="meta-label" for="meta-color">Farbe</label><input type="text" id="meta-color" class="meta-input"></div>
|
||
<div class="meta-edit-item"><label class="meta-label" for="meta-condition">Zustand</label><input type="text" id="meta-condition" class="meta-input"></div>
|
||
<div class="meta-edit-item"><label class="meta-label" for="meta-price">Preisvorschlag (€)</label><input type="number" id="meta-price" class="meta-input" step="0.5" min="0"></div>
|
||
<div class="meta-edit-item"><label class="meta-label" for="meta-storage-location">Lagerort</label><input type="text" id="meta-storage-location" class="meta-input" placeholder="z. B. Regal A2"></div>
|
||
</div>
|
||
<div id="fee-info" class="fee-info hidden"></div>
|
||
</div>
|
||
|
||
<details class="generator-html-details" id="html-preview-wrap" open>
|
||
<summary>Plattformvorschau <span>HTML-Code jederzeit umschaltbar</span></summary>
|
||
<div class="html-view-toolbar">
|
||
<div class="html-view-tabs" role="tablist" aria-label="Vorschauansicht">
|
||
<button class="html-view-tab is-active" type="button" data-html-scope="generator" data-html-view="preview">Plattformvorschau</button>
|
||
<button class="html-view-tab" type="button" data-html-scope="generator" data-html-view="code">HTML-Code</button>
|
||
</div>
|
||
<div class="generator-html-actions">
|
||
<button class="copy-btn" id="copy-desc-html" type="button">Editor-HTML kopieren</button>
|
||
<button class="copy-btn" id="copy-platform-html" type="button">Plattform-HTML kopieren</button>
|
||
<button class="copy-btn" id="format-html-source" type="button">Code bereinigen</button>
|
||
</div>
|
||
</div>
|
||
<div class="html-switch-stage">
|
||
<div id="generator-preview-view" class="html-switch-view is-active" data-html-panel="preview">
|
||
<div class="generator-html-pane-head"><strong>Plattformvorschau</strong><span id="generator-html-sync-status">Synchron</span></div>
|
||
<iframe id="html-preview" class="html-preview html-preview-frame" sandbox title="Plattformvorschau"></iframe>
|
||
</div>
|
||
<div id="generator-code-view" class="html-switch-view" data-html-panel="code">
|
||
<div class="generator-html-pane-head"><strong>HTML-Code</strong><span>Direkt editierbar · live synchronisiert</span></div>
|
||
<textarea id="html-source" class="result-textarea html-source" rows="14" spellcheck="false" aria-label="HTML-Code der Beschreibung"></textarea>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<div class="result-actions generator-result-actions">
|
||
<button id="copy-all-btn" class="secondary-btn">Alles kopieren</button>
|
||
<button id="save-btn" class="primary-btn">Speichern & Hinzufügen</button>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<!-- LISTINGS / HISTORIE -->
|
||
<section id="history" class="tab-content listings-page">
|
||
<header class="page-heading listings-heading">
|
||
<div>
|
||
<p class="eyebrow">Listing-Verwaltung</p>
|
||
<h2>Artikel</h2>
|
||
<p>Überblick über alle erstellten, geplanten und veröffentlichten Artikel.</p>
|
||
</div>
|
||
<div class="listings-heading-actions">
|
||
<div class="history-export-wrap">
|
||
<button id="history-export-toggle" class="vd-button secondary" type="button" aria-expanded="false">
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="m7 10 5 5 5-5"/><path d="M5 21h14"/></svg>
|
||
Exportieren
|
||
<span aria-hidden="true">⌄</span>
|
||
</button>
|
||
<div id="history-export-menu" class="history-popover history-export-menu hidden">
|
||
<button id="export-csv-btn" type="button">CSV exportieren</button>
|
||
<button id="export-json-btn" type="button">JSON exportieren</button>
|
||
</div>
|
||
</div>
|
||
<div class="history-columns-wrap">
|
||
<button id="history-columns-btn" class="vd-button secondary" type="button" aria-expanded="false">
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 5h16M4 12h16M4 19h16"/><path d="M8 3v4M15 10v4M11 17v4"/></svg>
|
||
Spalten anpassen
|
||
</button>
|
||
<div id="history-columns-panel" class="history-popover history-columns-panel hidden">
|
||
<strong>Sichtbare Spalten</strong>
|
||
<label><input type="checkbox" data-history-column="platform" checked> Plattform</label>
|
||
<label><input type="checkbox" data-history-column="provider" checked> AI-Provider</label>
|
||
<label><input type="checkbox" data-history-column="price" checked> Preis</label>
|
||
<label><input type="checkbox" data-history-column="status" checked> Status</label>
|
||
<label><input type="checkbox" data-history-column="location" checked> Lagerort</label>
|
||
<label><input type="checkbox" data-history-column="published" checked> Veröffentlicht</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="history-filterbar" aria-label="Listing-Filter">
|
||
<label class="history-search-field">
|
||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg>
|
||
<input type="search" id="search-input" placeholder="Titel, SKU, Marke oder Beschreibung">
|
||
</label>
|
||
<label class="history-filter-field">
|
||
<span>Plattform</span>
|
||
<select id="filter-platform"><option value="">Alle</option></select>
|
||
</label>
|
||
<label class="history-filter-field">
|
||
<span>Status</span>
|
||
<select id="filter-status">
|
||
<option value="">Alle</option>
|
||
<option value="active">Aktiv</option>
|
||
<option value="sold">Verkauft</option>
|
||
<option value="reserved">Reserviert</option>
|
||
</select>
|
||
</label>
|
||
<label class="history-filter-field history-period-field">
|
||
<span>Zeitraum</span>
|
||
<select id="history-period">
|
||
<option value="90">Letzte 90 Tage</option>
|
||
<option value="30">Letzte 30 Tage</option>
|
||
<option value="7">Letzte 7 Tage</option>
|
||
<option value="year">Dieses Jahr</option>
|
||
<option value="all">Gesamter Zeitraum</option>
|
||
<option value="custom">Benutzerdefiniert</option>
|
||
</select>
|
||
</label>
|
||
<div id="history-custom-dates" class="history-custom-dates hidden">
|
||
<label><span>Von</span><input type="date" id="filter-date-from" title="Von Datum"></label>
|
||
<label><span>Bis</span><input type="date" id="filter-date-to" title="Bis Datum"></label>
|
||
</div>
|
||
<button id="history-reset-filters" class="vd-button ghost" type="button">
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v6h6"/></svg>
|
||
Filter zurücksetzen
|
||
</button>
|
||
</div>
|
||
|
||
<div class="history-table-shell">
|
||
<div id="history-batch-bar" class="history-batch-bar">
|
||
<label class="history-select-all-wrap">
|
||
<input type="checkbox" id="history-select-all">
|
||
<span id="history-selected-count">0 ausgewählt</span>
|
||
</label>
|
||
<div class="history-batch-actions">
|
||
<button id="history-publish-selected" class="vd-button compact" disabled>
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>
|
||
Veröffentlichen
|
||
</button>
|
||
<button id="history-edit-selected" class="vd-button compact" disabled>
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
|
||
Nachbearbeiten
|
||
</button>
|
||
<button id="history-price-selected" class="vd-button compact" disabled>Preis aktualisieren</button>
|
||
<button id="history-bulk-status" class="vd-button compact" disabled>Status ändern</button>
|
||
<button id="history-duplicate-selected" class="vd-button compact" disabled>Duplizieren</button>
|
||
<button id="history-print-labels" class="vd-button compact" disabled>Etiketten</button>
|
||
<button id="history-delete-selected" class="vd-button compact danger" disabled>Löschen</button>
|
||
</div>
|
||
<button id="history-clear-selection" class="history-clear-selection hidden" type="button">Auswahl aufheben</button>
|
||
</div>
|
||
|
||
<div id="history-table" class="history-table" role="table" aria-label="Artikel">
|
||
<div class="history-table-head" role="row">
|
||
<div class="history-cell history-cell-select" role="columnheader"><span class="sr-only">Auswahl</span></div>
|
||
<div class="history-cell history-cell-article" role="columnheader">Artikel</div>
|
||
<div class="history-cell history-cell-platform" data-column="platform" role="columnheader">Plattform</div>
|
||
<div class="history-cell history-cell-provider" data-column="provider" role="columnheader">AI-Provider</div>
|
||
<div class="history-cell history-cell-price" data-column="price" role="columnheader">Preis</div>
|
||
<div class="history-cell history-cell-status" data-column="status" role="columnheader">Status</div>
|
||
<div class="history-cell history-cell-location" data-column="location" role="columnheader">Lagerort</div>
|
||
<div class="history-cell history-cell-published" data-column="published" role="columnheader">Veröffentlicht</div>
|
||
<div class="history-cell history-cell-menu" role="columnheader"><span class="sr-only">Aktionen</span></div>
|
||
</div>
|
||
<div id="history-list" class="history-list" role="rowgroup"></div>
|
||
</div>
|
||
|
||
<div class="history-table-footer" id="history-pagination-bottom">
|
||
<label class="history-page-size">
|
||
<span>Zeige</span>
|
||
<select id="history-page-size-select">
|
||
<option value="10">10</option>
|
||
<option value="20">20</option>
|
||
<option value="50">50</option>
|
||
<option value="0">Alle</option>
|
||
</select>
|
||
<span id="history-total-info">von 0 Einträgen</span>
|
||
</label>
|
||
<div class="pagination-nav history-pagination-nav">
|
||
<button class="page-nav-btn" id="history-prev-bottom" disabled aria-label="Vorherige Seite">‹</button>
|
||
<div id="history-page-buttons" class="history-page-buttons"></div>
|
||
<button class="page-nav-btn" id="history-next-bottom" disabled aria-label="Nächste Seite">›</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="pagination-bar hidden" id="history-pagination-top">
|
||
<div class="pagination-nav">
|
||
<button class="page-nav-btn" id="history-prev" disabled>Zurück</button>
|
||
<span class="page-info" id="history-page-info">Seite 1 von 1</span>
|
||
<button class="page-nav-btn" id="history-next" disabled>Weiter</button>
|
||
</div>
|
||
</div>
|
||
<span class="page-info hidden" id="history-page-info-bottom">Seite 1 von 1</span>
|
||
<button id="history-delete-all" class="hidden" type="button">Alle löschen</button>
|
||
|
||
<div id="history-detail" class="history-detail hidden">
|
||
<button id="back-to-list" class="secondary-btn">Zurück zur Übersicht</button>
|
||
<div id="detail-content"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VORLAGEN -->
|
||
<section id="templates" class="tab-content">
|
||
<div class="templates-header">
|
||
<h2>Listing-Vorlagen</h2>
|
||
<button id="add-template-btn" class="primary-btn">Neue Vorlage</button>
|
||
</div>
|
||
<div id="template-list" class="template-list"></div>
|
||
<div id="template-form" class="template-form hidden">
|
||
<h3 id="template-form-title">Neue Vorlage</h3>
|
||
<div class="setting-group">
|
||
<label>Name</label>
|
||
<input type="text" id="tpl-name" placeholder="z.B. Sneaker-Template">
|
||
</div>
|
||
<div class="setting-group">
|
||
<label>Plattform</label>
|
||
<select id="tpl-platform"><option value="">Alle</option></select>
|
||
</div>
|
||
<div class="setting-group">
|
||
<label>Sprache</label>
|
||
<select id="tpl-language">
|
||
<option value="de">Deutsch</option>
|
||
<option value="en">English</option>
|
||
<option value="fr">Français</option>
|
||
</select>
|
||
</div>
|
||
<div class="setting-group">
|
||
<label>Verkäufernotizen</label>
|
||
<div id="tpl-notes-editor" style="min-height:100px"></div>
|
||
</div>
|
||
<div class="setting-group">
|
||
<label>Standard-Tags (kommagetrennt)</label>
|
||
<input type="text" id="tpl-tags" placeholder="#vintage, #secondhand">
|
||
</div>
|
||
<div class="result-actions">
|
||
<button id="save-template-btn" class="primary-btn">Speichern</button>
|
||
<button id="cancel-template-btn" class="secondary-btn">Abbrechen</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VERÖFFENTLICHEN -->
|
||
<section id="quality-center" class="tab-content quality-center-page">
|
||
<header class="page-heading quality-center-heading">
|
||
<div><p class="eyebrow">Artikel Quality Center</p><h2>Qualitätscenter</h2><p>Prüfe Inhalte, Bilder, Pflichtfelder, mögliche Duplikate und Plattformtauglichkeit vor dem Veröffentlichen.</p></div>
|
||
<div class="page-heading-actions"><button type="button" class="vd-button" id="quality-refresh">Aktualisieren</button><button type="button" class="primary-btn" id="quality-analyze-visible">Sichtbare prüfen</button></div>
|
||
</header>
|
||
|
||
<div class="quality-summary-grid">
|
||
<article><span>Durchschnitt</span><strong id="quality-summary-average">—</strong><small>Qualitätsscore</small></article>
|
||
<article><span>Bereit</span><strong id="quality-summary-ready">—</strong><small>ohne Blocker</small></article>
|
||
<article><span>Blockiert</span><strong id="quality-summary-blocked">—</strong><small>harte Fehler</small></article>
|
||
<article><span>Artikel</span><strong id="quality-summary-total">—</strong><small>im Bestand</small></article>
|
||
</div>
|
||
|
||
<div class="quality-toolbar card">
|
||
<label class="quality-search"><span>Suchen</span><input type="search" id="quality-search" placeholder="Titel, SKU oder Plattform"></label>
|
||
<label><span>Status</span><select id="quality-status"><option value="all">Alle</option><option value="blocked">Blockiert</option><option value="review">Prüfen</option><option value="ready">Bereit</option></select></label>
|
||
<label><span>Note</span><select id="quality-grade"><option value="all">Alle Noten</option><option value="A">A</option><option value="B">B</option><option value="C">C</option><option value="D">D</option><option value="E">E</option></select></label>
|
||
<label><span>Pro Seite</span><select id="quality-page-size"><option value="5">5</option><option value="10" selected>10</option><option value="15">15</option><option value="25">25</option></select></label>
|
||
</div>
|
||
|
||
<div class="quality-workspace">
|
||
<section class="quality-list-panel card">
|
||
<div class="section-title-row"><div><p class="eyebrow">Prüfliste</p><h3>Artikelqualität</h3></div><span id="quality-list-range">0 Artikel</span></div>
|
||
<div id="quality-list" class="quality-list"><div class="empty-state"><p>Qualitätsdaten werden geladen …</p></div></div>
|
||
<div class="quality-pagination"><button type="button" class="page-nav-btn" id="quality-prev">‹</button><span id="quality-page-info">Seite 1 von 1</span><button type="button" class="page-nav-btn" id="quality-next">›</button></div>
|
||
</section>
|
||
|
||
<aside class="quality-detail-panel card" id="quality-detail-panel">
|
||
<div class="quality-detail-empty" id="quality-detail-empty"><div class="quality-empty-icon">✓</div><h3>Artikel auswählen</h3><p>Öffne eine Qualitätsprüfung, um Blocker, Empfehlungen, Bilder und Verbesserungsvorschläge zu sehen.</p></div>
|
||
<div class="quality-detail-content hidden" id="quality-detail-content">
|
||
<header class="quality-detail-head">
|
||
<div class="quality-score-ring" id="quality-score-ring"><strong id="quality-detail-score">0</strong><span>/ 100</span></div>
|
||
<div><p class="eyebrow" id="quality-detail-platform">Plattform</p><h3 id="quality-detail-title">Artikel</h3><p id="quality-detail-meta"></p></div>
|
||
</header>
|
||
<div class="quality-readiness" id="quality-readiness"></div>
|
||
<div class="quality-detail-actions"><button type="button" class="primary-btn" id="quality-run-analysis">Neu analysieren</button><button type="button" class="vd-button" id="quality-open-article">Artikel bearbeiten</button><button type="button" class="vd-button accent" id="quality-open-ai">Mit AI verbessern</button></div>
|
||
<div class="quality-financials" id="quality-financials"></div>
|
||
<div class="quality-issue-tabs" role="tablist"><button type="button" class="active" data-quality-issue-filter="all">Alle</button><button type="button" data-quality-issue-filter="error">Blocker</button><button type="button" data-quality-issue-filter="warning">Warnungen</button><button type="button" data-quality-issue-filter="recommendation">Empfehlungen</button></div>
|
||
<div id="quality-issues" class="quality-issues"></div>
|
||
<section class="quality-duplicates"><div class="section-title-row"><h4>Mögliche Duplikate</h4></div><div id="quality-duplicates"></div></section>
|
||
<section class="quality-images"><div class="section-title-row"><h4>Bildprüfung</h4></div><div id="quality-images"></div></section>
|
||
<section class="quality-history"><div class="section-title-row"><h4>Score-Verlauf</h4><span id="quality-score-delta"></span></div><div id="quality-history"></div></section>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="publish" class="tab-content publish-center-page">
|
||
<header class="page-heading publish-center-heading">
|
||
<div>
|
||
<p class="eyebrow">Commerce Control</p>
|
||
<h2>Publish-Center</h2>
|
||
<p>Bereite Artikel für den Verkauf vor und veröffentliche sie sicher auf deinen Marktplätzen.</p>
|
||
</div>
|
||
<div class="publish-heading-actions">
|
||
<button id="publish-refresh" class="vd-button" type="button">Aktualisieren</button>
|
||
<button id="publish-add-selected-ebay" class="vd-button primary" type="button" disabled>Zur Publishing-Queue</button>
|
||
</div>
|
||
</header>
|
||
|
||
<nav class="publish-view-tabs" aria-label="Publish-Bereiche">
|
||
<button class="publish-view-tab active" type="button" data-publish-view="smart">
|
||
Smart Copy <span class="publish-tab-badge">Manuell</span>
|
||
</button>
|
||
<button class="publish-view-tab" type="button" data-publish-view="direct">
|
||
Direkt veröffentlichen <span class="publish-tab-count" id="publish-direct-count">0</span>
|
||
</button>
|
||
<button class="publish-view-tab" type="button" data-publish-view="queue">
|
||
Publishing-Queue <span class="publish-tab-count" id="publish-queue-count">0</span>
|
||
</button>
|
||
<button class="publish-view-tab" type="button" data-publish-view="errors">
|
||
Fehler & Verlauf <span class="publish-tab-count" id="publish-error-count">0</span>
|
||
</button>
|
||
<button class="publish-view-tab" type="button" data-publish-view="scheduled">
|
||
Geplante Veröffentlichungen <span class="publish-tab-count" id="publish-scheduled-count">0</span>
|
||
</button>
|
||
</nav>
|
||
|
||
<div class="publish-center-grid">
|
||
<aside class="publish-list-panel" aria-label="Artikel-Auswahl">
|
||
<div class="publish-list-panel-head">
|
||
<div>
|
||
<span class="publish-panel-kicker">Bereit zur Bearbeitung</span>
|
||
<h3>Artikel <span id="publish-list-count">0</span></h3>
|
||
</div>
|
||
<select id="publish-sort" aria-label="Artikel sortieren">
|
||
<option value="newest">Neueste zuerst</option>
|
||
<option value="oldest">Älteste zuerst</option>
|
||
<option value="price-desc">Preis absteigend</option>
|
||
<option value="price-asc">Preis aufsteigend</option>
|
||
<option value="title">Titel A–Z</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="publish-list-filters">
|
||
<label class="publish-search-field">
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg>
|
||
<input type="search" id="publish-search" placeholder="Titel, SKU oder Marke …">
|
||
</label>
|
||
<div class="publish-filter-row">
|
||
<select id="publish-filter-platform"><option value="">Alle Plattformen</option></select>
|
||
<select id="publish-filter-status">
|
||
<option value="">Alle Status</option>
|
||
<option value="active">Aktiv</option>
|
||
<option value="reserved">Reserviert</option>
|
||
<option value="sold">Verkauft</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="publish-selection-bar">
|
||
<label><input type="checkbox" id="publish-select-all"> Alle</label>
|
||
<span id="publish-selected-count">0 ausgewählt</span>
|
||
</div>
|
||
|
||
<div id="publish-list" class="publish-list" aria-live="polite"></div>
|
||
|
||
<div class="publish-batch-bar">
|
||
<button id="publish-batch-copy" class="vd-button compact" disabled>Smart Copy</button>
|
||
<button id="publish-batch-ebay" class="vd-button compact" disabled>Publishing-Queue</button>
|
||
<button id="publish-batch-schedule" class="vd-button compact" disabled>Planen</button>
|
||
<button id="publish-download-photos" class="vd-button compact" disabled>Fotos</button>
|
||
<button id="publish-batch-etsy" class="vd-button compact" disabled>Etsy</button>
|
||
</div>
|
||
</aside>
|
||
|
||
<section class="publish-workspace-panel" aria-live="polite">
|
||
<div id="publish-workspace" class="publish-workspace"></div>
|
||
</section>
|
||
|
||
<aside class="publish-status-rail" aria-label="Publish-Status">
|
||
<section class="publish-rail-section">
|
||
<div class="publish-rail-heading">
|
||
<div>
|
||
<span class="publish-panel-kicker">Live-Übersicht</span>
|
||
<h3>Queue-Status</h3>
|
||
</div>
|
||
<button id="publish-status-refresh" class="icon-button" type="button" aria-label="Status aktualisieren">↻</button>
|
||
</div>
|
||
<div class="publish-status-list">
|
||
<button class="publish-status-row" type="button" data-status-target="queue">
|
||
<span class="publish-status-icon pending">◷</span><span><strong>Ausstehend</strong><small>Wartet auf Verarbeitung</small></span><b id="publish-status-pending">0</b>
|
||
</button>
|
||
<button class="publish-status-row" type="button" data-status-target="queue">
|
||
<span class="publish-status-icon processing">◌</span><span><strong>In Bearbeitung</strong><small>Aktiver Upload</small></span><b id="publish-status-processing">0</b>
|
||
</button>
|
||
<button class="publish-status-row" type="button" data-status-target="queue">
|
||
<span class="publish-status-icon success">✓</span><span><strong>Veröffentlicht</strong><small>Erfolgreich live</small></span><b id="publish-status-published">0</b>
|
||
</button>
|
||
<button class="publish-status-row" type="button" data-status-target="errors">
|
||
<span class="publish-status-icon danger">!</span><span><strong>Fehlgeschlagen</strong><small>Aktion erforderlich</small></span><b id="publish-status-failed">0</b>
|
||
</button>
|
||
<button class="publish-status-row" type="button" data-status-target="scheduled">
|
||
<span class="publish-status-icon scheduled">▣</span><span><strong>Geplant</strong><small>Zukünftige Veröffentlichungen</small></span><b id="publish-status-scheduled">0</b>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="publish-rail-section">
|
||
<div class="publish-rail-heading"><div><span class="publish-panel-kicker">Direktzugriff</span><h3>Schnellaktionen</h3></div></div>
|
||
<div class="publish-quick-actions">
|
||
<button id="publish-ebay-queue-process" class="publish-quick-action primary" type="button"><strong>Queue öffnen</strong><small>Alle Plattformen und Status</small></button>
|
||
<button id="publish-ebay-queue-retry" class="publish-quick-action" type="button"><strong>Fehlerzentrale öffnen</strong><small id="publish-retry-caption">Keine Fehler</small></button>
|
||
<button id="publish-schedule-overview" class="publish-quick-action" type="button"><strong>Geplante öffnen</strong><small id="publish-schedule-caption">Keine Planungen</small></button>
|
||
<button id="publish-ebay-queue-btn" class="publish-quick-action" type="button"><strong>Publishing-Protokoll</strong><small>IDs, Links und Ereignisse prüfen</small></button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="publish-rail-section publish-activity-section">
|
||
<div class="publish-rail-heading"><div><span class="publish-panel-kicker">Verlauf</span><h3>Aktivität</h3></div></div>
|
||
<div id="publish-activity" class="publish-activity-list"></div>
|
||
</section>
|
||
</aside>
|
||
</div>
|
||
|
||
<div id="schedule-modal" class="modal-overlay hidden publish-schedule-overlay">
|
||
<div class="modal publish-schedule-dialog">
|
||
<div class="modal-header">
|
||
<div><span class="publish-panel-kicker">Zeitsteuerung</span><h3 id="schedule-modal-title">Veröffentlichung planen</h3></div>
|
||
<button id="schedule-modal-close" class="modal-close" aria-label="Schließen">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="publish-schedule-summary" id="schedule-listing-summary"></div>
|
||
<div class="publish-schedule-grid">
|
||
<label>Plattform
|
||
<select id="schedule-platform">
|
||
<option value="ebay-de">eBay.de</option>
|
||
<option value="etsy">Etsy</option>
|
||
<option value="vinted">Vinted</option>
|
||
<option value="ebay-ka">Kleinanzeigen</option>
|
||
</select>
|
||
</label>
|
||
<label>Datum & Uhrzeit
|
||
<input type="datetime-local" id="schedule-datetime">
|
||
</label>
|
||
</div>
|
||
<div class="publish-schedule-actions">
|
||
<button id="schedule-cancel" class="vd-button">Abbrechen</button>
|
||
<button id="schedule-confirm" class="vd-button primary">Veröffentlichung planen</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- PAPIERKORB -->
|
||
<section id="trash" class="tab-content">
|
||
<div class="trash-header">
|
||
<h2>Papierkorb</h2>
|
||
<div class="trash-actions-bar">
|
||
<span id="trash-info" class="trash-info-text">Einträge werden nach 30 Tagen automatisch gelöscht</span>
|
||
<button id="empty-trash-btn" class="small-btn danger-btn">Papierkorb leeren</button>
|
||
</div>
|
||
</div>
|
||
<div id="trash-list" class="trash-list"></div>
|
||
</section>
|
||
|
||
<!-- LAGERVERWALTUNG -->
|
||
<section id="inventory" class="tab-content">
|
||
<div class="inventory-header">
|
||
<h2>Lagerverwaltung</h2>
|
||
<div class="inventory-actions-bar">
|
||
<button id="inv-add-location-btn" class="primary-btn">+ Lagerort</button>
|
||
</div>
|
||
</div>
|
||
<div id="inv-stats" class="inventory-stats"></div>
|
||
<div id="inv-locations" class="inventory-locations"></div>
|
||
<div id="inv-detail" class="inventory-detail hidden">
|
||
<button id="inv-back" class="secondary-btn">← Übersicht</button>
|
||
<h3 id="inv-detail-title"></h3>
|
||
<div class="inventory-detail-actions">
|
||
<button id="inv-rename-btn" class="small-btn">Umbenennen</button>
|
||
<button id="inv-move-btn" class="small-btn">Artikel verschieben</button>
|
||
</div>
|
||
<div id="inv-detail-list" class="history-list"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- GEBÜHRENRECHNER -->
|
||
<section id="fees" class="tab-content">
|
||
<div class="page-heading fee-heading">
|
||
<div><p class="eyebrow">Verkäufererlös</p><h2>Gebührenrechner</h2><p>Aktuelle Orientierung für private Verkäufer in Deutschland. Etsy wird als Shop-Plattform separat kalkuliert; optionale Werbung, Zusatzleistungen, Steuern und internationale Sonderfälle sind nicht pauschal eingerechnet.</p></div>
|
||
<span class="fee-verified-badge">Stand 08.07.2026</span>
|
||
</div>
|
||
<div class="setting-group">
|
||
<label>Verkaufspreis (€)</label>
|
||
<input type="number" id="fee-price" min="0" step="0.5" value="25" class="result-input" style="max-width:200px">
|
||
</div>
|
||
<div id="fee-results" class="fee-results"></div>
|
||
</section>
|
||
|
||
<!-- ADMIN -->
|
||
<section id="admin" class="tab-content">
|
||
<div class="admin-wrap">
|
||
<div class="admin-header">
|
||
<h2>Benutzer & Sicherheit</h2>
|
||
<button class="primary-btn" id="invite-user-btn">+ User einladen</button>
|
||
</div>
|
||
|
||
<div class="admin-tabs">
|
||
<button class="admin-tab active" data-admin-tab="users">Benutzer</button>
|
||
<button class="admin-tab" data-admin-tab="roles">Rollen</button>
|
||
<button class="admin-tab" data-admin-tab="sessions">Sessions</button>
|
||
<button class="admin-tab" data-admin-tab="smtp">E-Mail / SMTP</button>
|
||
<button class="admin-tab" data-admin-tab="system">System</button>
|
||
<button class="admin-tab" data-admin-tab="modules">Module</button>
|
||
<button class="admin-tab" data-admin-tab="security">Sicherheit</button>
|
||
<button class="admin-tab" data-admin-tab="audit">Audit Log</button>
|
||
</div>
|
||
|
||
<!-- Users Tab -->
|
||
<div class="admin-panel active" id="admin-users-panel">
|
||
<div id="users-list" class="users-list"></div>
|
||
</div>
|
||
|
||
<!-- Roles Tab -->
|
||
<div class="admin-panel" id="admin-roles-panel">
|
||
<div class="security-panel-heading">
|
||
<div><p class="eyebrow">RBAC</p><h3>Rollen und Berechtigungen</h3><p>Verbindliche Rollenprofile für Artikel, Medien, Publishing und Administration.</p></div>
|
||
</div>
|
||
<div id="role-cards" class="role-cards"><div class="empty-state">Rollen werden geladen …</div></div>
|
||
<div id="role-permission-matrix" class="role-permission-matrix"></div>
|
||
</div>
|
||
|
||
<!-- Sessions Tab -->
|
||
<div class="admin-panel" id="admin-sessions-panel">
|
||
<div id="sessions-list" class="sessions-list"></div>
|
||
</div>
|
||
|
||
<!-- SMTP Tab -->
|
||
<div class="admin-panel" id="admin-smtp-panel">
|
||
<div class="smtp-config-form">
|
||
<div class="smtp-status-bar" id="smtp-status-bar">
|
||
<span class="smtp-status-dot" id="smtp-status-dot"></span>
|
||
<span id="smtp-status-text">Lade...</span>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>SMTP Host</label>
|
||
<input type="text" id="smtp-host" placeholder="smtp.gmail.com">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>SMTP Port</label>
|
||
<input type="number" id="smtp-port" placeholder="587" value="587">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>SMTP Benutzer</label>
|
||
<input type="text" id="smtp-user" placeholder="user@example.com">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>SMTP Passwort</label>
|
||
<div class="key-input-wrap">
|
||
<input type="password" id="smtp-pass" placeholder="Passwort">
|
||
<button class="toggle-visibility" id="smtp-pass-toggle">Zeigen</button>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Absender (From)</label>
|
||
<input type="text" id="smtp-from" placeholder="noreply@example.com">
|
||
<small>E-Mail-Adresse, die als Absender angezeigt wird</small>
|
||
</div>
|
||
<div class="smtp-actions">
|
||
<button class="primary-btn" id="smtp-save-btn">SMTP speichern</button>
|
||
<button class="secondary-btn" id="smtp-test-btn">Verbindung testen</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- System Tab -->
|
||
<div class="admin-panel" id="admin-system-panel">
|
||
<div class="system-panel-heading">
|
||
<div>
|
||
<p class="eyebrow">Runtime & Integrität</p>
|
||
<h3>Systemprüfung</h3>
|
||
<p>Prüft Datenbank, Schreibrechte, UI-Dateien, Browser-Extensions und die optionale ComfyUI-Verbindung – ohne API-Schlüssel offenzulegen.</p>
|
||
</div>
|
||
<div class="system-panel-actions">
|
||
<button class="primary-btn" id="system-diagnostics-btn" type="button">Systemprüfung starten</button>
|
||
<button class="secondary-btn" id="system-diagnostics-copy" type="button" disabled>Diagnose kopieren</button>
|
||
</div>
|
||
</div>
|
||
<div id="system-diagnostics-summary" class="diagnostics-summary is-idle">Noch keine Systemprüfung ausgeführt.</div>
|
||
<div id="system-diagnostics-grid" class="diagnostics-grid" aria-live="polite"></div>
|
||
<div id="system-info-cards" class="system-info-grid"></div>
|
||
<div class="system-actions" style="margin-top:20px;display:flex;gap:8px;flex-wrap:wrap">
|
||
<button class="secondary-btn" id="system-cleanup-btn">Abgelaufene Sessions bereinigen</button>
|
||
</div>
|
||
<section class="operations-center" aria-labelledby="operations-center-title">
|
||
<header class="operations-center-head">
|
||
<div><p class="eyebrow">Sicherung, Updates & Browser</p><h3 id="operations-center-title">Betriebszentrale</h3><p>Verifizierte Backups, sichere Wiederherstellung, Update-Staging und Extension-Diagnose an einem Ort.</p></div>
|
||
<button type="button" class="secondary-btn" id="operations-refresh-btn"><span data-vd-icon="refresh-cw"></span> Aktualisieren</button>
|
||
</header>
|
||
|
||
<div id="operations-pending-banner" class="operations-pending hidden" role="status"></div>
|
||
|
||
<div class="operations-tabs" role="tablist" aria-label="Betriebsbereiche">
|
||
<button type="button" class="operations-tab active" data-operations-tab="backup">Backup & Restore</button>
|
||
<button type="button" class="operations-tab" data-operations-tab="updates">Update Center</button>
|
||
<button type="button" class="operations-tab" data-operations-tab="extensions">Extension-Diagnose</button>
|
||
</div>
|
||
|
||
<div class="operations-panel active" id="operations-backup-panel">
|
||
<div class="operations-grid">
|
||
<article class="operations-card operations-create-card">
|
||
<header><span data-vd-icon="database-backup"></span><div><h4>Neues Backup</h4><p>Datenbank wird als konsistenter SQLite-Snapshot gesichert.</p></div></header>
|
||
<label class="operation-field"><span>Bezeichnung</span><input id="operations-backup-label" type="text" maxlength="60" placeholder="z. B. vor großem Import"></label>
|
||
<label class="operation-check"><input id="operations-backup-uploads" type="checkbox" checked><span><strong>Bilder und Uploads einschließen</strong><small>Empfohlen für eine vollständige Wiederherstellung.</small></span></label>
|
||
<label class="operation-check warning"><input id="operations-backup-config" type="checkbox"><span><strong>.env mit Zugangsdaten einschließen</strong><small>Nur für verschlüsselt oder sicher aufbewahrte Backups.</small></span></label>
|
||
<button type="button" class="primary-btn" id="operations-backup-create"><span data-vd-icon="archive"></span> Backup erstellen und prüfen</button>
|
||
</article>
|
||
|
||
<article class="operations-card">
|
||
<header><span data-vd-icon="calendar-clock"></span><div><h4>Automatische Sicherung</h4><p>Ein tägliches rotierendes Backup, solange Vendoo läuft.</p></div></header>
|
||
<label class="operation-check"><input id="operations-auto-enabled" type="checkbox"><span><strong>Tägliches Backup aktivieren</strong><small>Zugangsdaten werden nie automatisch gesichert.</small></span></label>
|
||
<div class="operation-inline-fields">
|
||
<label class="operation-field"><span>Uhrzeit</span><select id="operations-auto-hour"></select></label>
|
||
<label class="operation-field"><span>Aufbewahren</span><select id="operations-auto-retention"><option value="3">3 Backups</option><option value="7">7 Backups</option><option value="14">14 Backups</option><option value="30">30 Backups</option></select></label>
|
||
</div>
|
||
<label class="operation-check"><input id="operations-auto-uploads" type="checkbox" checked><span><strong>Uploads einschließen</strong><small>Kann bei großen Bildbeständen mehr Speicher benötigen.</small></span></label>
|
||
<button type="button" class="secondary-btn" id="operations-settings-save">Zeitplan speichern</button>
|
||
</article>
|
||
|
||
<article class="operations-card operations-restore-card">
|
||
<header><span data-vd-icon="rotate-ccw"></span><div><h4>Wiederherstellung vorbereiten</h4><p>Das Backup wird vollständig geprüft. Vorher entsteht automatisch eine Sicherheitssicherung.</p></div></header>
|
||
<label class="operation-dropzone" for="operations-restore-input"><span data-vd-icon="upload-cloud"></span><strong>Vendoo-Backup auswählen</strong><small>Nur verifizierte ZIP-Backups aus dieser Betriebszentrale.</small></label>
|
||
<input type="file" id="operations-restore-input" accept=".zip" hidden>
|
||
<div id="operations-restore-file" class="operation-file-state">Keine Datei ausgewählt.</div>
|
||
<button type="button" class="secondary-btn danger" id="operations-restore-stage" disabled>Wiederherstellung prüfen und vorbereiten</button>
|
||
</article>
|
||
</div>
|
||
|
||
<div class="operations-list-head"><div><h4>Vorhandene Backups</h4><p id="operations-backup-summary">Backups werden geladen …</p></div></div>
|
||
<div id="operations-backup-list" class="operations-backup-list"><div class="empty-state">Backups werden geladen …</div></div>
|
||
</div>
|
||
|
||
<div class="operations-panel" id="operations-updates-panel">
|
||
<div class="operations-grid operations-update-grid">
|
||
<article class="operations-card">
|
||
<header><span data-vd-icon="badge-check"></span><div><h4>Installierter Stand</h4><p>Version, Migrationen und letzte Systemoperation.</p></div></header>
|
||
<div id="operations-version-card" class="operation-version-card"><strong>Vendoo —</strong><span>Wird geladen …</span></div>
|
||
<div id="operations-migration-list" class="operation-migration-list"></div>
|
||
</article>
|
||
<article class="operations-card">
|
||
<header><span data-vd-icon="radio-tower"></span><div><h4>Online-Updateprüfung</h4><p>Optional über eine selbst konfigurierte öffentliche Manifest-URL.</p></div></header>
|
||
<label class="operation-field"><span>Update-Manifest-URL</span><input id="operations-update-url" type="url" placeholder="https://example.org/vendoo/latest.json"></label>
|
||
<div class="operation-card-actions"><button type="button" class="secondary-btn" id="operations-update-url-save">URL speichern</button><button type="button" class="secondary-btn" id="operations-update-check">Jetzt prüfen</button></div>
|
||
<div id="operations-update-check-result" class="operation-result">Noch nicht geprüft.</div>
|
||
</article>
|
||
<article class="operations-card operations-deployment-card">
|
||
<header><span data-vd-icon="cloud-cog"></span><div><h4>Coolify & GitHub Deployment</h4><p>Neue GitHub-Versionen kontrolliert über Coolify ausrollen. Vendoo erhält keinen Docker-Socket.</p></div></header>
|
||
<label class="operation-field"><span>Provider</span><select id="deployment-provider"><option value="none">Nicht konfiguriert</option><option value="coolify">Coolify</option></select></label>
|
||
<label class="operation-field"><span>Coolify URL</span><input id="deployment-coolify-url" type="url" placeholder="https://coolify.example.de"></label>
|
||
<label class="operation-field"><span>Resource UUID</span><input id="deployment-resource-uuid" type="text" placeholder="Coolify Application UUID"></label>
|
||
<label class="operation-field"><span>Trigger</span><select id="deployment-trigger-mode"><option value="webhook">Deploy-Webhook (empfohlen)</option><option value="api">Coolify API</option></select></label>
|
||
<label class="operation-field"><span>Deploy-Webhook</span><input id="deployment-webhook-url" type="password" autocomplete="new-password" placeholder="Nur neu eingeben, wenn er geändert werden soll"></label>
|
||
<label class="operation-field"><span>API-Token</span><input id="deployment-api-token" type="password" autocomplete="new-password" placeholder="Nur für API-Modus"></label>
|
||
<div class="operation-card-actions"><button type="button" class="secondary-btn" id="deployment-save">Konfiguration speichern</button><button type="button" class="secondary-btn" id="deployment-test">Verbindung prüfen</button></div>
|
||
<div id="deployment-status" class="operation-result">Deployment-Konfiguration wird geladen …</div>
|
||
</article>
|
||
<article class="operations-card operations-deploy-action-card">
|
||
<header><span data-vd-icon="rocket"></span><div><h4>GitHub-Stand ausrollen</h4><p>Coolify holt den konfigurierten Branch und ersetzt den laufenden Container erst nach erfolgreichem Build und Healthcheck.</p></div></header>
|
||
<label class="operation-field"><span>GitHub Repository</span><input id="deployment-github-repository" type="text" value="Masterluke77/vendoo"></label>
|
||
<label class="operation-field"><span>Produktionsbranch</span><input id="deployment-github-branch" type="text" value="main"></label>
|
||
<label class="operation-field"><span>Update-Kanal</span><select id="deployment-update-channel"><option value="stable">Stable</option><option value="beta">Beta</option></select></label>
|
||
<label class="operation-check"><input id="deployment-backup-before" type="checkbox" checked><span>Vor dem Deployment ein verifiziertes Backup mit Konfiguration erstellen</span></label>
|
||
<label class="operation-check"><input id="deployment-backup-uploads" type="checkbox"><span>Uploads zusätzlich in das Vorab-Backup aufnehmen</span></label>
|
||
<div class="operation-card-actions"><button type="button" class="secondary-btn" id="deployment-update-check">Version prüfen</button><button type="button" class="primary-btn" id="deployment-trigger">Coolify-Deployment starten</button></div>
|
||
<div id="deployment-action-result" class="operation-result">Noch kein Deployment aus dem Webinterface angefordert.</div>
|
||
</article>
|
||
|
||
<article class="operations-card operations-update-upload">
|
||
<header><span data-vd-icon="package-open"></span><div><h4>Update-Paket vorbereiten</h4><p>Prüft Version, Pflichtdateien und verbotene Laufzeitdaten. Vorher wird automatisch gesichert.</p></div></header>
|
||
<label class="operation-dropzone" for="operations-update-input"><span data-vd-icon="file-archive"></span><strong>Vendoo-Update-ZIP auswählen</strong><small>Vollständiges Drüberkopier-Paket mit neuerer Version.</small></label>
|
||
<input type="file" id="operations-update-input" accept=".zip" hidden>
|
||
<div id="operations-update-file" class="operation-file-state">Keine Datei ausgewählt.</div>
|
||
<button type="button" class="primary-btn" id="operations-update-stage" disabled>Update prüfen und vorbereiten</button>
|
||
</article>
|
||
</div>
|
||
<div class="operations-instruction"><span data-vd-icon="shield-alert"></span><div><strong>Bewusster Neustart statt riskanter Live-Aktualisierung</strong><p>Vorbereitete Updates und Wiederherstellungen werden erst bei beendetem Vendoo über Setup-Menüpunkt 11 angewendet. Menüpunkt 12 stellt den vorherigen Programmstand wieder her.</p></div></div>
|
||
</div>
|
||
|
||
<div class="operations-panel" id="operations-extensions-panel">
|
||
<div class="operations-extension-summary" id="operations-extension-summary"><div class="empty-state">Extension-Diagnose wird geladen …</div></div>
|
||
<div id="operations-extension-packages" class="operations-extension-packages"></div>
|
||
<div class="operations-list-head"><div><h4>Zuletzt verbundene Browser</h4><p>Live gilt eine Verbindung, wenn sie sich in den letzten drei Minuten gemeldet hat.</p></div><button type="button" class="secondary-btn" id="operations-extension-refresh">Diagnose aktualisieren</button></div>
|
||
<div id="operations-extension-clients" class="operations-extension-clients"><div class="empty-state">Noch keine Extension-Verbindung gemeldet.</div></div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- Modules Tab -->
|
||
<div class="admin-panel" id="admin-modules-panel">
|
||
<div class="module-manager-head">
|
||
<div><p class="eyebrow">Plattform & Erweiterungen</p><h3>Modulmanager</h3><p>Vendoo-Module sicher aktivieren, deaktivieren, exportieren, installieren und – sofern zulässig – entfernen.</p></div>
|
||
<div class="module-manager-actions"><button type="button" class="secondary-btn" id="module-manager-refresh">Aktualisieren</button></div>
|
||
</div>
|
||
<div id="module-manager-summary" class="module-manager-summary"></div>
|
||
<div id="module-manager-safety" class="module-safety-card"></div>
|
||
<section class="module-install-card">
|
||
<h4>Modulpaket installieren</h4>
|
||
<p>Akzeptiert werden geprüfte <code>.vmod</code>-Pakete. Deklarative Module dürfen keinen ausführbaren Code enthalten. Ausführbare Fremdmodule bleiben bis zum isolierten Extension-Host in Quarantäne.</p>
|
||
<div class="module-install-row"><label><span>Modulpaket auswählen</span><input id="module-manager-file" type="file" accept=".vmod,application/vnd.vendoo.module+json,application/json"></label><button type="button" class="primary-btn" id="module-manager-install">Prüfen und installieren</button></div>
|
||
</section>
|
||
<div class="module-filter-row"><input id="module-manager-search" type="search" placeholder="Module suchen …"></div>
|
||
<div id="module-manager-list" class="module-list"><div class="module-empty">Module werden geladen …</div></div>
|
||
</div>
|
||
|
||
<!-- Security Tab -->
|
||
<div class="admin-panel" id="admin-security-panel">
|
||
<div class="security-panel-heading">
|
||
<div><p class="eyebrow">Serverbetrieb</p><h3>Sicherheitszentrale</h3><p>HTTPS, verschlüsselte Secrets, CSP, Request-Telemetrie, Sitzungen, Rate Limits und Bearbeitungssperren.</p></div>
|
||
<button type="button" class="secondary-btn" id="security-refresh-btn"><span data-vd-icon="refresh-cw"></span> Aktualisieren</button>
|
||
</div>
|
||
<div id="security-status-summary" class="security-status-summary"></div>
|
||
<div id="security-warning-list" class="security-warning-list"></div>
|
||
<div class="security-grid">
|
||
<article class="security-card"><h4>Netzwerk & HTTPS</h4><div id="security-network-info"></div></article>
|
||
<article class="security-card"><h4>Sessions & Limits</h4><div id="security-session-info"></div></article>
|
||
<article class="security-card"><h4>Secret-Speicher</h4><div id="security-secret-info"></div></article>
|
||
<article class="security-card"><h4>Requests & CSP</h4><div id="security-request-info"></div></article>
|
||
</div>
|
||
<div class="security-lock-head"><div><h4>Aktive Bearbeitungssperren</h4><p>Verhindert, dass zwei Benutzer denselben Artikel gleichzeitig überschreiben.</p></div></div>
|
||
<div id="security-lock-list" class="security-lock-list"><div class="empty-state">Keine aktiven Sperren.</div></div>
|
||
<div class="security-env-guide">
|
||
<h4>Empfohlene Server-Konfiguration</h4>
|
||
<pre>VENDOO_BIND_HOST=127.0.0.1
|
||
VENDOO_ALLOWED_HOSTS=vendoo.example.de
|
||
VENDOO_ALLOWED_ORIGINS=https://vendoo.example.de
|
||
VENDOO_TRUST_PROXY=true
|
||
PUBLIC_BASE_URL=https://vendoo.example.de</pre>
|
||
<p>Für LAN-Zugriff <code>VENDOO_BIND_HOST=0.0.0.0</code> verwenden. Öffentlichen Zugriff ausschließlich hinter einem HTTPS-Reverse-Proxy freigeben.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Audit Tab -->
|
||
<div class="admin-panel" id="admin-audit-panel">
|
||
<div class="audit-toolbar">
|
||
<input type="search" id="audit-search" placeholder="Benutzer, Aktion, Ziel oder IP suchen">
|
||
<input type="text" id="audit-action-filter" placeholder="Aktion, z. B. listing">
|
||
<input type="date" id="audit-from">
|
||
<input type="date" id="audit-to">
|
||
<select id="audit-page-size"><option value="50">50 Einträge</option><option value="100" selected>100 Einträge</option><option value="200">200 Einträge</option></select>
|
||
<button type="button" class="secondary-btn" id="audit-filter-btn">Filtern</button>
|
||
<button type="button" class="secondary-btn" id="audit-export-btn"><span data-vd-icon="download"></span> CSV exportieren</button>
|
||
</div>
|
||
<div id="audit-summary" class="audit-summary"></div>
|
||
<div id="audit-list" class="audit-list"></div>
|
||
<div class="audit-pagination"><button type="button" class="page-nav-btn" id="audit-prev">Zurück</button><span id="audit-page-info">Seite 1</span><button type="button" class="page-nav-btn" id="audit-next">Weiter</button></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Invite Modal -->
|
||
<div id="invite-modal" class="modal-overlay hidden">
|
||
<div class="modal" style="max-width:440px">
|
||
<div class="modal-header">
|
||
<h3>User einladen</h3>
|
||
<button class="modal-close" data-close-target="invite-modal">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>E-Mail *</label>
|
||
<input type="email" id="invite-email" placeholder="user@example.com" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Name</label>
|
||
<input type="text" id="invite-name" placeholder="Max Mustermann">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Rolle</label>
|
||
<select id="invite-role" class="model-select">
|
||
<option value="viewer">Leser</option>
|
||
<option value="publisher">Publisher</option>
|
||
<option value="editor" selected>Editor</option>
|
||
<option value="manager">Manager</option>
|
||
<option value="admin">Administrator</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Einladungsmethode</label>
|
||
<div class="invite-method-radios">
|
||
<label class="radio-label">
|
||
<input type="radio" name="invite-method" value="magic_link" checked>
|
||
<span>Magic Link <small>(User setzt Passwort)</small></span>
|
||
</label>
|
||
<label class="radio-label">
|
||
<input type="radio" name="invite-method" value="auto_password">
|
||
<span>Auto-Passwort generieren</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-group hidden" id="invite-result-wrap">
|
||
<label>Generiertes Passwort</label>
|
||
<div class="key-input-wrap">
|
||
<input type="text" id="invite-result-password" readonly>
|
||
<button class="toggle-visibility" id="invite-copy-pw" type="button">Kopieren</button>
|
||
</div>
|
||
<small>Dieses Passwort wurde an den User gesendet. Notiere es bei Bedarf.</small>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="secondary-btn" data-close-target="invite-modal">Abbrechen</button>
|
||
<button class="primary-btn" id="invite-send-btn">Einladung senden</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Edit User Modal -->
|
||
<div id="edit-user-modal" class="modal-overlay hidden">
|
||
<div class="modal" style="max-width:440px">
|
||
<div class="modal-header">
|
||
<h3>User bearbeiten</h3>
|
||
<button class="modal-close" data-close-target="edit-user-modal">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>E-Mail</label>
|
||
<input type="email" id="edit-user-email" readonly aria-readonly="true">
|
||
<small>Die Login-Adresse bleibt unverändert. Für eine andere Adresse bitte einen neuen Benutzer anlegen.</small>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Name</label>
|
||
<input type="text" id="edit-user-name">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Rolle</label>
|
||
<select id="edit-user-role" class="model-select">
|
||
<option value="viewer">Leser</option>
|
||
<option value="publisher">Publisher</option>
|
||
<option value="editor" selected>Editor</option>
|
||
<option value="manager">Manager</option>
|
||
<option value="admin">Administrator</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Status</label>
|
||
<select id="edit-user-active" class="model-select">
|
||
<option value="1">Aktiv</option>
|
||
<option value="0">Deaktiviert</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Neues Passwort setzen</label>
|
||
<div class="key-input-wrap">
|
||
<input type="password" id="edit-user-password" placeholder="Leer lassen = nicht ändern" minlength="10">
|
||
<button type="button" class="toggle-visibility" id="edit-user-pw-toggle">Zeigen</button>
|
||
</div>
|
||
<small>Mindestens 10 Zeichen mit Groß-/Kleinbuchstaben, Zahl und Sonderzeichen. Nur ausfüllen, wenn du das Passwort ändern möchtest.</small>
|
||
</div>
|
||
<div class="form-group" id="edit-user-password-status-wrap">
|
||
<label>Passwort-Status</label>
|
||
<span id="edit-user-pw-status" class="pw-status-badge"></span>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Login-Verlauf</label>
|
||
<button class="small-btn" id="edit-user-show-history" type="button">Login-Verlauf anzeigen</button>
|
||
<div id="edit-user-login-history" class="login-history-list hidden"></div>
|
||
</div>
|
||
<input type="hidden" id="edit-user-id">
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="secondary-btn" data-close-target="edit-user-modal">Abbrechen</button>
|
||
<button type="button" class="primary-btn" id="edit-user-save-btn">Speichern</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- My Sessions Modal -->
|
||
<div id="my-sessions-modal" class="modal-overlay hidden">
|
||
<div class="modal" style="max-width:520px">
|
||
<div class="modal-header">
|
||
<h3>Meine aktiven Sessions</h3>
|
||
<button class="modal-close" data-close-target="my-sessions-modal">×</button>
|
||
</div>
|
||
<div class="modal-body" id="my-sessions-list"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- EINSTELLUNGEN -->
|
||
<section id="flux-studio" class="tab-content flux-studio-page">
|
||
<header class="page-heading flux-studio-heading">
|
||
<div>
|
||
<p class="eyebrow">Lokale Bildgenerierung · Studio Pro</p>
|
||
<h2>FLUX Studio Pro</h2>
|
||
<p>Erzeuge 1, 2 oder 4 Prompt-Varianten, verwalte echte ComfyUI-Aufträge und greife jederzeit auf Verlauf, Parameter und Favoriten zurück.</p>
|
||
</div>
|
||
<div class="flux-studio-engine-actions">
|
||
<span id="flux-studio-engine-chip" class="settings-status-chip is-disabled">Wird geprüft</span>
|
||
<button type="button" class="vd-button" id="flux-studio-reset"><span data-vd-icon="rotate-ccw"></span> Arbeitsbereich zurücksetzen</button>
|
||
<button type="button" class="vd-button" id="flux-studio-refresh-engine">System prüfen</button>
|
||
<button type="button" class="vd-button" id="flux-studio-start-engine">FLUX starten</button>
|
||
<button type="button" class="vd-button" id="flux-studio-stop-engine">Stoppen</button>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="flux-studio-layout flux-studio-pro-layout">
|
||
<div class="flux-studio-left-stack">
|
||
<article class="flux-studio-card flux-studio-controls">
|
||
<div class="flux-studio-card-head"><div><span>01</span><h3>Prompt & Auftrag</h3></div><small>Reiner Text-zu-Bild-Workflow</small></div>
|
||
<label class="flux-studio-prompt-field">
|
||
<span>Bildbeschreibung</span>
|
||
<textarea id="flux-studio-prompt" rows="8" maxlength="2000" placeholder="Beispiel: Hochwertige Produktaufnahme eines minimalistischen Arbeitsplatzes, weiches Tageslicht, heller Hintergrund, fotorealistisch …"></textarea>
|
||
<small><b id="flux-studio-prompt-count">0</b> / 2.000 Zeichen</small>
|
||
</label>
|
||
<div class="flux-prompt-toolbar">
|
||
<div class="flux-studio-template-row" aria-label="Prompt-Vorlagen">
|
||
<button type="button" data-flux-template="product">Produktfoto</button>
|
||
<button type="button" data-flux-template="social">Social Media</button>
|
||
<button type="button" data-flux-template="background">Hintergrund</button>
|
||
<button type="button" data-flux-template="editorial">Editorial</button>
|
||
<button type="button" data-flux-template="lifestyle">Lifestyle</button>
|
||
</div>
|
||
<button type="button" class="vd-button flux-optimize-button" id="flux-studio-optimize-prompt"><span>✦</span> Prompt Lab</button>
|
||
</div>
|
||
<div class="flux-prompt-quality" id="flux-prompt-quality" data-level="empty">
|
||
<span><i></i><strong>Prompt-Check</strong></span><p id="flux-prompt-quality-copy">Beschreibe zuerst Motiv, Umgebung, Licht und Perspektive.</p>
|
||
</div>
|
||
|
||
<div class="flux-order-options">
|
||
<div class="flux-option-block">
|
||
<span class="flux-option-label">Bildvarianten</span>
|
||
<div class="flux-segmented" id="flux-studio-variant-selector" role="group" aria-label="Anzahl der Bildvarianten">
|
||
<button type="button" data-flux-variants="1" class="active">1 Bild</button>
|
||
<button type="button" data-flux-variants="2">2 Bilder</button>
|
||
<button type="button" data-flux-variants="4">4 Bilder</button>
|
||
</div>
|
||
<input type="hidden" id="flux-studio-variants" value="1">
|
||
</div>
|
||
<label class="flux-lock-toggle">
|
||
<input type="checkbox" id="flux-studio-seed-lock">
|
||
<span><strong>Seed Lock</strong><small>Seed-Reihe bei Wiederholung exakt beibehalten</small></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="flux-profile-strip" aria-label="Qualitätsprofile">
|
||
<button type="button" data-flux-profile="fast"><strong>Schnell</strong><small>768 px · 4 Schritte</small></button>
|
||
<button type="button" data-flux-profile="balanced" class="active"><strong>Ausgewogen</strong><small>bis 1024 px · 4 Schritte</small></button>
|
||
<button type="button" data-flux-profile="quality"><strong>Detail</strong><small>1024 px · 6 Schritte</small></button>
|
||
<button type="button" data-flux-profile="custom"><strong>Eigene Werte</strong><small>Format & Schritte frei</small></button>
|
||
</div>
|
||
<input type="hidden" id="flux-studio-profile" value="balanced">
|
||
<div class="flux-studio-fields">
|
||
<label>Prompt-Modus
|
||
<select id="flux-studio-prompt-mode"><option value="precise" selected>Präzise</option><option value="creative">Kreativ</option><option value="raw">Unverändert</option></select>
|
||
</label>
|
||
<label>Stil
|
||
<select id="flux-studio-style">
|
||
<option value="none">Prompt unverändert</option>
|
||
<option value="photorealistic" selected>Fotorealistisch</option>
|
||
<option value="product">Produktfotografie</option>
|
||
<option value="editorial">Editorial</option>
|
||
<option value="cinematic">Cinematic</option>
|
||
<option value="illustration">Illustration</option>
|
||
<option value="social">Social Media</option>
|
||
</select>
|
||
</label>
|
||
<label>Format
|
||
<select id="flux-studio-format">
|
||
<option value="768x768">Quadrat · 768 × 768</option>
|
||
<option value="1024x1024">Quadrat · 1024 × 1024</option>
|
||
<option value="768x1024">Hochformat · 768 × 1024</option>
|
||
<option value="1024x768">Querformat · 1024 × 768</option>
|
||
</select>
|
||
</label>
|
||
<label>Schritte
|
||
<select id="flux-studio-steps">
|
||
<option value="4" selected>Empfohlen für Schnell · 4</option>
|
||
<option value="6">Mehr Details · 6</option>
|
||
<option value="8">Experimentell · 8</option>
|
||
</select>
|
||
</label>
|
||
<label>Start-Seed
|
||
<div class="flux-seed-input"><input id="flux-studio-seed" type="number" min="0" max="2147483647" value="42"><button type="button" id="flux-studio-random-seed" title="Zufälligen Seed erzeugen">↻</button></div>
|
||
</label>
|
||
</div>
|
||
<div class="flux-studio-run-row">
|
||
<button type="button" class="vd-button primary" id="flux-studio-generate">Auftrag starten</button>
|
||
<span id="flux-studio-status">Bereit.</span>
|
||
</div>
|
||
<div id="flux-studio-progress" class="flux-studio-progress hidden" aria-live="polite">
|
||
<div><span id="flux-studio-progress-label">Warteschlange</span><strong id="flux-studio-progress-value">Phase</strong></div>
|
||
<div class="flux-indeterminate-track"><i id="flux-studio-progress-bar"></i></div>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="flux-studio-card flux-runtime-card">
|
||
<div class="flux-studio-card-head"><div><span>02</span><h3>System & ComfyUI</h3></div><button type="button" class="small-btn" id="flux-runtime-refresh">Aktualisieren</button></div>
|
||
<div id="flux-runtime-summary" class="flux-runtime-summary"><div class="empty-state">Systemdaten werden geladen …</div></div>
|
||
</article>
|
||
</div>
|
||
|
||
<div class="flux-studio-side-stack">
|
||
<article class="flux-studio-card flux-studio-preview-card">
|
||
<div class="flux-studio-card-head"><div><span>03</span><h3>Auswahl & Varianten</h3></div><small id="flux-studio-preview-meta">Noch kein Bild</small></div>
|
||
<div id="flux-studio-variant-results" class="flux-variant-results hidden"></div>
|
||
<div id="flux-studio-preview" class="flux-studio-preview">
|
||
<div id="flux-studio-preview-empty" class="flux-studio-preview-empty"><b>✦</b><strong>Dein FLUX-Bild erscheint hier</strong><span>Prompt eingeben und Auftrag starten.</span></div>
|
||
<img id="flux-studio-preview-image" class="hidden" alt="FLUX-Vorschau">
|
||
</div>
|
||
<div id="flux-studio-preview-actions" class="flux-studio-preview-actions hidden">
|
||
<button type="button" class="vd-button primary" id="flux-studio-edit">Bild bearbeiten</button>
|
||
<button type="button" class="vd-button" id="flux-studio-similar">Ähnlich erneut erzeugen</button>
|
||
<button type="button" class="vd-button" id="flux-studio-favorite">☆ Favorit</button>
|
||
<a class="vd-button" id="flux-studio-download" download>Herunterladen</a>
|
||
<button type="button" class="vd-button" id="flux-studio-use-in-generator">Als Produktfoto übernehmen</button>
|
||
<button type="button" class="vd-button danger" id="flux-studio-delete">Löschen</button>
|
||
</div>
|
||
</article>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<section class="flux-job-center">
|
||
<div class="flux-job-center-head">
|
||
<div><p class="eyebrow">Produktionszentrale</p><h3>FLUX Job-Center</h3><p>Aktive Aufträge, Verlauf und Archiv mit kontrollierter Bereinigung.</p></div>
|
||
<div class="flux-job-center-actions">
|
||
<div class="flux-job-view-switch" role="group" aria-label="Job-Center Bereich">
|
||
<button type="button" class="active" id="flux-job-view-active">Aufträge</button>
|
||
<button type="button" id="flux-job-view-archive">Archiv <span id="flux-job-archive-count">0</span></button>
|
||
</div>
|
||
<select id="flux-job-filter" aria-label="Jobstatus filtern"><option value="">Alle Aufträge</option><option value="active">Laufend & wartend</option><option value="completed">Erfolgreich</option><option value="failed">Fehlgeschlagen</option><option value="cancelled">Abgebrochen</option></select>
|
||
<select id="flux-job-page-size" aria-label="Aufträge pro Seite"><option value="5">5 / Seite</option><option value="10" selected>10 / Seite</option><option value="15">15 / Seite</option></select>
|
||
<button type="button" class="vd-button" id="flux-job-collapse-all">Alle einklappen</button>
|
||
<button type="button" class="vd-button" id="flux-job-refresh">Aktualisieren</button>
|
||
<button type="button" class="vd-button danger" id="flux-job-clear-queue">Warteschlange leeren</button>
|
||
<button type="button" class="vd-button flux-job-center-toggle" id="flux-job-center-toggle" aria-expanded="true">Aufträge einklappen</button>
|
||
</div>
|
||
</div>
|
||
<div id="flux-job-center-body" class="flux-job-center-body">
|
||
<div id="flux-job-summary" class="flux-job-summary"></div>
|
||
<div id="flux-job-bulkbar" class="flux-job-bulkbar">
|
||
<label><input type="checkbox" id="flux-job-select-page"> <span id="flux-job-selected-count">0 ausgewählt</span></label>
|
||
<div>
|
||
<button type="button" class="vd-button compact" id="flux-job-archive-selected" disabled>Auswahl archivieren</button>
|
||
<button type="button" class="vd-button compact hidden" id="flux-job-restore-selected" disabled>Wiederherstellen</button>
|
||
<button type="button" class="vd-button compact danger hidden" id="flux-job-delete-selected" disabled>Auswahl löschen</button>
|
||
<button type="button" class="vd-button compact danger hidden" id="flux-job-delete-all-archive">Archiv komplett löschen</button>
|
||
</div>
|
||
</div>
|
||
<div id="flux-job-list" class="flux-job-list"><div class="empty-state">Aufträge werden geladen …</div></div>
|
||
<div id="flux-job-pagination" class="flux-job-pagination">
|
||
<button type="button" class="page-nav-btn" id="flux-job-prev">‹</button>
|
||
<span id="flux-job-page-info">Seite 1 von 1</span>
|
||
<button type="button" class="page-nav-btn" id="flux-job-next">›</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="flux-studio-history-section">
|
||
<div class="flux-studio-history-head">
|
||
<div><p class="eyebrow">Bildbibliothek</p><h3>Ergebnisse & Favoriten</h3></div>
|
||
<div class="flux-library-actions"><label><input type="checkbox" id="flux-studio-favorites-only"> Nur Favoriten</label><select id="flux-history-page-size" aria-label="Bilder pro Seite"><option value="5" selected>5 / Seite</option><option value="10">10 / Seite</option><option value="15">15 / Seite</option></select><button type="button" class="vd-button" id="flux-studio-refresh-history">Aktualisieren</button></div>
|
||
</div>
|
||
<div id="flux-studio-history" class="flux-studio-history"><div class="empty-state">Noch keine FLUX-Bilder gespeichert.</div></div>
|
||
<div class="flux-history-pagination"><button type="button" class="page-nav-btn" id="flux-history-prev">‹</button><span id="flux-history-page-info">Seite 1 von 1</span><button type="button" class="page-nav-btn" id="flux-history-next">›</button></div>
|
||
</section>
|
||
</section>
|
||
|
||
<section id="media-library" class="tab-content media-library-page">
|
||
<header class="page-heading media-library-heading">
|
||
<div><p class="eyebrow">Zentrale Medienverwaltung</p><h2>Bildergalerie</h2><p>FLUX-, AI-, bearbeitete und in Artikeln verwendete Bilder gemeinsam durchsuchen, prüfen und verwalten.</p></div>
|
||
<div class="media-heading-actions">
|
||
<button type="button" class="vd-button" id="media-refresh">Aktualisieren</button>
|
||
<button type="button" class="vd-button primary" data-tab-target="flux-studio">Neues FLUX-Bild</button>
|
||
</div>
|
||
</header>
|
||
|
||
<section class="media-summary" aria-label="Medienübersicht">
|
||
<button type="button" data-media-source="all" class="active"><span>Gesamt</span><strong id="media-count-total">0</strong></button>
|
||
<button type="button" data-media-source="flux"><span>FLUX</span><strong id="media-count-flux">0</strong></button>
|
||
<button type="button" data-media-source="edited"><span>Bearbeitet</span><strong id="media-count-edited">0</strong></button>
|
||
<button type="button" data-media-source="batch"><span>Produktion</span><strong id="media-count-batch">0</strong></button>
|
||
<button type="button" data-media-source="ai"><span>AI-Bilder</span><strong id="media-count-ai">0</strong></button>
|
||
<button type="button" data-media-source="listing"><span>Artikel</span><strong id="media-count-listing">0</strong></button>
|
||
</section>
|
||
|
||
<div class="media-toolbar">
|
||
<label class="media-search"><span data-vd-icon="zoom-in"></span><input type="search" id="media-search" placeholder="Prompt, Titel oder Dateiname suchen"></label>
|
||
<select id="media-source"><option value="all">Alle Quellen</option><option value="flux">FLUX</option><option value="edited">Bearbeitet</option><option value="batch">Bildproduktion</option><option value="ai">AI-Bilder</option><option value="listing">Artikelbilder</option></select>
|
||
<select id="media-sort"><option value="newest">Neueste zuerst</option><option value="oldest">Älteste zuerst</option><option value="name">Name A–Z</option></select>
|
||
<label class="media-check"><input type="checkbox" id="media-favorites-only"> Nur Favoriten</label>
|
||
<select id="media-page-size"><option value="24">24 / Seite</option><option value="48">48 / Seite</option><option value="96">96 / Seite</option></select>
|
||
<div class="media-view-switch"><button type="button" class="active" id="media-view-grid" title="Rasteransicht" aria-label="Rasteransicht"><span data-vd-icon="image"></span></button><button type="button" id="media-view-list" title="Listenansicht" aria-label="Listenansicht"><span data-vd-icon="list"></span></button></div>
|
||
</div>
|
||
|
||
<div class="media-batchbar">
|
||
<label><input type="checkbox" id="media-select-page"> <span id="media-selected-count">0 ausgewählt</span></label>
|
||
<div><button type="button" class="vd-button compact" id="media-send-to-factory" disabled>Bildproduktion</button><button type="button" class="vd-button compact" id="media-download-selected" disabled>Download / ZIP</button><button type="button" class="vd-button compact danger" id="media-delete-selected" disabled>Löschen</button></div>
|
||
</div>
|
||
|
||
<div class="media-pagination media-pagination-top" data-media-pagination aria-label="Seitennavigation oberhalb der Bildergalerie">
|
||
<div class="media-pagination-summary" data-media-page-range>0 Bilder</div>
|
||
<div class="media-pagination-controls">
|
||
<button type="button" class="page-nav-btn" data-media-page-action="prev" aria-label="Vorherige Galerieseite">‹</button>
|
||
<label class="media-page-jump">Seite <select data-media-page-jump aria-label="Galerieseite auswählen"><option value="1">1</option></select></label>
|
||
<span data-media-page-info>von 1</span>
|
||
<button type="button" class="page-nav-btn" data-media-page-action="next" aria-label="Nächste Galerieseite">›</button>
|
||
</div>
|
||
</div>
|
||
<div id="media-grid" class="media-grid"><div class="empty-state">Bildergalerie wird geladen …</div></div>
|
||
<div class="media-pagination media-pagination-bottom" data-media-pagination aria-label="Seitennavigation unterhalb der Bildergalerie">
|
||
<div class="media-pagination-summary" data-media-page-range>0 Bilder</div>
|
||
<div class="media-pagination-controls">
|
||
<button type="button" class="page-nav-btn" data-media-page-action="prev" aria-label="Vorherige Galerieseite">‹</button>
|
||
<label class="media-page-jump">Seite <select data-media-page-jump aria-label="Galerieseite auswählen"><option value="1">1</option></select></label>
|
||
<span data-media-page-info>von 1</span>
|
||
<button type="button" class="page-nav-btn" data-media-page-action="next" aria-label="Nächste Galerieseite">›</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<section id="image-factory" class="tab-content image-factory-page">
|
||
<header class="page-heading image-factory-heading">
|
||
<div><p class="eyebrow">Batch Image Factory</p><h2>Bildproduktion</h2><p>Erzeuge aus mehreren Quellbildern automatisch optimierte Varianten für Marktplätze, Webshops und Social Media.</p></div>
|
||
<div class="image-factory-heading-actions"><button type="button" class="vd-button" id="image-factory-refresh">Aktualisieren</button><button type="button" class="vd-button primary" id="image-factory-start">Produktion starten</button></div>
|
||
</header>
|
||
|
||
<div class="image-factory-layout">
|
||
<section class="image-factory-config surface-card">
|
||
<div class="section-title-row"><div><p class="eyebrow">Auftrag</p><h3>Quellen und Ausgabeprofile</h3></div><span class="image-factory-selection" id="image-factory-selection-count">0 Bilder · 0 Profile</span></div>
|
||
<label class="field"><span>Auftragsname</span><input type="text" id="image-factory-name" maxlength="100" placeholder="z. B. Sommerkollektion eBay + Vinted"></label>
|
||
|
||
<div class="image-factory-source-head"><div><strong>Quellbilder</strong><span>Aus der zentralen Bildergalerie auswählen</span></div><div class="image-factory-source-tools"><input type="search" id="image-factory-source-search" placeholder="Bilder suchen"><select id="image-factory-source-filter"><option value="all">Alle Quellen</option><option value="listing">Artikel</option><option value="flux">FLUX</option><option value="batch">Produktion</option><option value="edited">Bearbeitet</option><option value="ai">AI</option></select><button type="button" class="vd-button compact" id="image-factory-select-visible">Sichtbare wählen</button><button type="button" class="vd-button compact" id="image-factory-clear-sources">Leeren</button></div></div>
|
||
<div id="image-factory-source-grid" class="image-factory-source-grid"><div class="empty-state">Bilder werden geladen …</div></div>
|
||
|
||
<div class="image-factory-profile-head"><div><strong>Produktionsprofile</strong><span>Ein Auftrag kann mehrere Ausgaben pro Bild erzeugen</span></div><button type="button" class="vd-button compact" id="image-factory-new-profile">Eigenes Profil</button></div>
|
||
<div id="image-factory-profile-grid" class="image-factory-profile-grid"><div class="empty-state">Profile werden geladen …</div></div>
|
||
|
||
<details class="image-factory-options">
|
||
<summary>Zusätzliche Verarbeitung</summary>
|
||
<div class="image-factory-options-grid">
|
||
<label class="toggle-row"><input type="checkbox" id="image-factory-remove-bg"><span><strong>Hintergrund entfernen</strong><small>Transparente Ausgabe; Intensität regelbar</small></span></label>
|
||
<label class="field"><span>Entfernungsintensität <output id="image-factory-bg-value">45</output></span><input type="range" id="image-factory-bg-sensitivity" min="0" max="100" value="45"></label>
|
||
<label class="toggle-row"><input type="checkbox" id="image-factory-watermark"><span><strong>Wasserzeichen</strong><small>Auf alle erzeugten Varianten anwenden</small></span></label>
|
||
<label class="field"><span>Wasserzeichentext</span><input type="text" id="image-factory-watermark-text" value="Vendoo" maxlength="80"></label>
|
||
<label class="field"><span>Position</span><select id="image-factory-watermark-position"><option value="bottom-right">Unten rechts</option><option value="bottom-left">Unten links</option><option value="top-right">Oben rechts</option><option value="top-left">Oben links</option><option value="center">Mitte</option></select></label>
|
||
<label class="field"><span>Deckkraft <output id="image-factory-watermark-value">40 %</output></span><input type="range" id="image-factory-watermark-opacity" min="10" max="100" value="40"></label>
|
||
</div>
|
||
</details>
|
||
<div class="image-factory-submit"><div><strong id="image-factory-output-estimate">Noch keine Ausgabe geplant</strong><span>Originalbilder bleiben unverändert. Jede Ausgabe wird als neue Version gespeichert.</span></div><button type="button" class="primary-btn" id="image-factory-submit">Bildproduktion starten</button></div>
|
||
</section>
|
||
|
||
<aside class="image-factory-status surface-card">
|
||
<p class="eyebrow">Übersicht</p><h3>Produktionsstatus</h3>
|
||
<div class="image-factory-stat-grid" id="image-factory-summary">
|
||
<div><span>Wartend</span><strong data-batch-summary="queued">0</strong></div><div><span>Laufend</span><strong data-batch-summary="running">0</strong></div><div><span>Pausiert</span><strong data-batch-summary="paused">0</strong></div><div><span>Fertig</span><strong data-batch-summary="completed">0</strong></div><div><span>Teilweise</span><strong data-batch-summary="partial">0</strong></div><div><span>Fehler</span><strong data-batch-summary="failed">0</strong></div>
|
||
</div>
|
||
<div class="image-factory-help"><strong>Neustartsicher</strong><p>Wartende Aufträge werden nach einem Vendoo-Neustart fortgesetzt. Pausierte Aufträge bleiben pausiert.</p></div>
|
||
</aside>
|
||
</div>
|
||
|
||
<section class="image-factory-jobs surface-card">
|
||
<div class="section-title-row"><div><p class="eyebrow">Job-Center</p><h3>Produktionsaufträge</h3></div><div class="image-factory-job-tools"><select id="image-factory-job-page-size"><option value="5">5 / Seite</option><option value="10" selected>10 / Seite</option><option value="15">15 / Seite</option></select><button type="button" class="vd-button compact" id="image-factory-jobs-refresh">Aktualisieren</button></div></div>
|
||
<div id="image-factory-jobs" class="image-factory-job-list"><div class="empty-state">Noch keine Produktionsaufträge.</div></div>
|
||
<div class="image-factory-pagination"><button type="button" class="page-nav-btn" id="image-factory-job-prev">‹</button><span id="image-factory-job-page-info">Seite 1 von 1</span><button type="button" class="page-nav-btn" id="image-factory-job-next">›</button></div>
|
||
</section>
|
||
</section>
|
||
|
||
<div class="modal-overlay hidden" id="image-factory-profile-modal" aria-hidden="true">
|
||
<div class="modal image-factory-profile-modal" role="dialog" aria-modal="true" aria-labelledby="image-factory-profile-title">
|
||
<div class="modal-header"><div><p class="eyebrow">Eigenes Ausgabeprofil</p><h3 id="image-factory-profile-title">Produktionsprofil anlegen</h3></div><button type="button" class="modal-close" id="image-factory-profile-close" aria-label="Schließen">×</button></div>
|
||
<div class="modal-body image-factory-profile-form">
|
||
<label class="field"><span>Name</span><input type="text" id="image-factory-profile-name" maxlength="80" placeholder="Mein Shop-Format"></label>
|
||
<label class="field"><span>Beschreibung</span><input type="text" id="image-factory-profile-description" maxlength="300" placeholder="Wofür wird dieses Profil verwendet?"></label>
|
||
<div class="form-grid two"><label class="field"><span>Breite</span><input type="number" id="image-factory-profile-width" min="0" max="12000" value="1600"></label><label class="field"><span>Höhe</span><input type="number" id="image-factory-profile-height" min="0" max="12000" value="1600"></label></div>
|
||
<div class="form-grid two"><label class="field"><span>Anpassung</span><select id="image-factory-profile-fit"><option value="contain">Einpassen mit Rand</option><option value="cover">Format füllen / zuschneiden</option><option value="inside">Nur verkleinern</option></select></label><label class="field"><span>Hintergrund</span><input type="color" id="image-factory-profile-background" value="#ffffff"></label></div>
|
||
<div class="form-grid two"><label class="field"><span>Format</span><select id="image-factory-profile-format"><option value="jpeg">JPEG</option><option value="webp">WebP</option><option value="png">PNG</option></select></label><label class="field"><span>Qualität</span><input type="number" id="image-factory-profile-quality" min="40" max="100" value="90"></label></div>
|
||
<label class="field"><span>Dateinamensschema</span><input type="text" id="image-factory-profile-pattern" value="{name}-{profile}-{index}"><small>Platzhalter: {name}, {profile}, {index}</small></label>
|
||
</div>
|
||
<div class="modal-footer"><button type="button" class="vd-button" id="image-factory-profile-cancel">Abbrechen</button><button type="button" class="vd-button primary" id="image-factory-profile-save">Profil speichern</button></div>
|
||
</div>
|
||
</div>
|
||
|
||
<section id="extensions" class="tab-content extensions-page">
|
||
<header class="page-heading extensions-heading">
|
||
<div><p class="eyebrow">Browser-Integration</p><h2>Vendoo Link Extensions</h2><p>Bereite die passende Browser-Erweiterung vor, öffne den Installationsordner und folge der kurzen Anleitung. Der Browser verlangt aus Sicherheitsgründen immer eine abschließende Bestätigung.</p></div>
|
||
<div class="extensions-heading-actions">
|
||
<div class="extensions-active-browser" id="extensions-active-browser"><span>Aktiver Browser</span><strong>Wird erkannt …</strong></div>
|
||
<button type="button" class="vd-button primary" id="extensions-prepare-active"><span data-vd-icon="puzzle"></span> Aktiven Browser vorbereiten</button>
|
||
</div>
|
||
</header>
|
||
<div class="extensions-notice"><span data-vd-icon="shield-check"></span><div><strong>Sicher statt versteckt</strong><p>Vendoo installiert keine Erweiterung unbemerkt. Ein Klick bereitet alles automatisch vor; die letzte Freigabe erfolgt bewusst in Chrome, Edge, Firefox oder Safari.</p></div></div>
|
||
<div id="extensions-grid" class="extensions-grid" aria-live="polite"></div>
|
||
<section class="extensions-help-card">
|
||
<div><span data-vd-icon="circle-help"></span><div><strong>So funktioniert die Ein-Klick-Vorbereitung</strong><p>Vendoo erkennt deinen Browser, öffnet den richtigen Erweiterungsordner und kopiert den Pfad. Danach musst du im Browser nur noch „Entpackte Erweiterung laden“ beziehungsweise die passende Firefox-/Safari-Aktion bestätigen.</p></div></div>
|
||
<ol><li>Bei deinem Browser auf <b>Installation vorbereiten</b> klicken.</li><li>Die geöffnete Erweiterungsverwaltung verwenden.</li><li>Den bereits kopierten Ordner auswählen und Vendoo Link anheften.</li></ol>
|
||
</section>
|
||
</section>
|
||
|
||
<section id="settings" class="tab-content settings-workspace">
|
||
<div class="settings-hero">
|
||
<div class="settings-hero-copy">
|
||
<span class="settings-eyebrow">Systemzentrale</span>
|
||
<h2>Einstellungen</h2>
|
||
<p>Sauber getrennte Bereiche für Grundeinstellungen, AI-Dienste, Marktplätze und den lokalen FLUX-Bildserver.</p>
|
||
</div>
|
||
<div class="settings-hero-status">
|
||
<div class="settings-status-chip" id="settings-ai-status-chip">
|
||
<span class="settings-status-dot"></span>
|
||
<div><small>AI-System</small><strong id="settings-ai-status-text">Wird geprüft …</strong></div>
|
||
</div>
|
||
<div class="settings-status-chip" id="settings-flux-status-chip">
|
||
<span class="settings-status-dot"></span>
|
||
<div><small>Lokales FLUX</small><strong id="settings-flux-status-text">Wird geprüft …</strong></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-shell">
|
||
<nav class="settings-nav" aria-label="Einstellungsbereiche">
|
||
<button type="button" class="settings-nav-item active" data-settings-panel="general">
|
||
<span class="settings-nav-icon">⌂</span><span><strong>Allgemein</strong><small>Standards & Netzwerk</small></span>
|
||
</button>
|
||
<button type="button" class="settings-nav-item" data-settings-panel="appearance">
|
||
<span class="settings-nav-icon">◐</span><span><strong>Darstellung</strong><small>Themes & Barrierefreiheit</small></span>
|
||
</button>
|
||
<button type="button" class="settings-nav-item" data-settings-panel="ai">
|
||
<span class="settings-nav-icon">✦</span><span><strong>AI & APIs</strong><small>Provider & Bildlogik</small></span>
|
||
</button>
|
||
<button type="button" class="settings-nav-item" data-settings-panel="marketplaces">
|
||
<span class="settings-nav-icon">◎</span><span><strong>Marktplätze</strong><small>Etsy & eBay</small></span>
|
||
</button>
|
||
<button type="button" class="settings-nav-item" data-settings-panel="flux">
|
||
<span class="settings-nav-icon">⚡</span><span><strong>Lokales FLUX</strong><small>Server & Installation</small></span>
|
||
</button>
|
||
</nav>
|
||
|
||
<div class="settings-panels">
|
||
<section class="settings-panel active" data-settings-panel-content="general">
|
||
<div class="settings-panel-head">
|
||
<div><span>01</span><h3>Allgemeine Einstellungen</h3><p>Die Standards, mit denen Vendoo im Alltag startet.</p></div>
|
||
</div>
|
||
<div class="settings-card-grid two-cols">
|
||
<article class="settings-card">
|
||
<div class="settings-card-head"><div><strong>Arbeitsstandard</strong><small>Vorauswahl im Generator</small></div></div>
|
||
<div class="settings-field-grid">
|
||
<div class="setting-group"><label for="setting-default-platform">Standard-Plattform</label><select id="setting-default-platform"></select></div>
|
||
<div class="setting-group"><label for="setting-default-ai">Standard AI Provider</label><select id="setting-default-ai"></select></div>
|
||
<div class="setting-group"><label for="setting-default-language">Standard-Sprache</label><select id="setting-default-language"><option value="de">Deutsch</option><option value="en">English</option><option value="fr">Français</option><option value="nl">Nederlands</option><option value="pl">Polski</option><option value="es">Español</option><option value="it">Italiano</option><option value="pt">Português</option></select></div>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="settings-card">
|
||
<div class="settings-card-head"><div><strong>Netzwerk & Smartphone</strong><small>QR-Upload im lokalen Netz</small></div></div>
|
||
<div class="setting-group">
|
||
<label for="setting-public-base-url">Vendoo LAN-Adresse</label>
|
||
<div class="inline-input-actions"><input type="text" id="setting-public-base-url" placeholder="http://192.168.178.50:8124"><button type="button" class="secondary-btn compact-inline" id="detect-public-base-url-btn">LAN-IP erkennen</button></div>
|
||
<small>Smartphone und Vendoo-PC müssen im selben Netzwerk sein.</small>
|
||
<div id="public-base-url-status" class="ai-models-status">Noch keine LAN-Adresse geprüft.</div>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
|
||
<article class="settings-card">
|
||
<div class="settings-card-head"><div><strong>Verkäufernotizen</strong><small>Automatischer Zusatz für neue Listing-Texte</small></div></div>
|
||
<div class="setting-group"><textarea id="setting-seller-notes" rows="5" placeholder="z. B. Versand: 2–3 Werktage, tierfreier Nichtraucherhaushalt …"></textarea><small>Wird automatisch in jede Listing-Beschreibung eingebaut.</small></div>
|
||
</article>
|
||
</section>
|
||
|
||
|
||
<section class="settings-panel" data-settings-panel-content="appearance" id="theme-manager-root">
|
||
<div class="settings-panel-head"><div><span>02</span><h3>Theme Manager</h3><p>Darstellung sicher über Design Tokens anpassen – ohne freies CSS und ohne Dateibearbeitung.</p></div></div>
|
||
|
||
<article class="settings-card vd-card theme-manager-grid">
|
||
<div class="settings-card-head split"><div><strong>Meine Darstellung</strong><small>Persönliches Theme, Dichte und Bewegung</small></div><span class="settings-status-chip"><span class="settings-status-dot"></span><strong>Live-Vorschau</strong></span></div>
|
||
<div class="theme-choice-grid" id="theme-choice-grid" aria-label="Theme auswählen"></div>
|
||
<div class="theme-manager-toolbar">
|
||
<div class="setting-group"><label for="theme-density">UI-Dichte</label><select id="theme-density"><option value="compact">Kompakt</option><option value="comfortable">Ausgewogen</option><option value="spacious">Großzügig</option></select></div>
|
||
<div class="setting-group"><label for="theme-reduced-motion">Animationen</label><select id="theme-reduced-motion"><option value="system">Systemeinstellung</option><option value="reduce">Reduzieren</option><option value="allow">Zulassen</option></select></div>
|
||
<button type="button" class="vd-button primary" id="theme-preference-save">Meine Darstellung speichern</button>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="settings-card vd-card theme-admin-only">
|
||
<div class="settings-card-head split"><div><strong>Systemstandard</strong><small>Vorgabe für neue Benutzer und „Systemstandard“</small></div><button type="button" class="vd-button" id="theme-system-save">Systemstandard speichern</button></div>
|
||
<div class="settings-field-grid three-cols">
|
||
<div class="setting-group"><label for="theme-system-default">Standard-Theme</label><select id="theme-system-default"><option value="system">Betriebssystem</option><option value="light">Hell</option><option value="dark">Dunkel</option><option value="contrast">Hoher Kontrast</option></select></div>
|
||
<div class="setting-group"><label for="theme-system-density">Standard-Dichte</label><select id="theme-system-density"><option value="compact">Kompakt</option><option value="comfortable">Ausgewogen</option><option value="spacious">Großzügig</option></select></div>
|
||
<div class="setting-group"><label for="theme-system-motion">Animationen</label><select id="theme-system-motion"><option value="system">Systemeinstellung</option><option value="reduce">Reduzieren</option><option value="allow">Zulassen</option></select></div>
|
||
</div>
|
||
</article>
|
||
|
||
<div class="theme-editor-layout theme-admin-only">
|
||
<article class="settings-card vd-card">
|
||
<div class="settings-card-head split"><div><strong id="theme-editor-title">Neues Theme</strong><small>Nur freigegebene Tokenwerte – kein CSS oder JavaScript</small></div><div><button type="button" class="vd-button compact" id="theme-new-btn">Neu</button><label class="vd-button compact" for="theme-import-input">Import</label><input type="file" id="theme-import-input" accept="application/json,.json" hidden></div></div>
|
||
<div class="settings-field-grid two-cols">
|
||
<div class="setting-group"><label for="theme-editor-name">Name</label><input class="vd-input" id="theme-editor-name" maxlength="80" placeholder="z. B. Vendoo Orange Pro"></div>
|
||
<div class="setting-group"><label for="theme-editor-base">Basis-Theme</label><select id="theme-editor-base"><option value="light">Hell</option><option value="dark">Dunkel</option><option value="contrast">Hoher Kontrast</option></select></div>
|
||
</div>
|
||
<div class="theme-token-groups" id="theme-token-groups"></div>
|
||
<div class="theme-preview-actions"><button type="button" class="vd-button" id="theme-validate-btn">Prüfen</button><button type="button" class="vd-button primary" id="theme-save-btn">Theme speichern</button><button type="button" class="vd-button danger" id="theme-delete-btn" hidden>Löschen</button></div>
|
||
</article>
|
||
|
||
<aside class="theme-preview">
|
||
<article class="settings-card vd-card">
|
||
<div class="settings-card-head"><div><strong>Live-Vorschau</strong><small id="theme-preview-name">Theme-Vorschau</small></div></div>
|
||
<div class="theme-preview-stage">
|
||
<div class="theme-preview-card"><strong>Produktkarte</strong><p>Text, Flächen, Linien und Abstände werden live geprüft.</p></div>
|
||
<div class="theme-preview-actions"><button type="button" class="vd-button primary">Primäraktion</button><button type="button" class="vd-button">Sekundär</button></div>
|
||
<label class="setting-group"><span>Eingabefeld</span><input class="vd-input" value="Sichere Token-Vorschau" readonly></label>
|
||
</div>
|
||
<button type="button" class="vd-button" id="theme-preview-reset">Vorschau zurücksetzen</button>
|
||
</article>
|
||
<article class="settings-card vd-card"><div class="settings-card-head"><div><strong>Kontrastprüfung</strong><small>WCAG-orientierte Kernpaare</small></div></div><div class="theme-contrast-list" id="theme-contrast-list"></div></article>
|
||
<article class="settings-card vd-card"><div class="settings-card-head"><div><strong>Eigene Themes</strong><small>Bearbeiten oder exportieren</small></div></div><div class="theme-profile-list" id="theme-profile-list"></div></article>
|
||
</aside>
|
||
</div>
|
||
|
||
<div class="theme-manager-status" id="theme-manager-status" role="status" aria-live="polite">Theme Manager wird geladen …</div>
|
||
</section>
|
||
|
||
<section class="settings-panel" data-settings-panel-content="ai">
|
||
<div class="settings-panel-head"><div><span>02</span><h3>AI & API-Dienste</h3><p>Textanalyse, Bildprovider und die Genauigkeit der Produktreferenz.</p></div></div>
|
||
|
||
<article class="settings-card">
|
||
<div class="settings-card-head"><div><strong>API-Zugänge</strong><small>Keys bleiben lokal in deiner Vendoo-Installation</small></div></div>
|
||
<div class="settings-card-grid three-cols">
|
||
<div class="setting-group"><label for="setting-anthropic-key">Anthropic API Key</label><div class="key-input-wrap"><input type="password" id="setting-anthropic-key" placeholder="sk-ant-..."><button class="toggle-visibility">Zeigen</button></div><small>Claude für Listing-Texte.</small></div>
|
||
<div class="setting-group"><label for="setting-openai-key">OpenAI API Key</label><div class="key-input-wrap"><input type="password" id="setting-openai-key" placeholder="sk-..."><button class="toggle-visibility">Zeigen</button></div><small>Analyse, Moderation und Bild-Fallback.</small></div>
|
||
<div class="setting-group"><label for="setting-openrouter-key">OpenRouter API Key</label><div class="key-input-wrap"><input type="password" id="setting-openrouter-key" placeholder="sk-or-..."><button class="toggle-visibility">Zeigen</button></div><small>Optionale kostenlose Bildmodelle.</small></div>
|
||
</div>
|
||
<div class="setting-group compact-top"><label for="setting-ollama-url">Ollama URL</label><input type="text" id="setting-ollama-url" placeholder="http://localhost:11434"><small>Lokale Text-AI via Ollama.</small></div>
|
||
</article>
|
||
|
||
|
||
<article class="settings-card ai-settings-card">
|
||
<div class="settings-card-head split"><div><strong>Lokale Bildwerkzeuge</strong><small>Ghost Mannequin, Flatlay und optionale Cloud-Fallbacks</small></div><label class="premium-switch"><input type="checkbox" id="setting-ai-model-photo-enabled"><span></span><b>Feature aktiv</b></label></div>
|
||
<div class="settings-field-grid four-cols">
|
||
<div class="setting-group"><label for="setting-ai-model-photo-provider">Bild-Provider</label><select id="setting-ai-model-photo-provider"><option value="auto">Auto: Lokal → OpenRouter → OpenAI</option><option value="local">Nur lokales FLUX</option><option value="openrouter">Nur OpenRouter</option><option value="openai">Nur OpenAI</option></select></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-mode">Standard-Modus</label><select id="setting-ai-model-photo-mode"><option value="ghost_mannequin">Ghost Mannequin</option><option value="flatlay">Flatlay</option></select></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-variants">Bilder pro Auftrag</label><select id="setting-ai-model-photo-variants"><option value="1">1 Bild</option><option value="2">2 Bilder</option><option value="3">3 Bilder</option></select></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-preset">Standard-Look</label><select id="setting-ai-model-photo-preset"><option value="mixed">Mix</option><option value="studio">Studio</option><option value="indoor">Indoor</option><option value="outdoor">Outdoor</option></select></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-local-resolution">Lokale Bildgröße</label><select id="setting-ai-model-photo-local-resolution"><option value="768">Schnell · 768 × 768</option><option value="1024">Qualität · 1024 × 1024</option></select><small>768 ist deutlich schneller und für Marktplatzbilder meist ausreichend.</small></div>
|
||
</div>
|
||
|
||
<div class="reference-control-card">
|
||
<div class="reference-control-copy"><span class="reference-icon">◫</span><div><strong>Produktfotos verbindlich verwenden</strong><small>Diese Referenzsteuerung gilt für Ghost Mannequin und Flatlay. Der freie FLUX-Generator arbeitet unabhängig davon nur mit Texteingaben.</small></div></div>
|
||
<label class="premium-switch"><input type="checkbox" id="setting-ai-model-photo-use-source-reference"><span></span><b>Referenz aktiv</b></label>
|
||
<div class="reference-strength-row"><label for="setting-ai-model-photo-reference-strength">Referenztreue</label><input type="range" id="setting-ai-model-photo-reference-strength" min="30" max="90" step="5" value="70"><output id="setting-ai-model-photo-reference-strength-value">70%</output></div>
|
||
</div>
|
||
|
||
<div class="setting-inline-checks modern-checks">
|
||
<label><input type="checkbox" id="setting-ai-model-photo-free-only"><span>Nur kostenlose OpenRouter-Modelle</span></label>
|
||
<label><input type="checkbox" id="setting-ai-model-photo-block-underwear"><span>Unterwäsche/Bademode blockieren</span></label>
|
||
<label><input type="checkbox" id="setting-ai-model-photo-block-kids"><span>Kinderkleidung blockieren</span></label>
|
||
<label><input type="checkbox" id="setting-ai-model-photo-preserve-logos"><span>Logos, Prints und Brustaufdrucke strikt schützen</span></label>
|
||
</div>
|
||
|
||
<details class="settings-disclosure">
|
||
<summary><span>Cloud-Bildprovider konfigurieren</span><small>OpenRouter und OpenAI</small></summary>
|
||
<div class="settings-card-grid two-cols disclosure-body">
|
||
<div class="setting-group"><label for="setting-ai-model-photo-openrouter-model">OpenRouter-Modell</label><div class="inline-input-actions"><select id="setting-ai-model-photo-openrouter-model"></select><button type="button" class="secondary-btn compact-inline" id="refresh-openrouter-models-btn">Modelle laden</button></div><small>Leer lassen für automatische Auswahl.</small></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-openai-model">OpenAI-Fallback-Modell</label><input type="text" id="setting-ai-model-photo-openai-model" placeholder="gpt-image-1"></div>
|
||
<div id="openrouter-models-status" class="ai-models-status full-span">Noch keine OpenRouter-Modelle geladen.</div>
|
||
<div id="openrouter-models-preview" class="openrouter-models-preview hidden full-span"></div>
|
||
</div>
|
||
</details>
|
||
</article>
|
||
</section>
|
||
|
||
<section class="settings-panel" data-settings-panel-content="marketplaces">
|
||
<div class="settings-panel-head"><div><span>03</span><h3>Marktplätze</h3><p>API-Verbindungen für Etsy und eBay übersichtlich an einem Ort.</p></div></div>
|
||
<div class="settings-card-grid two-cols">
|
||
<article class="settings-card">
|
||
<div class="settings-card-head"><div><strong>Etsy</strong><small>API-Key und Verbindung</small></div><span id="etsy-status-badge" class="etsy-status"></span></div>
|
||
<div class="setting-group"><label for="setting-etsy-key">Etsy API Key</label><div class="key-input-wrap"><input type="password" id="setting-etsy-key" placeholder="xxxxxxxx"><button class="toggle-visibility">Zeigen</button></div><small>Key unter etsy.com/developers erstellen.</small></div>
|
||
<div id="etsy-connect-wrap" class="etsy-connect-wrap hidden"><button id="etsy-connect-btn" class="secondary-btn">Mit Etsy verbinden</button></div>
|
||
</article>
|
||
|
||
<article class="settings-card">
|
||
<div class="settings-card-head"><div><strong>eBay.de</strong><small>Developer-Zugang und OAuth</small></div><span id="ebay-status-badge" class="etsy-status"></span></div>
|
||
<div class="setting-group"><label for="setting-ebay-client-id">Client ID</label><div class="key-input-wrap"><input type="password" id="setting-ebay-client-id" placeholder="eBay-App-..."><button class="toggle-visibility">Zeigen</button></div></div>
|
||
<div class="setting-group"><label for="setting-ebay-client-secret">Client Secret</label><div class="key-input-wrap"><input type="password" id="setting-ebay-client-secret" placeholder="eBay-Cert-..."><button class="toggle-visibility">Zeigen</button></div></div>
|
||
<div class="setting-group"><label for="setting-ebay-ru-name">RuName</label><input type="text" id="setting-ebay-ru-name" class="meta-input" placeholder="Dein_RuName"></div>
|
||
<label class="checkbox-line"><input type="checkbox" id="setting-ebay-sandbox"><span>Sandbox-Modus verwenden</span></label>
|
||
<div id="ebay-connect-wrap" class="etsy-connect-wrap hidden"><button id="ebay-connect-btn" class="secondary-btn">Mit eBay verbinden</button></div>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="settings-panel" data-settings-panel-content="flux">
|
||
<div class="settings-panel-head"><div><span>04</span><h3>Lokales FLUX / ComfyUI</h3><p>Installation, Aktivierung, Serverstatus und Wartung ohne Technik-Chaos.</p></div></div>
|
||
|
||
<article class="flux-command-card">
|
||
<div class="flux-command-main">
|
||
<div class="flux-orb" id="local-flux-orb"><span>FLUX</span></div>
|
||
<div class="flux-command-copy"><span id="local-flux-engine-kicker">Lokale Bild-Engine</span><h3 id="local-flux-engine-title">Status wird geprüft …</h3><p id="local-flux-engine-detail">Vendoo prüft Installation, Modell und laufenden Bildserver.</p></div>
|
||
</div>
|
||
<label class="premium-switch large"><input type="checkbox" id="setting-ai-model-photo-local-enabled"><span></span><b id="local-flux-enable-label">Aktivieren</b></label>
|
||
<div class="flux-command-actions">
|
||
<button type="button" class="primary-btn compact-inline" id="start-local-image-provider-btn">Server starten</button>
|
||
<button type="button" class="secondary-btn compact-inline" id="stop-local-image-provider-btn">Server stoppen</button>
|
||
<button type="button" class="secondary-btn compact-inline" id="test-local-image-provider-btn">Neu prüfen</button>
|
||
<button type="button" class="primary-btn compact-inline" id="open-flux-studio-page-btn">FLUX Studio öffnen</button>
|
||
</div>
|
||
</article>
|
||
|
||
<div class="flux-health-grid">
|
||
<div><span>Installation</span><strong id="local-flux-health-install">Wird geprüft</strong></div>
|
||
<div><span>FLUX-Modell</span><strong id="local-flux-health-model">Wird geprüft</strong></div>
|
||
<div><span>Bildserver</span><strong id="local-flux-health-server">Wird geprüft</strong></div>
|
||
<div><span>Prompt-Modus</span><strong id="local-flux-health-reference">Ohne Produktfoto</strong></div>
|
||
</div>
|
||
|
||
<article class="settings-card flux-performance-card">
|
||
<div class="settings-card-head"><div><strong>Leistung & Standardausgabe</strong><small>Optimiert Startverhalten und neue FLUX-Aufträge.</small></div></div>
|
||
<div class="settings-field-grid four-cols">
|
||
<div class="setting-group"><label for="setting-flux-runtime-profile">Serverprofil</label><select id="setting-flux-runtime-profile"><option value="auto">Automatisch nach VRAM</option><option value="fast">Schnell · ab ca. 12 GB VRAM</option><option value="balanced">Ausgewogen</option><option value="lowvram">Wenig VRAM</option></select></div>
|
||
<div class="setting-group"><label for="setting-flux-default-profile">Bildprofil</label><select id="setting-flux-default-profile"><option value="fast">Schnell</option><option value="balanced">Ausgewogen</option><option value="quality">Detail</option><option value="custom">Eigene Werte</option></select></div>
|
||
<div class="setting-group"><label for="setting-flux-default-style">Standardstil</label><select id="setting-flux-default-style"><option value="none">Prompt unverändert</option><option value="photorealistic">Fotorealistisch</option><option value="product">Produktfotografie</option><option value="editorial">Editorial</option><option value="cinematic">Cinematic</option><option value="illustration">Illustration</option><option value="social">Social Media</option></select></div>
|
||
<div class="setting-group"><label for="setting-flux-default-format">Standardformat</label><select id="setting-flux-default-format"><option value="768x768">768 × 768</option><option value="1024x1024">1024 × 1024</option><option value="768x1024">768 × 1024</option><option value="1024x768">1024 × 768</option></select></div>
|
||
<div class="setting-group"><label for="setting-flux-default-variants">Standardvarianten</label><select id="setting-flux-default-variants"><option value="1">1 Bild</option><option value="2">2 Bilder</option><option value="4">4 Bilder</option></select></div>
|
||
<div class="setting-group"><label for="setting-flux-max-parallel-jobs">GPU-Parallelität</label><select id="setting-flux-max-parallel-jobs"><option value="1">1 Auftrag gleichzeitig · empfohlen</option><option value="2">2 gleichzeitig</option><option value="3">3 gleichzeitig</option><option value="4">4 gleichzeitig</option></select></div>
|
||
</div>
|
||
<label class="checkbox-line"><input type="checkbox" id="setting-flux-prompt-assistant"><span>Prompt-Assistent automatisch verwenden</span></label>
|
||
<label class="checkbox-line"><input type="checkbox" id="setting-flux-seed-lock"><span>Seed Lock für neue Aufträge standardmäßig aktivieren</span></label>
|
||
<div class="settings-inline-note"><strong>Hinweis</strong><span>Das Serverprofil wird beim nächsten FLUX-Start aktiv. Schnell hält Modelle bevorzugt im VRAM; Wenig VRAM spart Speicher, ist aber langsamer.</span></div>
|
||
</article>
|
||
|
||
<article class="settings-card">
|
||
<div class="settings-card-head split"><div><strong>Installation & Wartung</strong><small>Nur die Aktion wählen – Vendoo erledigt den Rest.</small></div><span id="local-flux-engine-badge" class="flux-state-badge">Wird geprüft</span></div>
|
||
<div class="local-flux-install-options modern-checks">
|
||
<label><input type="checkbox" id="local-flux-install-model" checked><span>FLUX.1-schnell FP8 mitinstallieren</span></label>
|
||
<label><input type="checkbox" id="local-flux-enable-autostart" checked><span>Bei Windows-Anmeldung starten</span></label>
|
||
<label><input type="checkbox" id="local-flux-start-now" checked><span>Nach Installation sofort starten</span></label>
|
||
</div>
|
||
<div class="local-flux-actions command-actions">
|
||
<button type="button" class="primary-btn compact-inline" id="install-local-image-provider-btn">Installieren / reparieren</button>
|
||
<button type="button" class="secondary-btn compact-inline" id="update-local-image-provider-btn">ComfyUI aktualisieren</button>
|
||
<button type="button" class="danger-btn compact-inline" id="uninstall-local-image-provider-btn">FLUX deinstallieren</button>
|
||
</div>
|
||
<div id="local-image-provider-status" class="ai-models-status">Lokaler FLUX/ComfyUI-Status wird geprüft.</div>
|
||
</article>
|
||
|
||
<section class="local-flux-status-panel" aria-live="polite">
|
||
<div class="local-flux-status-head"><div><strong>Technischer Installationsstatus</strong><span id="local-flux-phase-label">Noch nicht gestartet</span></div><span id="local-flux-updated-at">–</span></div>
|
||
<div class="local-flux-progress" id="local-flux-progress-wrap"><div class="local-flux-progress-head"><strong id="local-flux-progress-label">Installation</strong><span id="local-flux-progress-value">0%</span></div><div class="local-flux-progress-track"><div id="local-flux-progress-bar"></div></div></div>
|
||
<div id="local-flux-live-metrics" class="local-flux-live-metrics"><div><span>Installer</span><strong id="local-flux-installer-state">Bereit</strong></div><div><span>Laufzeit</span><strong id="local-flux-elapsed">0 s</strong></div><div><span>Entpackt</span><strong id="local-flux-extract-files">0 Dateien</strong></div><div><span>Datenmenge</span><strong id="local-flux-extract-size">0 MB</strong></div><div><span>Heartbeat</span><strong id="local-flux-heartbeat">–</strong></div></div>
|
||
<div id="local-flux-checks" class="local-flux-checks"></div>
|
||
<div id="local-flux-error" class="local-flux-error hidden"></div>
|
||
<details class="local-flux-log-details"><summary>Installationsprotokoll anzeigen</summary><pre id="local-flux-log-tail">Noch kein Installationsprotokoll vorhanden.</pre></details>
|
||
<details class="local-flux-log-details"><summary>7-Zip-Ausgabe anzeigen</summary><pre id="local-flux-7zip-tail">Noch keine 7-Zip-Ausgabe vorhanden.</pre></details>
|
||
</section>
|
||
|
||
<details class="settings-disclosure">
|
||
<summary><span>Erweiterte lokale Konfiguration</span><small>URL, Token und Pfade</small></summary>
|
||
<div class="settings-card-grid two-cols disclosure-body">
|
||
<div class="setting-group"><label for="setting-ai-model-photo-local-url">ComfyUI URL</label><input type="text" id="setting-ai-model-photo-local-url" placeholder="http://127.0.0.1:8188"></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-local-token">Lokaler Zugriffstoken</label><div class="inline-input-actions"><input type="text" id="setting-ai-model-photo-local-token" placeholder="Token gesetzt"><button type="button" class="secondary-btn compact-inline" id="regenerate-local-image-token-btn">Token neu</button></div></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-local-workflow-path">Workflow-Pfad Standard</label><input type="text" id="setting-ai-model-photo-local-workflow-path" placeholder="local-ai/workflows/vendoo_flux_schnell_api.json"></div>
|
||
<div class="setting-group"><label for="setting-ai-model-photo-local-install-path">Installationspfad</label><input type="text" id="setting-ai-model-photo-local-install-path" placeholder="local-ai/comfyui"></div>
|
||
<label class="checkbox-line full-span"><input type="checkbox" id="setting-ai-model-photo-local-require-token"><span>Token für lokalen Zugriff verlangen</span></label>
|
||
</div>
|
||
</details>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-savebar">
|
||
<div><strong id="settings-save-title">Änderungen werden lokal gespeichert</strong><small id="settings-save-copy">Konfigurationen gelten direkt nach dem Speichern.</small></div>
|
||
<button id="save-settings-btn" class="primary-btn">Einstellungen speichern</button>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- Advanced Image Editor -->
|
||
<div id="photo-editor-overlay" class="photo-editor-overlay hidden" aria-hidden="true">
|
||
<div class="photo-editor" role="dialog" aria-modal="true" aria-labelledby="photo-editor-title">
|
||
<header class="photo-editor-header">
|
||
<div>
|
||
<span class="photo-editor-kicker">Advanced Image Editor</span>
|
||
<h3 id="photo-editor-title">Bild nicht destruktiv bearbeiten</h3>
|
||
<small id="pe-image-meta">Original wird niemals überschrieben.</small>
|
||
</div>
|
||
<button id="photo-editor-close" class="modal-close" type="button" aria-label="Editor schließen">×</button>
|
||
</header>
|
||
|
||
<div class="photo-editor-toolbar" role="toolbar" aria-label="Bearbeitungsschritte">
|
||
<button class="small-btn" id="pe-undo" type="button" disabled>↶ Undo</button>
|
||
<button class="small-btn" id="pe-redo" type="button" disabled>↷ Redo</button>
|
||
<button class="small-btn" id="pe-compare" type="button" aria-pressed="false">◫ Vorher / Nachher</button>
|
||
<button class="small-btn" id="pe-restore-original" type="button">Original wiederherstellen</button>
|
||
<span id="pe-history-status" class="pe-history-status">Schritt 1 von 1</span>
|
||
</div>
|
||
|
||
<div class="photo-editor-workspace">
|
||
<section class="photo-editor-stage" aria-label="Bildvorschau">
|
||
<div id="pe-before-pane" class="pe-preview-pane pe-before-pane hidden">
|
||
<span>Original</span>
|
||
<canvas id="photo-editor-before-canvas"></canvas>
|
||
</div>
|
||
<div class="pe-preview-pane pe-after-pane">
|
||
<span>Bearbeitung</span>
|
||
<div id="photo-editor-canvas-wrap" class="photo-editor-canvas-wrap">
|
||
<canvas id="photo-editor-canvas"></canvas>
|
||
<canvas id="photo-editor-crop-overlay" class="crop-overlay hidden"></canvas>
|
||
</div>
|
||
</div>
|
||
<div class="pe-stage-footer">
|
||
<span id="pe-output-dimensions">—</span>
|
||
<span id="pe-crop-hint">Zuschnitt ist nicht aktiv.</span>
|
||
</div>
|
||
</section>
|
||
|
||
<aside class="photo-editor-sidebar">
|
||
<details class="pe-control-group" open>
|
||
<summary>Geometrie & Zuschnitt</summary>
|
||
<div class="pe-control-body">
|
||
<div class="pe-button-grid">
|
||
<button class="small-btn" id="pe-rotate-left" type="button">↶ 90°</button>
|
||
<button class="small-btn" id="pe-rotate-right" type="button">↷ 90°</button>
|
||
<button class="small-btn" id="pe-flip-h" type="button">↔ Horizontal</button>
|
||
<button class="small-btn" id="pe-flip-v" type="button">↕ Vertikal</button>
|
||
</div>
|
||
<div class="editor-row">
|
||
<label for="pe-straighten">Begradigen</label>
|
||
<input type="range" id="pe-straighten" min="-15" max="15" step="0.1" value="0">
|
||
<span class="range-val" id="pe-straighten-val">0,0°</span>
|
||
</div>
|
||
<div class="pe-crop-controls">
|
||
<label for="pe-crop-ratio">Seitenverhältnis</label>
|
||
<select id="pe-crop-ratio">
|
||
<option value="free">Frei</option>
|
||
<option value="original">Original</option>
|
||
<option value="1:1">1:1</option>
|
||
<option value="4:5">4:5</option>
|
||
<option value="3:4">3:4</option>
|
||
<option value="16:9">16:9</option>
|
||
</select>
|
||
<div class="pe-button-grid three">
|
||
<button class="small-btn" id="pe-crop-toggle" type="button">✂ Auswahl starten</button>
|
||
<button class="small-btn hidden" id="pe-crop-apply" type="button">✓ Anwenden</button>
|
||
<button class="small-btn hidden" id="pe-crop-cancel" type="button">Abbrechen</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="pe-control-group" open>
|
||
<summary>Licht & Farbe</summary>
|
||
<div class="pe-control-body">
|
||
<div class="editor-row"><label for="pe-exposure">Belichtung</label><input type="range" id="pe-exposure" min="-2" max="2" step="0.1" value="0"><span class="range-val" id="pe-exposure-val">0,0</span></div>
|
||
<div class="editor-row"><label for="pe-brightness">Helligkeit</label><input type="range" id="pe-brightness" min="-100" max="100" value="0"><span class="range-val" id="pe-brightness-val">0</span></div>
|
||
<div class="editor-row"><label for="pe-contrast">Kontrast</label><input type="range" id="pe-contrast" min="-100" max="100" value="0"><span class="range-val" id="pe-contrast-val">0</span></div>
|
||
<div class="editor-row"><label for="pe-highlights">Lichter</label><input type="range" id="pe-highlights" min="-100" max="100" value="0"><span class="range-val" id="pe-highlights-val">0</span></div>
|
||
<div class="editor-row"><label for="pe-shadows">Schatten</label><input type="range" id="pe-shadows" min="-100" max="100" value="0"><span class="range-val" id="pe-shadows-val">0</span></div>
|
||
<div class="editor-row"><label for="pe-temperature">Temperatur</label><input type="range" id="pe-temperature" min="-100" max="100" value="0"><span class="range-val" id="pe-temperature-val">0</span></div>
|
||
<div class="editor-row"><label for="pe-saturation">Sättigung</label><input type="range" id="pe-saturation" min="-100" max="100" value="0"><span class="range-val" id="pe-saturation-val">0</span></div>
|
||
<div class="editor-row"><label for="pe-sharpness">Schärfe</label><input type="range" id="pe-sharpness" min="0" max="100" value="0"><span class="range-val" id="pe-sharpness-val">0</span></div>
|
||
<button class="small-btn full" id="pe-reset-adjustments" type="button">Licht & Farbe zurücksetzen</button>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="pe-control-group" open>
|
||
<summary>Freistellen & Wasserzeichen</summary>
|
||
<div class="pe-control-body pe-special-tools">
|
||
<label class="pe-tool-toggle">
|
||
<input type="checkbox" id="pe-remove-background">
|
||
<span><strong>Hintergrund entfernen</strong><small>Entfernt einen gleichmäßigen Randhintergrund nicht destruktiv. Für Transparenz wird PNG empfohlen.</small></span>
|
||
</label>
|
||
<div class="pe-background-strength">
|
||
<label for="pe-background-sensitivity">Entfernungsintensität</label>
|
||
<div class="pe-inline-control"><input type="range" id="pe-background-sensitivity" min="0" max="100" value="45"><span class="range-val" id="pe-background-sensitivity-val">45%</span></div><small class="pe-sensitivity-help">Niedrig schützt feine Kanten; hoch entfernt mehr ähnliche Hintergrundfarben.</small>
|
||
</div>
|
||
<div class="pe-watermark-tools">
|
||
<label class="pe-tool-toggle">
|
||
<input type="checkbox" id="pe-watermark-enabled">
|
||
<span><strong>Wasserzeichen hinzufügen</strong><small>Text, Position und Deckkraft werden erst beim Speichern eingebrannt.</small></span>
|
||
</label>
|
||
<label for="pe-watermark-text">Wasserzeichentext</label>
|
||
<input id="pe-watermark-text" type="text" maxlength="80" value="Vendoo" placeholder="Vendoo">
|
||
<label for="pe-watermark-position">Position</label>
|
||
<select id="pe-watermark-position">
|
||
<option value="bottom-right" selected>Unten rechts</option>
|
||
<option value="bottom-left">Unten links</option>
|
||
<option value="top-right">Oben rechts</option>
|
||
<option value="top-left">Oben links</option>
|
||
<option value="center">Mittig</option>
|
||
</select>
|
||
<label for="pe-watermark-opacity">Deckkraft</label>
|
||
<div class="pe-inline-control"><input type="range" id="pe-watermark-opacity" min="10" max="100" value="40"><span class="range-val" id="pe-watermark-opacity-val">40%</span></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="pe-control-group" open>
|
||
<summary>Export</summary>
|
||
<div class="pe-control-body pe-export-grid">
|
||
<label for="pe-format">Format</label>
|
||
<select id="pe-format"><option value="jpeg">JPEG</option><option value="webp">WebP</option><option value="png">PNG</option></select>
|
||
<label for="pe-quality">Qualität</label>
|
||
<div class="pe-inline-control"><input type="range" id="pe-quality" min="40" max="100" value="90"><span class="range-val" id="pe-quality-val">90%</span></div>
|
||
<label for="pe-target-size">Zielgröße</label>
|
||
<select id="pe-target-size"><option value="original">Originalgröße</option><option value="2048">max. 2048 px</option><option value="1600">max. 1600 px</option><option value="1200">max. 1200 px</option><option value="custom">Benutzerdefiniert</option></select>
|
||
<div id="pe-custom-size" class="pe-custom-size hidden">
|
||
<input id="pe-target-width" type="number" min="1" max="12000" placeholder="Breite">
|
||
<span>×</span>
|
||
<input id="pe-target-height" type="number" min="1" max="12000" placeholder="Höhe">
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="pe-control-group pe-version-group" open>
|
||
<summary>Gespeicherte Versionen <span id="pe-version-count">0</span></summary>
|
||
<div id="pe-version-list" class="pe-version-list"><div class="empty-state">Noch keine Bearbeitungsversion.</div></div>
|
||
</details>
|
||
</aside>
|
||
</div>
|
||
|
||
<footer class="photo-editor-actions">
|
||
<div><strong>Nicht destruktiv</strong><small>Speichern erzeugt immer eine neue Datei und Version.</small></div>
|
||
<button id="pe-cancel" class="secondary-btn" type="button">Abbrechen</button>
|
||
<button id="pe-apply" class="primary-btn" type="button">Als neue Version speichern</button>
|
||
</footer>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="mobile-upload-overlay" class="modal-overlay mobile-upload-overlay hidden" aria-hidden="true">
|
||
<div class="mobile-upload-dialog" role="dialog" aria-modal="true" aria-labelledby="mobile-upload-title">
|
||
<header>
|
||
<div class="mobile-upload-dialog-brand"><span class="mobile-upload-dialog-icon">QR</span><div><span>Mobiler Foto-Upload</span><h3 id="mobile-upload-title">Fotos direkt vom Handy</h3></div></div>
|
||
<button id="mobile-upload-close" class="modal-close" type="button" aria-label="Schließen">×</button>
|
||
</header>
|
||
<div class="mobile-upload-dialog-grid">
|
||
<div class="mobile-upload-qr-card">
|
||
<canvas id="mobile-upload-qr"></canvas>
|
||
<span id="mobile-upload-session-state" class="mobile-upload-session-state"><i></i>Link wird vorbereitet …</span>
|
||
</div>
|
||
<div class="mobile-upload-dialog-copy">
|
||
<span class="eyebrow">Smartphone verbinden</span>
|
||
<h4>QR-Code mit der Kamera scannen</h4>
|
||
<ol>
|
||
<li>QR-Code mit dem Smartphone öffnen</li>
|
||
<li>Produktfotos aufnehmen oder auswählen</li>
|
||
<li>Bilder erscheinen automatisch in Vendoo</li>
|
||
</ol>
|
||
<div class="mobile-upload-link-wrap"><input id="mobile-upload-link" type="text" readonly><button id="mobile-upload-copy-link" type="button">Kopieren</button></div>
|
||
<p id="mobile-upload-network-note">Das Smartphone muss diese Vendoo-Adresse erreichen können.</p>
|
||
<div class="mobile-upload-live"><strong id="mobile-upload-file-count">0 Bilder empfangen</strong><span id="mobile-upload-expiry"></span></div>
|
||
</div>
|
||
</div>
|
||
<footer><button id="mobile-upload-new-session" class="secondary-btn" type="button">Neuen QR-Code erzeugen</button><button id="mobile-upload-done" class="primary-btn" type="button">Fertig</button></footer>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="ai-prompt-modal" class="ai-prompt-modal hidden" aria-hidden="true">
|
||
<div class="ai-prompt-backdrop" data-ai-prompt-close></div>
|
||
<section class="ai-prompt-shell" role="dialog" aria-modal="true" aria-labelledby="ai-prompt-title">
|
||
<header class="ai-prompt-header">
|
||
<div>
|
||
<span class="print-studio-kicker">Vendoo AI Prompt</span>
|
||
<h2 id="ai-prompt-title">Eigene Bildanweisung</h2>
|
||
<p id="ai-prompt-scope-copy">Feinschliff für AI-Model-Fotos</p>
|
||
</div>
|
||
<button type="button" class="print-studio-close" data-ai-prompt-close aria-label="Schließen">×</button>
|
||
</header>
|
||
<div class="ai-prompt-body">
|
||
<div class="ai-prompt-summary">
|
||
<span class="ai-prompt-chip" id="ai-prompt-mode-chip">Modus: —</span>
|
||
<span class="ai-prompt-chip" id="ai-prompt-look-chip">Look: —</span>
|
||
<span class="ai-prompt-chip" id="ai-prompt-variants-chip">Varianten: —</span>
|
||
</div>
|
||
<label class="ai-prompt-field">
|
||
<span>Zusätzliche Prompt-Anweisung</span>
|
||
<textarea id="ai-prompt-textarea" rows="7" placeholder="z. B. neutrales Model, klare Frontalansicht, beide Ärmel sichtbar, Kapuze sauber am Rücken, natürlicher Stand, Produkt dominant..."></textarea>
|
||
<small>Optional. Vendoo ergänzt diese Anweisung zur sicheren Standardlogik.</small>
|
||
</label>
|
||
<label class="checkbox-line full-span ai-prompt-check"><input type="checkbox" id="ai-prompt-preserve-logos" checked><span>Logos, Prints und Aufdrucke strikt erhalten</span></label>
|
||
</div>
|
||
<footer class="ai-prompt-footer">
|
||
<button type="button" class="vd-button" id="ai-prompt-reset-btn">Zurücksetzen</button>
|
||
<div class="ai-prompt-footer-actions">
|
||
<button type="button" class="vd-button" data-ai-prompt-close>Schließen</button>
|
||
<button type="button" class="vd-button primary" id="ai-prompt-run-btn">Speichern & Generieren</button>
|
||
</div>
|
||
</footer>
|
||
</section>
|
||
</div>
|
||
|
||
|
||
|
||
<div id="smart-copy-modal" class="smart-copy-modal hidden" aria-hidden="true">
|
||
<button type="button" class="smart-copy-modal-backdrop" data-smart-copy-close aria-label="Smart Copy schließen"></button>
|
||
<section class="smart-copy-modal-dialog" role="dialog" aria-modal="true" aria-labelledby="smart-copy-modal-title">
|
||
<header><div><p class="eyebrow">Publish Assistant</p><h2 id="smart-copy-modal-title">Smart Copy</h2><p>Alle Verkaufsdaten kompakt kopieren und die Zielplattform direkt öffnen.</p></div><button type="button" class="modal-close" data-smart-copy-close aria-label="Schließen">×</button></header>
|
||
<div id="smart-copy-modal-content" class="smart-copy-modal-content"></div>
|
||
</section>
|
||
</div>
|
||
|
||
<div id="flux-prompt-lab" class="flux-prompt-lab hidden" aria-hidden="true">
|
||
<button type="button" class="flux-prompt-lab-backdrop" data-flux-prompt-lab-close aria-label="Prompt Lab schließen"></button>
|
||
<section class="flux-prompt-lab-dialog" role="dialog" aria-modal="true" aria-labelledby="flux-prompt-lab-title">
|
||
<header>
|
||
<div><p class="eyebrow">FLUX Prompt Director</p><h2 id="flux-prompt-lab-title">Prompt Lab</h2><p>Lokal strukturieren oder mit dem aktuell aktiven AI-Provider professionell veredeln.</p></div>
|
||
<button type="button" class="modal-close" data-flux-prompt-lab-close aria-label="Schließen">×</button>
|
||
</header>
|
||
<div class="flux-prompt-lab-body">
|
||
<div class="flux-prompt-lab-provider"><span>Aktiver AI-Provider</span><strong id="flux-prompt-lab-provider">—</strong></div>
|
||
<label class="flux-prompt-lab-field"><span>Ausgangsprompt</span><textarea id="flux-prompt-lab-original" rows="6"></textarea></label>
|
||
<div class="flux-prompt-lab-options">
|
||
<label>Zielprofil<select id="flux-prompt-lab-goal"><option value="product" selected>Produktfotografie & Marketplace</option><option value="precise">Präzise & technisch</option><option value="creative">Kreativ & aufmerksamkeitsstark</option><option value="cinematic">Cinematisch & atmosphärisch</option></select></label>
|
||
<label class="flux-prompt-lab-check"><input type="checkbox" id="flux-prompt-lab-preserve" checked><span>Motiv und Produktmerkmale strikt erhalten</span></label>
|
||
<label class="flux-prompt-lab-check"><input type="checkbox" id="flux-prompt-lab-avoid-text" checked><span>Keine erfundene Schrift, Logos oder Wasserzeichen</span></label>
|
||
</div>
|
||
<div class="flux-prompt-lab-actions"><button type="button" class="vd-button" id="flux-prompt-lab-local">Lokal strukturieren</button><button type="button" class="vd-button primary" id="flux-prompt-lab-ai">Mit AI veredeln</button></div>
|
||
<div id="flux-prompt-lab-status" class="flux-prompt-lab-status">Bereit.</div>
|
||
<label class="flux-prompt-lab-field"><span>Optimierter Prompt</span><textarea id="flux-prompt-lab-result" rows="9" placeholder="Hier erscheint der optimierte FLUX-Prompt …"></textarea></label>
|
||
<p id="flux-prompt-lab-notes" class="flux-prompt-lab-notes"></p>
|
||
</div>
|
||
<footer><button type="button" class="vd-button" data-flux-prompt-lab-close>Abbrechen</button><button type="button" class="vd-button primary" id="flux-prompt-lab-apply">Prompt übernehmen</button></footer>
|
||
</section>
|
||
</div>
|
||
|
||
<div id="media-lightbox" class="media-lightbox hidden" aria-hidden="true">
|
||
<button type="button" class="media-lightbox-backdrop" data-media-lightbox-close aria-label="Vorschau schließen"></button>
|
||
<section class="media-lightbox-dialog" role="dialog" aria-modal="true" aria-labelledby="media-lightbox-title">
|
||
<header><div><p class="eyebrow">Bildvorschau</p><h3 id="media-lightbox-title">Bild</h3></div><button type="button" class="icon-button media-lightbox-close" data-media-lightbox-close aria-label="Vorschau schließen"><span data-vd-icon="x"></span></button></header>
|
||
<div class="media-lightbox-toolbar" aria-label="Zoomsteuerung">
|
||
<button type="button" class="icon-button" id="media-zoom-out" aria-label="Verkleinern" title="Verkleinern"><span data-vd-icon="zoom-out"></span></button>
|
||
<input type="range" id="media-zoom-range" min="10" max="400" step="5" value="100" aria-label="Zoomstufe">
|
||
<button type="button" class="icon-button" id="media-zoom-in" aria-label="Vergrößern" title="Vergrößern"><span data-vd-icon="zoom-in"></span></button>
|
||
<button type="button" class="vd-button compact" id="media-zoom-fit"><span data-vd-icon="maximize"></span> Einpassen</button>
|
||
<button type="button" class="vd-button compact" id="media-zoom-original">100 %</button>
|
||
<output id="media-zoom-value">100 %</output>
|
||
</div>
|
||
<div class="media-lightbox-body"><div class="media-lightbox-stage" id="media-lightbox-stage"><div class="media-lightbox-canvas" id="media-lightbox-canvas"><img id="media-lightbox-image" alt="Bildvorschau" draggable="false"></div></div><aside id="media-lightbox-meta"></aside></div>
|
||
<footer><button type="button" class="vd-button primary" id="media-lightbox-edit"><span data-vd-icon="pencil"></span> Im Editor öffnen</button><a class="vd-button" id="media-lightbox-download" download><span data-vd-icon="download"></span> Herunterladen</a><button type="button" class="vd-button" id="media-lightbox-favorite"><span data-vd-icon="heart"></span> Favorit</button><button type="button" class="vd-button danger" id="media-lightbox-delete"><span data-vd-icon="trash-2"></span> Löschen</button></footer>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="modal-overlay hidden" id="quality-ai-modal" role="dialog" aria-modal="true" aria-labelledby="quality-ai-title">
|
||
<div class="modal quality-ai-modal">
|
||
<header><div><p class="eyebrow">Bestätigte AI-Verbesserung</p><h2 id="quality-ai-title">Artikel verbessern</h2><p>Die AI erstellt nur Vorschläge. Übernommen wird erst nach deiner Bestätigung.</p></div><button type="button" class="modal-close" id="quality-ai-close" aria-label="Schließen">×</button></header>
|
||
<div class="quality-ai-options">
|
||
<label><input type="checkbox" id="quality-ai-field-title" checked> Titel</label>
|
||
<label><input type="checkbox" id="quality-ai-field-description" checked> Beschreibung</label>
|
||
<label><input type="checkbox" id="quality-ai-field-tags" checked> Tags</label>
|
||
<label class="quality-ai-mode"><span>Profil</span><select id="quality-ai-mode"><option value="balanced">Ausgewogen</option><option value="concise">Kompakt</option><option value="sales">Verkaufsstark</option><option value="seo">Suchoptimiert</option></select></label>
|
||
</div>
|
||
<div class="quality-ai-status" id="quality-ai-status">Wähle die Felder und erstelle einen Vorschlag.</div>
|
||
<div class="quality-ai-compare hidden" id="quality-ai-compare">
|
||
<section><h3>Original</h3><label>Titel<textarea id="quality-ai-original-title" readonly></textarea></label><label>Beschreibung<textarea id="quality-ai-original-description" readonly></textarea></label><label>Tags<textarea id="quality-ai-original-tags" readonly></textarea></label></section>
|
||
<section><h3>Vorschlag</h3><label>Titel<textarea id="quality-ai-suggested-title"></textarea></label><label>Beschreibung<textarea id="quality-ai-suggested-description"></textarea></label><label>Tags<textarea id="quality-ai-suggested-tags"></textarea></label></section>
|
||
</div>
|
||
<div class="quality-ai-reasons" id="quality-ai-reasons"></div>
|
||
<footer><button type="button" class="vd-button" id="quality-ai-cancel">Abbrechen</button><button type="button" class="vd-button accent" id="quality-ai-generate">Vorschlag erstellen</button><button type="button" class="primary-btn hidden" id="quality-ai-apply">Bestätigt übernehmen</button></footer>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="toast" class="toast"></div>
|
||
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/qrious@4.0.2/dist/qrious.min.js"></script>
|
||
<script src="design-system/theme-runtime.js?v=1.41.2"></script>
|
||
<script src="vendoo-icons.js?v=1.41.2"></script>
|
||
<script src="app.js?v=1.41.2"></script>
|
||
<script type="module" src="modules/theme-manager/theme-manager.js?v=1.41.2"></script>
|
||
<script type="module" src="modules/module-manager/module-manager.js?v=1.41.2"></script>
|
||
|
||
|
||
|
||
</body>
|
||
</html>
|