Adds GET /api/fenjaops/events and three new panels: per-type totals + device breakdown, per-user summary (logins / timeline views / last seen), and a raw event log capped at the newest 500 rows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
109 lines
4.1 KiB
HTML
109 lines
4.1 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta name="robots" content="noindex, nofollow" />
|
||
<title>Admin — Fenja AI</title>
|
||
<link rel="stylesheet" href="/fenjaops/admin.css" />
|
||
</head>
|
||
<body>
|
||
<header class="masthead">
|
||
<h1>Fenja AI <span class="dim">— Admin</span></h1>
|
||
</header>
|
||
|
||
<section class="panel">
|
||
<h2>Invite a new user <span class="dim">— non-admin only</span></h2>
|
||
<form class="invite-form" id="invite-form" novalidate>
|
||
<label>
|
||
<span class="lbl">Email</span>
|
||
<input type="email" name="email" autocomplete="off" required />
|
||
</label>
|
||
<label>
|
||
<span class="lbl">First name <span class="opt">(optional)</span></span>
|
||
<input type="text" name="first_name" maxlength="64" autocomplete="off" />
|
||
</label>
|
||
<button type="submit">Send invite</button>
|
||
<p class="form-msg" id="invite-msg" hidden></p>
|
||
</form>
|
||
</section>
|
||
|
||
<section class="panel">
|
||
<h2>Stats</h2>
|
||
<div class="stats" id="stats">
|
||
<div class="stat"><span class="stat-k">Total clicks</span><span class="stat-v" id="stat-clicks">–</span></div>
|
||
<div class="stat"><span class="stat-k">Unique users</span><span class="stat-v" id="stat-unique">–</span></div>
|
||
<div class="stat"><span class="stat-k">Invites</span><span class="stat-v" id="stat-invites">–</span></div>
|
||
<div class="stat"><span class="stat-k">Admins</span><span class="stat-v" id="stat-admins">–</span></div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="panel">
|
||
<h2>Per-user join summary</h2>
|
||
<table class="t" id="t-summary">
|
||
<thead><tr>
|
||
<th>Email</th><th class="num">Clicks</th><th>First click</th><th>Last click</th>
|
||
</tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
<p class="empty" id="empty-summary" hidden>No join clicks yet.</p>
|
||
</section>
|
||
|
||
<section class="panel">
|
||
<h2>Engagement events <span class="dim">— totals</span></h2>
|
||
<div class="stats" id="event-totals">
|
||
<div class="stat"><span class="stat-k">Logins</span><span class="stat-v" id="stat-event-logins">–</span></div>
|
||
<div class="stat"><span class="stat-k">Timeline views</span><span class="stat-v" id="stat-event-tlv">–</span></div>
|
||
<div class="stat"><span class="stat-k">Login users</span><span class="stat-v" id="stat-event-login-users">–</span></div>
|
||
<div class="stat"><span class="stat-k">Timeline users</span><span class="stat-v" id="stat-event-tlv-users">–</span></div>
|
||
</div>
|
||
<div class="stats" id="event-devices" style="margin-top:.6rem"></div>
|
||
</section>
|
||
|
||
<section class="panel">
|
||
<h2>Per-user engagement</h2>
|
||
<table class="t" id="t-event-summary">
|
||
<thead><tr>
|
||
<th>Email</th><th class="num">Logins</th><th class="num">Timeline</th><th>Last seen</th>
|
||
</tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
<p class="empty" id="empty-event-summary" hidden>No events yet.</p>
|
||
</section>
|
||
|
||
<section class="panel">
|
||
<h2>Raw event log <span class="dim">(newest 500)</span></h2>
|
||
<table class="t" id="t-events">
|
||
<thead><tr>
|
||
<th>When</th><th>Type</th><th>Email</th><th>Device</th><th class="mono">Session</th><th>Meta</th>
|
||
</tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
<p class="empty" id="empty-events" hidden>No events logged yet.</p>
|
||
</section>
|
||
|
||
<section class="panel">
|
||
<h2>Invites</h2>
|
||
<table class="t" id="t-invites">
|
||
<thead><tr>
|
||
<th>Email</th><th>Name</th><th>Invited</th><th>By</th><th class="num">Admin</th><th class="num">Action</th>
|
||
</tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
<p class="empty" id="empty-invites" hidden>No invites yet.</p>
|
||
</section>
|
||
|
||
<section class="panel">
|
||
<h2>Raw join log <span class="dim">(newest first)</span></h2>
|
||
<table class="t" id="t-clicks">
|
||
<thead><tr>
|
||
<th>When</th><th>Email</th><th class="mono">Session</th>
|
||
</tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
<p class="empty" id="empty-clicks" hidden>No clicks logged yet.</p>
|
||
</section>
|
||
|
||
<script src="/fenjaops/admin.js" defer></script>
|
||
</body>
|
||
</html>
|