This commit is contained in:
2025-12-09 00:21:01 +01:00
parent 9488fe1ea4
commit ad89392ff1
8 changed files with 788 additions and 124 deletions

View File

@@ -0,0 +1,158 @@
<?php
$assetVersion = defined('ASSET_VERSION') ? ASSET_VERSION : time();
$appBaseUrl = rtrim($GLOBALS['app_base_url'] ?? '', '/');
$assetBase = $appBaseUrl !== '' ? $appBaseUrl : '';
$appApiBase = rtrim($GLOBALS['app_api_base'] ?? '', '/');
$debugRedirect = isset($_GET['debug_redirect']);
?>
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Email Template System Bridge Setup</title>
<script>document.documentElement.classList.add('auth-pending');</script>
<style>html.auth-pending body{visibility:hidden;}</style>
<script>
window.APP_BASE_URL = <?= json_encode($appBaseUrl, JSON_UNESCAPED_SLASHES) ?>;
window.APP_API_BASE = <?= json_encode($appApiBase, JSON_UNESCAPED_SLASHES) ?>;
<?php if ($debugRedirect): ?>
window.DISABLE_AUTH_REDIRECT = true;
<?php endif; ?>
</script>
<script src="https://cdn.tailwindcss.com"></script>
<?php if ($debugRedirect): ?>
<script src="<?= $assetBase ?>/assets/js/debug-location.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
<?php endif; ?>
<link rel="stylesheet" href="<?= $assetBase ?>/assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
<link rel="stylesheet" href="<?= $assetBase ?>/assets/css/toast.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
<style>
:root { color-scheme: light; }
.btn{display:inline-flex;align-items:center;gap:.5rem;padding:.35rem .7rem;border-radius:.7rem;border:1px solid #e5e7eb;background:#fff;font-size:.9rem;cursor:pointer;}
.btn:hover{background:#f8fafc}
.btn-avatar{padding:.35rem;border-radius:999px;width:42px;height:42px;justify-content:center;font-weight:600;background:#0ea5e9;color:#fff;border:none}
.btn-avatar:hover{background:#0284c7}
.section-card{background:#fff;border:1px solid #e2e8f0;border-radius:1rem;padding:1.25rem;margin-bottom:1.5rem}
.section-card h4{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#0f172a}
.input{width:100%;border:1px solid #cbd5f5;border-radius:.5rem;padding:.5rem .75rem}
.badge{display:inline-flex;align-items:center;padding:.1rem .5rem;border-radius:999px;font-size:.75rem;background:#e2e8f0;color:#0f172a}
.chip{display:inline-flex;align-items:center;padding:.15rem .55rem;border-radius:999px;background:#f1f5f9;color:#0f172a;border:1px solid #e2e8f0;font-size:.8rem}
</style>
</head>
<body class="bg-slate-50 text-slate-800" data-page="bridge-setup">
<header class="sticky top-0 z-30 bg-white/90 border-b backdrop-blur">
<div class="max-w-4xl mx-auto px-4 py-4 flex items-center gap-3">
<a href="<?= $appBaseUrl ?>/admin/settings.php" class="btn" title="Zurück zur Administration">← Administration</a>
<h1 class="font-semibold text-lg">Bridge Setup</h1>
<div class="ms-auto flex gap-2 items-center">
<div class="relative" id="userMenu">
<button id="btn-user" type="button" class="btn-avatar" aria-haspopup="true" aria-expanded="false">
<span id="userAvatar">U</span>
</button>
<div id="userMenuPanel" class="user-menu hidden" role="menu">
<a href="<?= $appBaseUrl ?>/admin/profile.php" class="user-menu-item" data-menu="profile">Profil</a>
<a href="<?= $appBaseUrl ?>/admin/dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
<a href="<?= $appBaseUrl ?>/admin/settings.php" class="user-menu-item" data-role="admin">Administration</a>
<button id="btn-logout" type="button" class="user-menu-item text-red-600">Logout</button>
</div>
</div>
</div>
</div>
</header>
<main class="max-w-4xl mx-auto p-4 md:p-6 space-y-6">
<section class="section-card">
<h4>Bridge-Datei vorbereiten</h4>
<p class="text-sm text-slate-600 mb-3">
Diese Angaben werden nur verwendet, um die <strong>emailtemplate_bridge.php</strong> zu generieren. Das EmailTemplate-System selbst behält Zugriff auf alle Tabellen; die hier definierten Whitelists greifen ausschließlich in der Bridge-Datei.
</p>
<form id="bridgeSetupForm" class="space-y-4">
<div>
<label class="block text-sm text-slate-600">Tabellen-Whitelist (optional)</label>
<textarea name="tables" class="input mt-1" rows="3" placeholder="z.B. customers, orders"></textarea>
<p class="text-xs text-slate-500 mt-1">Kommagetrennt oder je Zeile eine Tabelle. Leer lassen = keine Einschränkung.</p>
<div id="selectedTables" class="flex flex-wrap gap-2 text-sm text-slate-600 mt-2">Noch keine Tabellen angegeben.</div>
</div>
<fieldset class="border border-slate-200 rounded-xl p-4">
<legend class="px-2 text-sm font-semibold">Datenbankquelle</legend>
<div class="flex flex-wrap gap-4 text-sm text-slate-600 mb-3">
<label class="inline-flex items-center gap-2">
<input type="radio" name="db_mode" value="direct" checked> Direkte Angaben (Host, DB, Benutzer …)
</label>
<label class="inline-flex items-center gap-2">
<input type="radio" name="db_mode" value="config"> Aus bestehender Konfigurationsdatei laden
</label>
</div>
<div id="directFields" class="grid md:grid-cols-2 gap-3">
<label class="block text-sm text-slate-600">Server / Host
<input type="text" name="direct_host" class="input mt-1" placeholder="127.0.0.1">
</label>
<label class="block text-sm text-slate-600">Port
<input type="number" name="direct_port" class="input mt-1" placeholder="3306">
</label>
<label class="block text-sm text-slate-600">Datenbankname
<input type="text" name="direct_database" class="input mt-1" placeholder="kunden_db">
</label>
<label class="block text-sm text-slate-600">Zeichensatz
<input type="text" name="direct_charset" class="input mt-1" value="utf8mb4">
</label>
<label class="block text-sm text-slate-600">Benutzername
<input type="text" name="direct_user" class="input mt-1" placeholder="db_user">
</label>
<label class="block text-sm text-slate-600">Passwort
<input type="text" name="direct_password" class="input mt-1" placeholder="••••">
</label>
</div>
<div id="configFields" class="hidden space-y-3">
<div>
<label class="block text-sm text-slate-600">Pfad zur Konfigurationsdatei</label>
<input type="text" name="config_file" class="input mt-1" placeholder="../config/database.php">
<p class="text-xs text-slate-500 mt-1">Relativ zur Bridge-Datei oder absolut. Die Datei sollte ein Array oder Objekt mit den Zugangsdaten liefern.</p>
</div>
<div>
<label class="block text-sm text-slate-600">Basis-Pfad im Array (optional)</label>
<input type="text" name="config_base" class="input mt-1" placeholder="database.connections.mysql">
<p class="text-xs text-slate-500 mt-1">Dot-Notation, um in verschachtelte Arrays zu springen.</p>
</div>
<div class="grid md:grid-cols-2 gap-3">
<label class="block text-sm text-slate-600">Host-Key
<input type="text" name="config_host_key" class="input mt-1" placeholder="host">
</label>
<label class="block text-sm text-slate-600">Port-Key
<input type="text" name="config_port_key" class="input mt-1" placeholder="port">
</label>
<label class="block text-sm text-slate-600">DB-Name-Key
<input type="text" name="config_database_key" class="input mt-1" placeholder="database">
</label>
<label class="block text-sm text-slate-600">Charset-Key
<input type="text" name="config_charset_key" class="input mt-1" placeholder="charset">
</label>
<label class="block text-sm text-slate-600">User-Key
<input type="text" name="config_user_key" class="input mt-1" placeholder="username">
</label>
<label class="block text-sm text-slate-600">Passwort-Key
<input type="text" name="config_password_key" class="input mt-1" placeholder="password">
</label>
</div>
<p class="text-xs text-slate-500">Alle Keys nutzen Dot-Notation relativ zum Basis-Pfad.</p>
</div>
</fieldset>
<div class="flex flex-wrap gap-2">
<button type="button" id="btn-load-remote" class="btn" data-role="admin">Tabellen vom Bridge-Endpunkt laden</button>
<button type="submit" class="btn">Bridge-Setup speichern</button>
</div>
<div id="setupStatus" class="text-xs text-slate-500">Noch nicht gespeichert.</div>
</form>
</section>
</main>
<div id="toast-root"></div>
<script src="<?= $assetBase ?>/assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
<script type="module" src="<?= $assetBase ?>/assets/js/bridge-setup.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
</body>
</html>

View File

@@ -170,14 +170,9 @@ $debugRedirect = isset($_GET['debug_redirect']);
<button type="button" class="btn" data-rotate="external">Neu erstellen</button>
</div>
</div>
<div>
<label class="block text-sm text-slate-600">Verfügbare Tabellen (kommagetrennt oder Zeilen)</label>
<textarea name="bridge_tables" class="input mt-1" rows="3" placeholder="z.B. customers, orders"></textarea>
<p class="text-xs text-slate-500 mt-1">Nur diese Tabellen werden als Platzhalter angeboten. Leer = alle.</p>
</div>
<div class="flex flex-col gap-2">
<button type="button" id="btn-validate-bridge" class="btn w-max" data-role="admin">Verbindung prüfen & Tabellen laden</button>
<div id="bridgeTablesPreview" class="flex flex-wrap gap-2 text-sm text-slate-600">Noch nicht geprüft.</div>
<a href="<?= $appBaseUrl ?>/admin/bridge.php" class="btn w-max" data-role="admin">Bridge-Setup & Tabellen öffnen</a>
<p class="text-xs text-slate-500">Dort kannst du Tabellen-Filter sowie DB-Quellen für die Bridge-Datei konfigurieren.</p>
</div>
<div class="flex justify-between gap-2 flex-wrap pt-2">
<div class="flex gap-2" data-role="admin">