Files
gotelegram_pro/admin-web/static/index.html
2026-04-24 22:30:09 +03:00

270 lines
10 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GoTelegram Admin</title>
<script>
(function () {
var stored = localStorage.getItem("gotelegram-theme");
var theme = stored || (matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
document.documentElement.dataset.theme = theme;
}());
</script>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="app-shell">
<aside class="sidebar" id="sidebar">
<div class="brand">
<div class="brand-mark">GT</div>
<div>
<strong>GoTelegram</strong>
<span data-i18n="brandSubtitle">Local Admin</span>
</div>
</div>
<nav class="nav-tabs" aria-label="Admin sections">
<button type="button" class="nav-item active" data-nav="dashboard" data-i18n="navDashboard">Dashboard</button>
<button type="button" class="nav-item" data-nav="traffic" data-i18n="navTraffic">Traffic</button>
<button type="button" class="nav-item" data-nav="keys" data-i18n="navKeys">Keys</button>
<button type="button" class="nav-item" data-nav="backups" data-i18n="navBackups">Backups</button>
<button type="button" class="nav-item" data-nav="logs" data-i18n="navLogs">Logs</button>
<button type="button" class="nav-item" data-nav="settings" data-i18n="navSettings">Settings</button>
</nav>
<div class="sidebar-foot">
<span id="sidebarVersion">v--</span>
<span id="sidebarBind">127.0.0.1:1984</span>
</div>
</aside>
<div class="workspace">
<header class="topbar">
<button id="menuBtn" class="icon-btn mobile-only" type="button" aria-label="Menu"></button>
<div class="title-block">
<p class="eyebrow" id="pageKicker">Local Admin</p>
<h1 id="pageTitle">Dashboard</h1>
<small id="lastRefresh">--</small>
</div>
<div class="top-actions">
<span class="pill" id="languageBadge">EN</span>
<button id="themeToggle" class="ghost" type="button">Theme</button>
<button id="refreshBtn" type="button" data-i18n="refresh">Refresh</button>
</div>
</header>
<main class="content">
<section class="page-panel active" data-page="dashboard">
<div class="metric-grid">
<article class="metric-card accent-blue">
<span data-i18n="metricMode">Mode</span>
<strong id="metricMode">--</strong>
<small id="metricDomain">--</small>
</article>
<article class="metric-card accent-green">
<span data-i18n="metricKeys">Keys</span>
<strong id="metricUsers">0</strong>
<small data-i18n="configuredUsers">configured users</small>
</article>
<article class="metric-card accent-violet">
<span data-i18n="metricProxyTraffic">Proxy Traffic</span>
<strong id="metricProxyTraffic">0 B</strong>
<small id="metricProxyPackets">0 packets</small>
</article>
<article class="metric-card accent-amber">
<span data-i18n="metricSiteTraffic">Site Traffic</span>
<strong id="metricSiteTraffic">0 B</strong>
<small id="metricSitePackets">0 packets</small>
</article>
</div>
<div class="grid-two">
<section class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="servicesEyebrow">Services</p>
<h2 data-i18n="servicesTitle">Runtime health</h2>
</div>
</div>
<div class="service-grid" id="services"></div>
</section>
<section class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="runtimeEyebrow">Runtime</p>
<h2 data-i18n="runtimeTitle">telemt summary</h2>
</div>
</div>
<div id="runtimeCards" class="runtime-grid"></div>
<div id="runtimeIssues" class="issue-list"></div>
</section>
</div>
</section>
<section class="page-panel" data-page="traffic">
<div class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="trafficEyebrow">Traffic</p>
<h2 data-i18n="trafficTitle">History</h2>
</div>
<div class="panel-actions">
<span id="statsHealth" class="status-pill">--</span>
<button id="collectStatsBtn" class="ghost" type="button" data-i18n="collectStats">Collect</button>
<button id="repairStatsBtn" type="button" data-i18n="repairStats">Repair stats</button>
</div>
</div>
<div class="traffic-summary">
<article>
<span data-i18n="collector">Collector</span>
<strong id="collectorState">--</strong>
</article>
<article>
<span data-i18n="lastPoint">Last point</span>
<strong id="lastStatsPoint">--</strong>
</article>
<article>
<span data-i18n="historyRows">History rows</span>
<strong id="historyRows">0</strong>
</article>
</div>
<div id="trafficChart" class="traffic-chart"></div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th data-i18n="tableTime">Time</th>
<th data-i18n="tableProxyDelta">Proxy delta</th>
<th data-i18n="tableSiteDelta">Site delta</th>
<th data-i18n="tableProxyTotal">Proxy total</th>
<th data-i18n="tableSiteTotal">Site total</th>
</tr>
</thead>
<tbody id="historyTable"></tbody>
</table>
</div>
</div>
</section>
<section class="page-panel" data-page="keys">
<div class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="keysEyebrow">Access</p>
<h2 data-i18n="keysTitle">User keys</h2>
</div>
<form id="addUserForm" class="inline-form">
<input id="userName" autocomplete="off" placeholder="client-name" data-i18n-placeholder="userPlaceholder">
<button type="submit" data-i18n="addKey">Add key</button>
</form>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th data-i18n="tableUser">User</th>
<th data-i18n="tableSecret">Secret</th>
<th data-i18n="tableLink">Link</th>
<th data-i18n="tableActions">Actions</th>
</tr>
</thead>
<tbody id="usersTable"></tbody>
</table>
</div>
</div>
</section>
<section class="page-panel" data-page="backups">
<div class="grid-two">
<section class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="backupsEyebrow">Snapshots</p>
<h2 data-i18n="backupsTitle">Backups</h2>
</div>
<button id="createBackupBtn" type="button" data-i18n="createBackup">Create backup</button>
</div>
<div id="backupsList" class="backup-list"></div>
</section>
<aside class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="eventsEyebrow">Events</p>
<h2 data-i18n="eventsTitle">Activity</h2>
</div>
</div>
<div id="events" class="events-list"></div>
</aside>
</div>
</section>
<section class="page-panel" data-page="logs">
<div class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="logsEyebrow">Journal</p>
<h2 data-i18n="logsTitle">Logs</h2>
</div>
<div class="inline-form">
<select id="logService">
<option value="telemt">telemt</option>
<option value="nginx">nginx</option>
<option value="gotelegram-bot">bot</option>
<option value="gotelegram-stats">stats</option>
<option value="gotelegram-admin">admin</option>
</select>
<button id="loadLogsBtn" type="button" data-i18n="loadLogs">Load</button>
</div>
</div>
<pre id="logsBox" class="logs"></pre>
</div>
</section>
<section class="page-panel" data-page="settings">
<div class="grid-two">
<section class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="settingsEyebrow">Settings</p>
<h2 data-i18n="settingsTitle">Panel preferences</h2>
</div>
</div>
<div class="settings-list">
<div>
<span data-i18n="panelLanguage">Panel language</span>
<strong id="settingsLanguage">--</strong>
</div>
<div>
<span data-i18n="theme">Theme</span>
<strong id="settingsTheme">--</strong>
</div>
<div>
<span data-i18n="bindAddress">Bind address</span>
<strong id="settingsBind">127.0.0.1:1984</strong>
</div>
</div>
</section>
<section class="panel">
<div class="panel-head">
<div>
<p class="eyebrow" data-i18n="configEyebrow">Config</p>
<h2 data-i18n="configTitle">Installation state</h2>
</div>
</div>
<div id="configList" class="settings-list"></div>
</section>
</div>
</section>
</main>
</div>
</div>
<div id="toast" class="toast"></div>
<script src="/app.js" type="module"></script>
</body>
</html>