update
This commit is contained in:
110
partials/landingpage/admin/dashboard.php
Normal file
110
partials/landingpage/admin/dashboard.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
$assetVersion = defined('ASSET_VERSION') ? ASSET_VERSION : time();
|
||||
$base = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/') ?: '';
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>Email Template System – Dashboard</title>
|
||||
<script>document.documentElement.classList.add('auth-pending');</script>
|
||||
<style>html.auth-pending body{visibility:hidden;}</style>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="<?= $base ?>/assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<link rel="stylesheet" href="<?= $base ?>/assets/css/toast.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<style>
|
||||
:root { color-scheme: light; }
|
||||
.btn{display:inline-flex;align-items:center;gap:.4rem;padding:.4rem .8rem;border-radius:.8rem;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}
|
||||
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:1rem;margin-bottom:1.5rem}
|
||||
.stat-card{background:#fff;border:1px solid #e2e8f0;border-radius:1rem;padding:1.25rem}
|
||||
.stat-card h4{margin:0;font-size:.95rem;color:#475569}
|
||||
.stat-card strong{display:block;font-size:1.75rem;color:#0f172a}
|
||||
.section-card{background:#fff;border:1px solid #e2e8f0;border-radius:1rem;padding:1.25rem;margin-bottom:1.5rem}
|
||||
.usage-table{width:100%;border-collapse:collapse;font-size:.9rem}
|
||||
.usage-table th,.usage-table td{padding:.5rem;border-bottom:1px solid #e2e8f0;text-align:left}
|
||||
.user-menu{position:absolute;top:calc(100% + .5rem);right:0;min-width:180px;background:#fff;border:1px solid #e2e8f0;border-radius:.75rem;box-shadow:0 20px 35px rgba(15,23,42,.15);padding:.35rem;z-index:40}
|
||||
.user-menu-item{display:block;width:100%;text-align:left;padding:.45rem .75rem;border-radius:.6rem;font-size:.9rem;color:#0f172a}
|
||||
.user-menu-item:hover{background:#f1f5f9}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800" data-page="dashboard">
|
||||
<header class="sticky top-0 z-30 bg-white/90 border-b backdrop-blur">
|
||||
<div class="max-w-5xl mx-auto px-4 py-4 flex items-center gap-3">
|
||||
<a href="<?= $base ?>/index.php" class="btn" title="Zurück zur Übersicht">← Übersicht</a>
|
||||
<h1 class="font-semibold text-lg">Dashboard</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="<?= $base ?>/admin/profile.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="<?= $base ?>/admin/dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="<?= $base ?>/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-5xl mx-auto p-4 md:p-6">
|
||||
<section class="stat-grid" id="dashboardCounts">
|
||||
<div class="stat-card">
|
||||
<h4>Templates</h4>
|
||||
<strong id="count-templates">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Sections</h4>
|
||||
<strong id="count-sections">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Blocks</h4>
|
||||
<strong id="count-blocks">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Snippets</h4>
|
||||
<strong id="count-snippets">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Aufrufe gesamt</h4>
|
||||
<strong id="count-usage">–</strong>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card" data-role="admin">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div>
|
||||
<h4>Template-Nutzung</h4>
|
||||
<p class="text-sm text-slate-600">Wie oft wurden Templates über die API geladen? Setze einzelne Zähler bei Bedarf zurück.</p>
|
||||
</div>
|
||||
<button type="button" class="btn" id="btn-refresh-dashboard">Aktualisieren</button>
|
||||
</div>
|
||||
<div class="overflow-auto">
|
||||
<table class="usage-table" id="usageTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Template</th>
|
||||
<th>Aufrufe</th>
|
||||
<th>Zuletzt verwendet</th>
|
||||
<th class="text-right">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td colspan="4" class="text-sm text-slate-500">Lade Daten…</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="toast-root"></div>
|
||||
|
||||
<script src="<?= $base ?>/assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
<script type="module" src="<?= $base ?>/assets/js/dashboard.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
103
partials/landingpage/admin/profile.php
Normal file
103
partials/landingpage/admin/profile.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?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 – Konto</title>
|
||||
<script>document.documentElement.classList.add('auth-pending');</script>
|
||||
<style>html.auth-pending body{visibility:hidden;}</style>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="<?= $base ?>/assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<link rel="stylesheet" href="<?= $base ?>/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[aria-disabled="true"]{pointer-events: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}
|
||||
.user-tabs{display:flex;gap:.5rem;margin-bottom:1.25rem}
|
||||
.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}
|
||||
.chip{display:inline-flex;align-items:center;padding:.15rem .55rem;border-radius:999px;background:#f1f5f9;color:#0f172a;border:1px solid #e2e8f0;font-size:.8rem}
|
||||
.user-menu{position:absolute;top:calc(100% + .5rem);right:0;min-width:180px;background:#fff;border:1px solid #e2e8f0;border-radius:.75rem;box-shadow:0 20px 35px rgba(15,23,42,.15);padding:.35rem;z-index:40}
|
||||
.user-menu-item{display:block;width:100%;text-align:left;padding:.45rem .75rem;border-radius:.6rem;font-size:.9rem;color:#0f172a}
|
||||
.user-menu-item:hover{background:#f1f5f9}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800" data-page="account">
|
||||
<header class="sticky top-0 z-30 bg-white/90 border-b backdrop-blur">
|
||||
<div class="max-w-5xl mx-auto px-4 py-4 flex items-center gap-3">
|
||||
<a href="<?= $base ?>/index.php" class="btn" title="Zurück zur Übersicht">← Übersicht</a>
|
||||
<h1 class="font-semibold text-lg">Mein Konto</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="<?= $base ?>/admin/profile.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="<?= $base ?>/admin/dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="<?= $base ?>/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-5xl mx-auto p-4 md:p-6">
|
||||
<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>
|
||||
</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 class="section-card">
|
||||
<p class="text-sm text-slate-600">Teammitglieder, Absender und Integrationen verwaltest du im Bereich <strong>Administration</strong>. Öffne ihn über das Avatar-Menü oben rechts.</p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="toast-root"></div>
|
||||
|
||||
<script src="<?= $base ?>/assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
<script type="module" src="<?= $base ?>/assets/js/account.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
185
partials/landingpage/admin/settings.php
Normal file
185
partials/landingpage/admin/settings.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?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 – Administration</title>
|
||||
<script>document.documentElement.classList.add('auth-pending');</script>
|
||||
<style>html.auth-pending body{visibility:hidden;}</style>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="<?= $base ?>/assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<link rel="stylesheet" href="<?= $base ?>/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}
|
||||
.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}
|
||||
.chip{display:inline-flex;align-items:center;padding:.15rem .55rem;border-radius:999px;background:#f1f5f9;color:#0f172a;border:1px solid #e2e8f0;font-size:.8rem}
|
||||
.user-menu{position:absolute;top:calc(100% + .5rem);right:0;min-width:180px;background:#fff;border:1px solid #e2e8f0;border-radius:.75rem;box-shadow:0 20px 35px rgba(15,23,42,.15);padding:.35rem;z-index:40}
|
||||
.user-menu-item{display:block;width:100%;text-align:left;padding:.45rem .75rem;border-radius:.6rem;font-size:.9rem;color:#0f172a}
|
||||
.user-menu-item:hover{background:#f1f5f9}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800" data-page="admin">
|
||||
<header class="sticky top-0 z-30 bg-white/90 border-b backdrop-blur">
|
||||
<div class="max-w-5xl mx-auto px-4 py-4 flex items-center gap-3">
|
||||
<a href="<?= $base ?>/index.php" class="btn" title="Zurück zur Übersicht">← Übersicht</a>
|
||||
<h1 class="font-semibold text-lg">Administration</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="<?= $base ?>/admin/profile.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="<?= $base ?>/admin/dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="<?= $base ?>/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-5xl mx-auto p-4 md:p-6 space-y-6">
|
||||
<section class="section-card" data-role="owner">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<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 class="section-card" data-role="admin">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<h4>Absender für Testmails</h4>
|
||||
<button type="button" id="btn-sender-add" class="btn">+ Absender</button>
|
||||
</div>
|
||||
<div class="overflow-auto">
|
||||
<table class="team-table" id="senderTable">
|
||||
<thead>
|
||||
<tr><th>Bezeichnung</th><th>From-Name</th><th>E-Mail</th><th>Reply-To</th><th class="text-right">Aktionen</th></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<form id="senderForm" class="space-y-3 mt-4 hidden">
|
||||
<input type="hidden" name="sender_id">
|
||||
<label class="block text-sm text-slate-600">Bezeichnung
|
||||
<input type="text" name="label" class="input mt-1" placeholder="Interner Name (optional)">
|
||||
</label>
|
||||
<label class="block text-sm text-slate-600">Absender-Name
|
||||
<input type="text" name="from_name" class="input mt-1" placeholder="z.B. Newsletter Team">
|
||||
</label>
|
||||
<label class="block text-sm text-slate-600">Absender-E-Mail
|
||||
<input type="email" name="from_email" class="input mt-1" required placeholder="news@example.com">
|
||||
</label>
|
||||
<label class="block text-sm text-slate-600">Reply-To (optional)
|
||||
<input type="email" name="reply_to" class="input mt-1" placeholder="support@example.com">
|
||||
</label>
|
||||
<div class="flex justify-end gap-2">
|
||||
<button type="button" id="senderFormCancel" class="btn">Abbrechen</button>
|
||||
<button type="submit" class="btn">Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="section-card" data-role="admin">
|
||||
<h4>Integrationen, Downloads & Tokens</h4>
|
||||
<p class="text-sm text-slate-600 mb-4">Die Dateien enthalten automatisch deine aktuellen Tokens. Nach dem Speichern neuer Tokens bitte die Dateien erneut herunterladen.</p>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="flex justify-between gap-2 flex-wrap pt-2">
|
||||
<div class="flex gap-2" data-role="admin">
|
||||
<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>
|
||||
</main>
|
||||
|
||||
<div id="toast-root"></div>
|
||||
|
||||
<script src="<?= $base ?>/assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
<script type="module" src="<?= $base ?>/assets/js/account.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,103 +1,3 @@
|
||||
<?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 – Konto</title>
|
||||
<script>document.documentElement.classList.add('auth-pending');</script>
|
||||
<style>html.auth-pending body{visibility:hidden;}</style>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<link rel="stylesheet" href="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[aria-disabled="true"]{pointer-events: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}
|
||||
.user-tabs{display:flex;gap:.5rem;margin-bottom:1.25rem}
|
||||
.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}
|
||||
.chip{display:inline-flex;align-items:center;padding:.15rem .55rem;border-radius:999px;background:#f1f5f9;color:#0f172a;border:1px solid #e2e8f0;font-size:.8rem}
|
||||
.user-menu{position:absolute;top:calc(100% + .5rem);right:0;min-width:180px;background:#fff;border:1px solid #e2e8f0;border-radius:.75rem;box-shadow:0 20px 35px rgba(15,23,42,.15);padding:.35rem;z-index:40}
|
||||
.user-menu-item{display:block;width:100%;text-align:left;padding:.45rem .75rem;border-radius:.6rem;font-size:.9rem;color:#0f172a}
|
||||
.user-menu-item:hover{background:#f1f5f9}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800" data-page="account">
|
||||
<header class="sticky top-0 z-30 bg-white/90 border-b backdrop-blur">
|
||||
<div class="max-w-5xl mx-auto px-4 py-4 flex items-center gap-3">
|
||||
<a href="./" class="btn" title="Zurück zur Übersicht">← Übersicht</a>
|
||||
<h1 class="font-semibold text-lg">Mein Konto</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="account.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="admin.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-5xl mx-auto p-4 md:p-6">
|
||||
<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>
|
||||
</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 class="section-card">
|
||||
<p class="text-sm text-slate-600">Teammitglieder, Absender und Integrationen verwaltest du jetzt im neuen Bereich <strong>Administration</strong>. Öffne ihn über das Avatar-Menü oben rechts.</p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="toast-root"></div>
|
||||
|
||||
<script src="assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
<script type="module" src="assets/js/account.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
header('Location: /admin/profile.php', true, 301);
|
||||
exit;
|
||||
|
||||
186
public/admin.php
186
public/admin.php
@@ -1,185 +1,3 @@
|
||||
<?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 – Administration</title>
|
||||
<script>document.documentElement.classList.add('auth-pending');</script>
|
||||
<style>html.auth-pending body{visibility:hidden;}</style>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<link rel="stylesheet" href="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}
|
||||
.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}
|
||||
.chip{display:inline-flex;align-items:center;padding:.15rem .55rem;border-radius:999px;background:#f1f5f9;color:#0f172a;border:1px solid #e2e8f0;font-size:.8rem}
|
||||
.user-menu{position:absolute;top:calc(100% + .5rem);right:0;min-width:180px;background:#fff;border:1px solid #e2e8f0;border-radius:.75rem;box-shadow:0 20px 35px rgba(15,23,42,.15);padding:.35rem;z-index:40}
|
||||
.user-menu-item{display:block;width:100%;text-align:left;padding:.45rem .75rem;border-radius:.6rem;font-size:.9rem;color:#0f172a}
|
||||
.user-menu-item:hover{background:#f1f5f9}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800" data-page="admin">
|
||||
<header class="sticky top-0 z-30 bg-white/90 border-b backdrop-blur">
|
||||
<div class="max-w-5xl mx-auto px-4 py-4 flex items-center gap-3">
|
||||
<a href="./" class="btn" title="Zurück zur Übersicht">← Übersicht</a>
|
||||
<h1 class="font-semibold text-lg">Administration</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="account.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="admin.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-5xl mx-auto p-4 md:p-6 space-y-6">
|
||||
<section class="section-card" data-role="owner">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<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 class="section-card" data-role="admin">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<h4>Absender für Testmails</h4>
|
||||
<button type="button" id="btn-sender-add" class="btn">+ Absender</button>
|
||||
</div>
|
||||
<div class="overflow-auto">
|
||||
<table class="team-table" id="senderTable">
|
||||
<thead>
|
||||
<tr><th>Bezeichnung</th><th>From-Name</th><th>E-Mail</th><th>Reply-To</th><th class="text-right">Aktionen</th></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<form id="senderForm" class="space-y-3 mt-4 hidden">
|
||||
<input type="hidden" name="sender_id">
|
||||
<label class="block text-sm text-slate-600">Bezeichnung
|
||||
<input type="text" name="label" class="input mt-1" placeholder="Interner Name (optional)">
|
||||
</label>
|
||||
<label class="block text-sm text-slate-600">Absender-Name
|
||||
<input type="text" name="from_name" class="input mt-1" placeholder="z.B. Newsletter Team">
|
||||
</label>
|
||||
<label class="block text-sm text-slate-600">Absender-E-Mail
|
||||
<input type="email" name="from_email" class="input mt-1" required placeholder="news@example.com">
|
||||
</label>
|
||||
<label class="block text-sm text-slate-600">Reply-To (optional)
|
||||
<input type="email" name="reply_to" class="input mt-1" placeholder="support@example.com">
|
||||
</label>
|
||||
<div class="flex justify-end gap-2">
|
||||
<button type="button" id="senderFormCancel" class="btn">Abbrechen</button>
|
||||
<button type="submit" class="btn">Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="section-card" data-role="admin">
|
||||
<h4>Integrationen, Downloads & Tokens</h4>
|
||||
<p class="text-sm text-slate-600 mb-4">Die Dateien enthalten automatisch deine aktuellen Tokens. Nach dem Speichern neuer Tokens bitte die Dateien erneut herunterladen.</p>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="flex justify-between gap-2 flex-wrap pt-2">
|
||||
<div class="flex gap-2" data-role="admin">
|
||||
<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>
|
||||
</main>
|
||||
|
||||
<div id="toast-root"></div>
|
||||
|
||||
<script src="assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
<script type="module" src="assets/js/account.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
header('Location: /admin/settings.php', true, 301);
|
||||
exit;
|
||||
|
||||
2
public/admin/dashboard.php
Normal file
2
public/admin/dashboard.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
require dirname(__DIR__, 2) . '/partials/landingpage/admin/dashboard.php';
|
||||
2
public/admin/profile.php
Normal file
2
public/admin/profile.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
require dirname(__DIR__, 2) . '/partials/landingpage/admin/profile.php';
|
||||
2
public/admin/settings.php
Normal file
2
public/admin/settings.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
require dirname(__DIR__, 2) . '/partials/landingpage/admin/settings.php';
|
||||
@@ -26,7 +26,7 @@ function ensureAccess() {
|
||||
const role = (window.__currentUser?.role || '').toLowerCase();
|
||||
if (role !== 'owner' && role !== 'admin') {
|
||||
toast('Kein Zugriff auf das Dashboard', false);
|
||||
window.location.href = '/account.php';
|
||||
window.location.href = '/admin/profile.php';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -123,7 +123,7 @@ function enforcePageAccess() {
|
||||
if (pageType !== 'admin') return;
|
||||
if (isAdmin()) return;
|
||||
toast('Kein Zugriff auf diesen Bereich', false, { duration: 2500 });
|
||||
window.location.href = '/account.php';
|
||||
window.location.href = '/admin/profile.php';
|
||||
}
|
||||
|
||||
function handleUserContextChange() {
|
||||
|
||||
@@ -1,109 +1,3 @@
|
||||
<?php
|
||||
$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 – Dashboard</title>
|
||||
<script>document.documentElement.classList.add('auth-pending');</script>
|
||||
<style>html.auth-pending body{visibility:hidden;}</style>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="assets/css/admin.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<link rel="stylesheet" href="assets/css/toast.css?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>">
|
||||
<style>
|
||||
:root { color-scheme: light; }
|
||||
.btn{display:inline-flex;align-items:center;gap:.4rem;padding:.4rem .8rem;border-radius:.8rem;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}
|
||||
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:1rem;margin-bottom:1.5rem}
|
||||
.stat-card{background:#fff;border:1px solid #e2e8f0;border-radius:1rem;padding:1.25rem}
|
||||
.stat-card h4{margin:0;font-size:.95rem;color:#475569}
|
||||
.stat-card strong{display:block;font-size:1.75rem;color:#0f172a}
|
||||
.section-card{background:#fff;border:1px solid #e2e8f0;border-radius:1rem;padding:1.25rem;margin-bottom:1.5rem}
|
||||
.usage-table{width:100%;border-collapse:collapse;font-size:.9rem}
|
||||
.usage-table th,.usage-table td{padding:.5rem;border-bottom:1px solid #e2e8f0;text-align:left}
|
||||
.user-menu{position:absolute;top:calc(100% + .5rem);right:0;min-width:180px;background:#fff;border:1px solid #e2e8f0;border-radius:.75rem;box-shadow:0 20px 35px rgba(15,23,42,.15);padding:.35rem;z-index:40}
|
||||
.user-menu-item{display:block;width:100%;text-align:left;padding:.45rem .75rem;border-radius:.6rem;font-size:.9rem;color:#0f172a}
|
||||
.user-menu-item:hover{background:#f1f5f9}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800" data-page="dashboard">
|
||||
<header class="sticky top-0 z-30 bg-white/90 border-b backdrop-blur">
|
||||
<div class="max-w-5xl mx-auto px-4 py-4 flex items-center gap-3">
|
||||
<a href="./" class="btn" title="Zurück zur Übersicht">← Übersicht</a>
|
||||
<h1 class="font-semibold text-lg">Dashboard</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="account.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="admin.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-5xl mx-auto p-4 md:p-6">
|
||||
<section class="stat-grid" id="dashboardCounts">
|
||||
<div class="stat-card">
|
||||
<h4>Templates</h4>
|
||||
<strong id="count-templates">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Sections</h4>
|
||||
<strong id="count-sections">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Blocks</h4>
|
||||
<strong id="count-blocks">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Snippets</h4>
|
||||
<strong id="count-snippets">–</strong>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h4>Aufrufe gesamt</h4>
|
||||
<strong id="count-usage">–</strong>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card" data-role="admin">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div>
|
||||
<h4>Template-Nutzung</h4>
|
||||
<p class="text-sm text-slate-600">Wie oft wurden Templates über die API geladen? Setze einzelne Zähler bei Bedarf zurück.</p>
|
||||
</div>
|
||||
<button type="button" class="btn" id="btn-refresh-dashboard">Aktualisieren</button>
|
||||
</div>
|
||||
<div class="overflow-auto">
|
||||
<table class="usage-table" id="usageTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Template</th>
|
||||
<th>Aufrufe</th>
|
||||
<th>Zuletzt verwendet</th>
|
||||
<th class="text-right">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td colspan="4" class="text-sm text-slate-500">Lade Daten…</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="toast-root"></div>
|
||||
|
||||
<script src="assets/js/toast.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
<script type="module" src="assets/js/dashboard.js?v=<?= htmlspecialchars($assetVersion, ENT_QUOTES) ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
header('Location: /admin/dashboard.php', true, 301);
|
||||
exit;
|
||||
|
||||
@@ -62,9 +62,9 @@ $assetVersion = defined('ASSET_VERSION') ? ASSET_VERSION : time();
|
||||
<span id="userAvatar">U</span>
|
||||
</button>
|
||||
<div id="userMenuPanel" class="user-menu hidden" role="menu">
|
||||
<a href="account.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="admin.php" class="user-menu-item" data-role="admin">Administration</a>
|
||||
<a href="/admin/profile.php" class="user-menu-item" data-menu="profile">Profil</a>
|
||||
<a href="/admin/dashboard.php" class="user-menu-item" data-role="admin">Dashboard</a>
|
||||
<a href="/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>
|
||||
|
||||
Reference in New Issue
Block a user