diff --git a/admin.html b/admin.html
index abc4080..e484b25 100644
--- a/admin.html
+++ b/admin.html
@@ -332,6 +332,10 @@
Подписки
Все выданные подписки
+
| Пользователь | Сервер | Тариф | Выдана | Истекает | Статус | |
@@ -969,6 +973,16 @@ function initDropdowns() {
const countryOptions = COUNTRIES.map(([code, name]) => ({
value: code, label: `${flagEmoji(code)} ${name}`,
}));
+ DD.subsStatusFilter = createDropdown("subs-status-filter", {
+ options: [
+ { value: "all", label: "Все статусы" },
+ { value: "active", label: "Активные" },
+ { value: "held", label: "На паузе" },
+ { value: "expired", label: "Истекшие/отозванные" },
+ ],
+ value: "all", placeholder: "Статус",
+ onChange: () => renderFilteredSubs(),
+ });
DD.ngCountry = createDropdown("ng-country", {
options: countryOptions, placeholder: "Страна", searchable: true,
onChange: (code) => {
@@ -1413,8 +1427,9 @@ async function loadDashboard() {
`).join("") : '
Пока нет подписок |
';
}
-async function loadSubscriptions() {
- const subs = await api("/admin/api/subscriptions");
+let allSubs = [];
+
+function renderSubsTable(subs) {
const body = document.getElementById("subs-body");
body.innerHTML = subs.length ? subs.map((s, i) => `
| ${s.username ? "@" + esc(s.username) : "tg" + s.tg_id} | ${esc(s.node_label)} | ${esc(s.plan_label)} |
@@ -1429,6 +1444,31 @@ async function loadSubscriptions() {
`).join("") : '
Пока нет подписок |
';
}
+function subStatus(s) {
+ if (s.held_at) return "held";
+ if (!s.active) return "expired";
+ return "active";
+}
+
+function renderFilteredSubs() {
+ const q = document.getElementById("subs-search").value.trim().toLowerCase();
+ const statusFilter = DD.subsStatusFilter ? DD.subsStatusFilter.getValue() : "all";
+ const filtered = allSubs.filter((s) => {
+ if (statusFilter !== "all" && subStatus(s) !== statusFilter) return false;
+ if (!q) return true;
+ const haystack = [
+ s.username || "", String(s.tg_id), s.node_label || "", s.plan_label || "",
+ ].join(" ").toLowerCase();
+ return haystack.includes(q);
+ });
+ renderSubsTable(filtered);
+}
+
+async function loadSubscriptions() {
+ allSubs = await api("/admin/api/subscriptions");
+ renderFilteredSubs();
+}
+
let devicesTgId = null;
async function openUserCard(tgId, label) {
devicesTgId = tgId;