Files
emailtemplate.it/public/index.php
2025-12-07 02:49:46 +01:00

302 lines
15 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
$base = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/') ?: '';
$assetVersion = defined('ASSET_VERSION') ? ASSET_VERSION : time();
?>
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Email Template System Admin</title>
<!-- UI bis zur Auth verdecken -->
<script>document.documentElement.classList.add('auth-pending');</script>
<style>
html.auth-pending body { visibility: hidden; }
</style>
<!-- Tailwind zuerst -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Admin-Theme (neu) -->
<link rel="stylesheet" href="assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
<!-- Toast danach -->
<link rel="stylesheet" href="assets/css/toast.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
<!-- Kleine Hilfs-Utilities (belassen, falls admin.css andere Werte hat) -->
<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-danger{border-color:#fecaca;color:#b91c1c}.btn-danger:hover{background:#fef2f2}
.chip{display:inline-flex;align-items:center;gap:.35rem;padding:.15rem .5rem;border-radius:999px;background:#f1f5f9;color:#334155;font-size:.75rem;border:1px solid #e5e7eb}
.chip .dot{width:.5rem;height:.5rem;border-radius:999px;background:#64748b}
dialog::backdrop{background:rgba(15,23,42,.3)}
#toast-root{z-index:2147483647}
.truncate{max-width:22rem;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.hidden{display:none}
.btn-avatar{padding:.35rem;border-radius:999px;width:38px;height:38px;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:1rem;margin-bottom:1.25rem}
.section-card h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#0f172a}
.input{width:100%;border:1px solid #cbd5f5;border-radius:.5rem;padding:.5rem .75rem}
.user-tabs{display:flex;gap:.5rem;margin-bottom:1rem}
.user-panel{width:90vw;max-width:960px}
.team-table{width:100%;border-collapse:collapse;font-size:.9rem}
.team-table th,.team-table td{padding:.35rem .5rem;border-bottom:1px solid #e2e8f0;text-align:left}
.badge{display:inline-flex;align-items:center;padding:.1rem .5rem;border-radius:999px;font-size:.75rem;background:#e2e8f0;color:#0f172a}
</style>
</head>
<body class="page-admin bg-slate-50 text-slate-800">
<header class="sticky top-0 z-30 bg-white/90 backdrop-blur border-b">
<div class="max-w-6xl mx-auto px-4 py-3 flex items-center gap-3">
<h1 class="font-semibold text-lg">Email Template System</h1>
<nav class="isolate inline-flex rounded-2xl shadow-sm border bg-white overflow-hidden ms-6">
<button type="button" data-tab="templates" class="px-4 py-2 text-sm border-e bg-sky-50 text-sky-700">Templates</button>
<button type="button" data-tab="sections" class="px-4 py-2 text-sm border-e">Sections</button>
<button type="button" data-tab="blocks" class="px-4 py-2 text-sm border-e">Blocks</button>
<button type="button" data-tab="snippets" class="px-4 py-2 text-sm">Snippets</button>
</nav>
<div class="ms-auto flex gap-2 items-center">
<button id="btn-new" type="button" class="btn">Neu …</button>
<button id="btn-user" type="button" class="btn-avatar" title="Mein Konto">
<span id="userAvatar">U</span>
</button>
</div>
</div>
</header>
<main class="max-w-6xl mx-auto p-4">
<section id="view-templates" class="view"></section>
<section id="view-sections" class="view hidden"></section>
<section id="view-blocks" class="view hidden"></section>
<section id="view-snippets" class="view hidden"></section>
</main>
<!-- Create Dialog -->
<dialog id="createDialog" class="rounded-2xl p-0 w-[540px]">
<form id="createForm" method="dialog" class="p-4 bg-white rounded-2xl">
<h3 class="text-lg font-semibold mb-2">Neues Element erstellen</h3>
<p id="createHint" class="text-sm text-slate-600 mb-3"></p>
<div class="space-y-3" id="createFields"></div>
<div class="mt-4 flex justify-end gap-2">
<button type="button" id="createCancel" class="btn">Abbrechen</button>
<button type="submit" id="createSubmit" class="btn">Erstellen</button>
</div>
</form>
</dialog>
<!-- Delete Confirm Dialog -->
<dialog id="deleteDialog" class="rounded-2xl p-0 w-[520px]">
<form id="deleteForm" method="dialog" class="p-4 bg-white rounded-2xl">
<h3 class="text-lg font-semibold mb-2">Eintrag löschen?</h3>
<p id="deleteText" class="text-sm text-slate-600 mb-4"></p>
<div class="mt-1 flex justify-end gap-2">
<button type="button" id="deleteCancel" class="btn">Abbrechen</button>
<button type="submit" class="btn btn-danger">Löschen</button>
</div>
</form>
</dialog>
<!-- Editor Dialog -->
<dialog id="editorDialog" class="rounded-2xl p-0 w-[95vw] h-[90vh]">
<div class="h-full flex flex-col">
<div class="px-4 py-2 border-b flex items-center gap-2 bg-white/80 backdrop-blur">
<strong class="me-auto">E-Mail Editor</strong>
<button id="btn-clear-main" type="button" class="btn" title="Leeren">🧹</button>
<button id="btn-preview" type="button" class="btn">Vorschau</button>
<button id="btn-test" type="button" class="btn">Testversand</button>
<button id="btn-save" type="button" class="btn">Speichern</button>
<button id="btn-close" type="button" class="btn">Schließen</button>
</div>
<iframe id="editorFrame" src="about:blank" class="flex-1 w-full"></iframe>
</div>
</dialog>
<!-- Preview Dialog -->
<dialog id="previewDialog" class="rounded-2xl p-0 w-[90vw] h-[90vh]">
<div class="h-full flex flex-col">
<div class="px-4 py-2 border-b flex items-center gap-2 bg-white/80 backdrop-blur">
<strong class="me-auto">Vorschau</strong>
<button id="btn-close-preview" type="button" class="btn">Schließen</button>
</div>
<iframe id="previewFrame" class="flex-1 w-full"></iframe>
</div>
</dialog>
<!-- Test Send Dialog -->
<dialog id="sendTestDialog" class="rounded-2xl p-0 w-[480px]">
<form id="sendTestForm" method="dialog" class="p-4 bg-white rounded-2xl space-y-4">
<h3 class="text-lg font-semibold">Testversand</h3>
<p id="send_template_info" class="text-sm text-slate-600">Kein Template ausgewählt.</p>
<label class="block">
<span class="text-sm text-slate-600">Empfänger (E-Mail)</span>
<input id="send_to" type="email" required class="mt-1 w-full border rounded-lg px-3 py-2" placeholder="name@example.com" />
</label>
<label class="block">
<span class="text-sm text-slate-600">Betreff</span>
<input id="send_subject" type="text" class="mt-1 w-full border rounded-lg px-3 py-2" value="Testversand" />
</label>
<div class="flex justify-end gap-2">
<button type="button" id="btn-cancel-send" class="btn">Abbrechen</button>
<button type="submit" id="btn-send-now" class="btn">Senden</button>
</div>
</form>
</dialog>
<!-- Edit Snippet Dialog -->
<dialog id="editSnippetDialog" class="rounded-2xl p-0 w-[700px]">
<form id="editSnippetForm" method="dialog" class="p-4 bg-white rounded-2xl">
<h3 class="text-lg font-semibold mb-2">Snippet bearbeiten</h3>
<div class="space-y-3">
<label class="block">
<span class="text-sm text-slate-600">Name</span>
<input id="edit_snip_name" type="text" class="w-full border rounded-lg px-3 py-2" />
</label>
<label class="block">
<span class="text-sm text-slate-600">Content (HTML)</span>
<textarea id="edit_snip_content" class="w-full border rounded-lg px-3 py-2 h-64 font-mono text-sm"></textarea>
</label>
</div>
<div class="mt-4 flex justify-end gap-2">
<button type="button" id="editSnippetCancel" class="btn">Abbrechen</button>
<button type="submit" id="editSnippetSave" class="btn">Speichern</button>
</div>
</form>
</dialog>
<!-- User Account Dialog -->
<dialog id="userDialog" class="rounded-2xl p-0 user-panel">
<div class="flex flex-col bg-white rounded-2xl max-h-[90vh]">
<div class="px-4 py-3 border-b flex items-center gap-3 bg-white/80 backdrop-blur rounded-t-2xl">
<strong class="text-lg me-auto">Mein Konto</strong>
<button type="button" id="userClose" class="btn">Schließen</button>
</div>
<div class="p-4 overflow-y-auto flex-1">
<div class="user-tabs">
<button type="button" data-user-tab="profile" class="btn bg-sky-50 text-sky-700 flex-1">Profil</button>
<button type="button" data-user-tab="security" class="btn flex-1">Passwort</button>
<button type="button" data-user-tab="team" class="btn flex-1 owner-only hidden">Team</button>
<button type="button" data-user-tab="integration" class="btn flex-1 owner-only hidden">Integrationen</button>
</div>
<section data-user-panel="profile" class="section-card">
<h4>Profil</h4>
<form id="profileForm" class="space-y-3">
<label class="block text-sm text-slate-600">Name
<input type="text" id="profile_name" name="name" class="input mt-1" required>
</label>
<label class="block text-sm text-slate-600">E-Mail
<input type="email" id="profile_email" name="email" class="input mt-1" required>
</label>
<div class="flex justify-end">
<button type="submit" class="btn">Speichern</button>
</div>
</form>
</section>
<section data-user-panel="security" class="section-card hidden">
<h4>Passwort ändern</h4>
<form id="passwordForm" class="space-y-3">
<label class="block text-sm text-slate-600">Aktuelles Passwort
<input type="password" name="current_password" class="input mt-1" required>
</label>
<label class="block text-sm text-slate-600">Neues Passwort (min. 8 Zeichen)
<input type="password" name="new_password" class="input mt-1" required minlength="8">
</label>
<div class="flex justify-end">
<button type="submit" class="btn">Aktualisieren</button>
</div>
</form>
</section>
<section data-user-panel="team" class="section-card hidden owner-only">
<div class="flex items-center justify-between mb-2">
<h4>Team</h4>
<button type="button" id="btn-user-add" class="btn">+ Nutzer</button>
</div>
<div class="overflow-auto">
<table class="team-table" id="teamTable">
<thead>
<tr><th>Name</th><th>E-Mail</th><th>Rolle</th><th>Status</th><th class="text-right">Aktionen</th></tr>
</thead>
<tbody></tbody>
</table>
</div>
<form id="userForm" class="space-y-3 mt-4 hidden">
<input type="hidden" name="user_id">
<label class="block text-sm text-slate-600">Name
<input type="text" name="name" class="input mt-1" required>
</label>
<label class="block text-sm text-slate-600">E-Mail
<input type="email" name="email" class="input mt-1" required>
</label>
<label class="block text-sm text-slate-600">Rolle
<select name="role" class="input mt-1">
<option value="owner">Owner</option>
<option value="admin">Admin</option>
<option value="editor">Editor</option>
<option value="viewer">Viewer</option>
</select>
</label>
<label class="inline-flex items-center gap-2 text-sm text-slate-600">
<input type="checkbox" name="is_active" checked> Aktiv
</label>
<label class="inline-flex items-center gap-2 text-sm text-slate-600 reset-only hidden">
<input type="checkbox" name="reset_password"> Passwort zurücksetzen
</label>
<div class="flex justify-end gap-2">
<button type="button" id="userFormCancel" class="btn">Abbrechen</button>
<button type="submit" class="btn">Speichern</button>
</div>
</form>
</section>
<section data-user-panel="integration" class="section-card hidden owner-only">
<h4>Integrationen & Tokens</h4>
<form id="settingsForm" class="space-y-3">
<label class="block text-sm text-slate-600">Bridge-URL
<input type="url" name="bridge_url" class="input mt-1" placeholder="https://domain.tld/emailtemplate_bridge.php">
</label>
<div>
<label class="block text-sm text-slate-600">Bridge Token</label>
<div class="flex gap-2 mt-1">
<input type="text" name="bridge_token" class="input" readonly>
<button type="button" class="btn" data-rotate="bridge">Neu erstellen</button>
</div>
</div>
<div>
<label class="block text-sm text-slate-600">Sender Token</label>
<div class="flex gap-2 mt-1">
<input type="text" name="sender_token" class="input" readonly>
<button type="button" class="btn" data-rotate="sender">Neu erstellen</button>
</div>
</div>
<div>
<label class="block text-sm text-slate-600">Externer API-Token</label>
<div class="flex gap-2 mt-1">
<input type="text" name="external_api_token" class="input" readonly>
<button type="button" class="btn" data-rotate="external">Neu erstellen</button>
</div>
</div>
<div class="flex justify-between gap-2 flex-wrap pt-2">
<div class="flex gap-2">
<button type="button" class="btn" data-download="bridge">Bridge-Datei</button>
<button type="button" class="btn" data-download="sender">Sender-Datei</button>
</div>
<button type="submit" class="btn ms-auto">Einstellungen speichern</button>
</div>
</form>
</section>
</div>
</div>
</dialog>
<div id="toast-root"></div>
<script src="assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
<script type="module" src="assets/js/app.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
<script type="module" src="assets/js/ui-user.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
</body>
</html>