openclaw-zalo-mod 2.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/README.vi.md +306 -0
- package/bvbank.jpg +0 -0
- package/dashboard.css +5954 -0
- package/dashboard.js +7392 -0
- package/index.html +1212 -0
- package/index.js +7558 -0
- package/logo.png +0 -0
- package/openclaw.plugin.json +96 -0
- package/package.json +85 -0
- package/skills/zalo-mod-control/SKILL.md +236 -0
- package/src/agent/commands.js +224 -0
- package/src/agent/connect-actions.js +160 -0
- package/src/agent/skill-content.js +327 -0
- package/src/agent/tool-surface.js +990 -0
- package/src/context/context-selector.js +72 -0
- package/src/context/conversation-buffer.js +120 -0
- package/src/context/prompt-injector.js +91 -0
- package/src/context/turn-context.js +142 -0
- package/src/crm/crm-api.js +121 -0
- package/src/crm/crm-store.js +1023 -0
- package/src/crm/task-reconcile.js +169 -0
- package/src/crm/zalo-people.js +191 -0
- package/src/integration/openclaw-adapter.js +235 -0
- package/src/integration/owner-claim.js +11 -0
- package/src/integration/zalo-connect-bridge.js +335 -0
- package/src/integration/zalo-mod-engine.js +379 -0
- package/src/integration/zca-facade.js +204 -0
- package/src/licensing/entitlements.js +96 -0
- package/src/messaging/conversation-queue.js +110 -0
- package/src/messaging/mention-builder.js +83 -0
- package/src/messaging/reply-mention-correlator.js +104 -0
- package/src/messaging/reply-router.js +182 -0
- package/src/storage/database.js +178 -0
- package/src/storage/migrations.js +314 -0
- package/upgrade/plans.json +80 -0
package/index.html
ADDED
|
@@ -0,0 +1,1212 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="vi">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
7
|
+
<title>OpenClaw Zalo Owner Dashboard</title>
|
|
8
|
+
<link rel="icon" type="image/png" sizes="32x32" href="./logo.png?v=20260515">
|
|
9
|
+
<link rel="shortcut icon" href="./logo.png?v=20260515">
|
|
10
|
+
<link rel="apple-touch-icon" href="./logo.png?v=20260515">
|
|
11
|
+
<link rel="stylesheet" href="./dashboard.css?v=20260818c">
|
|
12
|
+
<script src="./dashboard.js?v=20260819e" defer></script>
|
|
13
|
+
</head>
|
|
14
|
+
|
|
15
|
+
<body>
|
|
16
|
+
<div class="sidebar-backdrop" id="sidebarBackdrop"></div>
|
|
17
|
+
<div class="app">
|
|
18
|
+
<aside class="sidebar" aria-label="Điều hướng chính">
|
|
19
|
+
<div class="brand">
|
|
20
|
+
<div class="brand-mark" aria-hidden="true">
|
|
21
|
+
<img src="./logo.png" alt="OpenClaw logo"
|
|
22
|
+
onerror="this.style.display='none'; this.parentElement.classList.add('is-fallback')">
|
|
23
|
+
</div>
|
|
24
|
+
<div class="brand-text">
|
|
25
|
+
<h1>Zalo Owner</h1>
|
|
26
|
+
<p>Quản trị Bot Zalo</p>
|
|
27
|
+
</div>
|
|
28
|
+
<button class="sidebar-collapse-btn" id="sidebarCollapseBtn" aria-label="Collapse sidebar" type="button">
|
|
29
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
30
|
+
stroke-linejoin="round">
|
|
31
|
+
<polyline points="15 18 9 12 15 6"></polyline>
|
|
32
|
+
</svg>
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
<nav class="nav" data-nav>
|
|
36
|
+
<button class="active" data-section="overview"><svg viewBox="0 0 24 24" fill="none">
|
|
37
|
+
<path d="M4 13h6V4H4v9Zm10 7h6V4h-6v16ZM4 20h6v-4H4v4Z" stroke="currentColor" stroke-width="2"
|
|
38
|
+
stroke-linejoin="round" />
|
|
39
|
+
</svg><span class="nav-label">Tổng quan</span></button>
|
|
40
|
+
<button data-section="groups"><svg viewBox="0 0 24 24" fill="none">
|
|
41
|
+
<path
|
|
42
|
+
d="M16 11a4 4 0 1 0-8 0m8 0a4 4 0 1 1-8 0m8 0h3a3 3 0 0 1 3 3v3M8 11H5a3 3 0 0 0-3 3v3m5 3v-2a5 5 0 0 1 10 0v2"
|
|
43
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
|
44
|
+
</svg><span class="nav-label">Nhóm</span></button>
|
|
45
|
+
<button data-section="members"><svg viewBox="0 0 24 24" fill="none">
|
|
46
|
+
<path d="M15 8a4 4 0 1 1-8 0 4 4 0 0 1 8 0Zm-12 13a8 8 0 0 1 16 0m0-13h3m-1.5-1.5v3" stroke="currentColor"
|
|
47
|
+
stroke-width="2" stroke-linecap="round" />
|
|
48
|
+
</svg><span class="nav-label">Thành viên</span></button>
|
|
49
|
+
<div class="nav-group open" id="navGroupJournal">
|
|
50
|
+
<button class="nav-group-trigger" type="button" onclick="this.parentElement.classList.toggle('open')">
|
|
51
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
52
|
+
<path d="M4 5a2 2 0 0 1 2-2h9l5 5v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5Z" stroke="currentColor" stroke-width="2"
|
|
53
|
+
stroke-linejoin="round" />
|
|
54
|
+
<path d="M14 3v5h5M8 13h8M8 17h5" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
55
|
+
stroke-linejoin="round" />
|
|
56
|
+
</svg>
|
|
57
|
+
<span class="nav-label">Nhật ký</span>
|
|
58
|
+
<svg class="chevron-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-left: auto; width: 12px; height: 12px; transition: transform 0.2s; flex-shrink: 0;"><polyline points="6 9 12 15 18 9"/></svg>
|
|
59
|
+
</button>
|
|
60
|
+
<div class="sidebar-submenu">
|
|
61
|
+
<button data-section="journal" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Theo nhóm</span></button>
|
|
62
|
+
<button data-section="reports" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Lịch báo cáo</span></button>
|
|
63
|
+
<button data-section="reportlog" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Lịch sử báo cáo</span></button>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="nav-group open" id="navGroupChat">
|
|
67
|
+
<button class="nav-group-trigger" type="button" onclick="this.parentElement.classList.toggle('open')">
|
|
68
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
69
|
+
<path d="M21 12a8 8 0 0 1-8 8H6l-4 2 1.4-4.2A8 8 0 1 1 21 12Z" stroke="currentColor" stroke-width="2"
|
|
70
|
+
stroke-linejoin="round" />
|
|
71
|
+
</svg>
|
|
72
|
+
<span class="nav-label">Tin nhắn</span>
|
|
73
|
+
<svg class="chevron-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-left: auto; width: 12px; height: 12px; transition: transform 0.2s; flex-shrink: 0;"><polyline points="6 9 12 15 18 9"/></svg>
|
|
74
|
+
</button>
|
|
75
|
+
<div class="sidebar-submenu">
|
|
76
|
+
<button data-section="chat" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Khung chat</span></button>
|
|
77
|
+
<button data-section="messages" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Gửi hàng loạt</span></button>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<button data-section="templates"><svg viewBox="0 0 24 24" fill="none">
|
|
81
|
+
<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
82
|
+
<path d="M14 2v6h6M16 13H8m8 4H8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
83
|
+
</svg><span class="nav-label">Lệnh & Rules</span></button>
|
|
84
|
+
<button data-section="permissions"><svg viewBox="0 0 24 24" fill="none">
|
|
85
|
+
<path d="M12 2 4 5v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V5l-8-3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
86
|
+
<path d="M9 12l2 2 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
87
|
+
</svg><span class="nav-label">Phân quyền</span></button>
|
|
88
|
+
<div class="nav-group open" id="navGroupCrm">
|
|
89
|
+
<button class="nav-group-trigger" type="button" onclick="this.parentElement.classList.toggle('open')">
|
|
90
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
91
|
+
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2m22 0v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75M13 7a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
92
|
+
</svg>
|
|
93
|
+
<span class="nav-label">CRM</span>
|
|
94
|
+
<svg class="chevron-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-left: auto; width: 12px; height: 12px; transition: transform 0.2s; flex-shrink: 0;"><polyline points="6 9 12 15 18 9"/></svg>
|
|
95
|
+
</button>
|
|
96
|
+
<div class="sidebar-submenu">
|
|
97
|
+
<button data-section="contacts" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Khách hàng</span></button>
|
|
98
|
+
<button data-section="leads" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Cơ hội bán hàng</span></button>
|
|
99
|
+
<button data-section="tasks" class="submenu-item" type="button"><span class="submenu-dot"></span><span class="nav-label">Công việc</span></button>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="nav-group open" id="navGroupUtilities">
|
|
103
|
+
<button class="nav-group-trigger" type="button" onclick="this.parentElement.classList.toggle('open')">
|
|
104
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
105
|
+
<path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
106
|
+
<line x1="7" y1="7" x2="7.01" y2="7" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>
|
|
107
|
+
</svg>
|
|
108
|
+
<span class="nav-label">Tiện ích</span>
|
|
109
|
+
<svg class="chevron-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-left: auto; width: 12px; height: 12px; transition: transform 0.2s; flex-shrink: 0;"><polyline points="6 9 12 15 18 9"/></svg>
|
|
110
|
+
</button>
|
|
111
|
+
<div class="sidebar-submenu">
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<button data-section="upgrade"><svg viewBox="0 0 24 24" fill="none">
|
|
115
|
+
<path d="m12 3 2.7 5.5 6 .9-4.3 4.2 1 5.9L12 16.6l-5.4 2.9 1-5.9L3.3 9.4l6-.9L12 3Z" stroke="currentColor"
|
|
116
|
+
stroke-width="2" stroke-linejoin="round" />
|
|
117
|
+
</svg><span class="nav-label">Nâng cấp</span></button>
|
|
118
|
+
<button data-section="settings"><svg viewBox="0 0 24 24" fill="none">
|
|
119
|
+
<path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="2" />
|
|
120
|
+
<path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-2.9 1.2V21a2 2 0 1 1-4 0v-.1A1.7 1.7 0 0 0 7 19.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0-1.2-2.9H3a2 2 0 1 1 0-4h.1A1.7 1.7 0 0 0 4.7 7l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.9.3H9.5A1.7 1.7 0 0 0 10.5 3V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 2.9 1.2l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.9v.1a1.7 1.7 0 0 0 1.6 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" />
|
|
121
|
+
</svg><span class="nav-label">Cài đặt</span></button>
|
|
122
|
+
</nav>
|
|
123
|
+
<div class="sidebar-footer">
|
|
124
|
+
<div class="sidebar-card">
|
|
125
|
+
<strong>Chế độ vận hành</strong>
|
|
126
|
+
<span>Dashboard gọi API thật khi ZCA khả dụng. Action rủi ro cao luôn cần xác nhận và được ghi audit
|
|
127
|
+
log.</span>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="plugin-meta">
|
|
130
|
+
<strong>zalo-mod <span id="pluginVersion">v2.29.0</span></strong>
|
|
131
|
+
<span>Được làm ❤️ bởi tuanminhole</span>
|
|
132
|
+
<div class="socials" aria-label="Author links">
|
|
133
|
+
<a href="https://www.facebook.com/holeminhtuan.it/" target="_blank" rel="noreferrer"
|
|
134
|
+
aria-label="Facebook"><svg class="icon" viewBox="0 0 24 24" fill="currentColor">
|
|
135
|
+
<path
|
|
136
|
+
d="M13.5 22v-8h2.7l.4-3.1h-3.1V8.9c0-.9.3-1.5 1.6-1.5h1.7V4.6c-.3 0-1.3-.1-2.5-.1-2.5 0-4.2 1.5-4.2 4.3v2.1H7.3V14h2.8v8h3.4Z" />
|
|
137
|
+
</svg></a>
|
|
138
|
+
<a href="https://t.me/holeminhtuan_it" target="_blank" rel="noreferrer" aria-label="Telegram"><svg
|
|
139
|
+
class="icon" viewBox="0 0 24 24" fill="none">
|
|
140
|
+
<path
|
|
141
|
+
d="m21 4-3.2 16.1c-.2.9-.8 1.1-1.6.7l-4.8-3.6-2.3 2.2c-.3.3-.5.5-1 .5l.4-5 9-8.1c.4-.4-.1-.6-.6-.3L5.7 13.5.9 12c-.9-.3-.9-.9.2-1.3L19.8 3.5c.8-.3 1.5.2 1.2.5Z"
|
|
142
|
+
stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" />
|
|
143
|
+
</svg></a>
|
|
144
|
+
<a href="https://zalo.me/0962794917" target="_blank" rel="noreferrer" aria-label="Zalo"><svg class="icon"
|
|
145
|
+
viewBox="0 0 24 24" fill="none">
|
|
146
|
+
<path
|
|
147
|
+
d="M5.5 6.5h13v8.2c0 2.1-1.7 3.8-3.8 3.8H10l-3.8 2v-2A3.7 3.7 0 0 1 2 14.8V10c0-1.9 1.6-3.5 3.5-3.5Z"
|
|
148
|
+
stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" />
|
|
149
|
+
<path d="M7 10h4l-4 4h4m2-4v4m2-4h2.2c.8 0 1.3.5 1.3 1.2 0 .5-.3.9-.8 1.1l1.1 1.7" stroke="currentColor"
|
|
150
|
+
stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" />
|
|
151
|
+
</svg></a>
|
|
152
|
+
<a href="https://github.com/tuanminhhole/openclaw-zalo-mod" target="_blank" rel="noreferrer"
|
|
153
|
+
aria-label="GitHub"><svg class="icon" viewBox="0 0 24 24" fill="currentColor">
|
|
154
|
+
<path
|
|
155
|
+
d="M12 2a10 10 0 0 0-3.2 19.5c.5.1.7-.2.7-.5v-1.8c-2.8.6-3.4-1.2-3.4-1.2-.5-1.1-1.1-1.4-1.1-1.4-.9-.6.1-.6.1-.6 1 .1 1.6 1.1 1.6 1.1.9 1.6 2.4 1.1 2.9.8.1-.7.4-1.1.7-1.4-2.2-.3-4.6-1.1-4.6-4.9 0-1.1.4-2 1-2.7-.1-.3-.5-1.3.1-2.7 0 0 .9-.3 2.8 1a9.4 9.4 0 0 1 5 0c1.9-1.3 2.8-1 2.8-1 .6 1.4.2 2.4.1 2.7.7.7 1 1.6 1 2.7 0 3.8-2.3 4.6-4.6 4.9.4.3.8 1 .8 2v2.9c0 .3.2.6.8.5A10 10 0 0 0 12 2Z" />
|
|
156
|
+
</svg></a>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</aside>
|
|
161
|
+
<main>
|
|
162
|
+
<header class="topbar">
|
|
163
|
+
<button class="mobile-menu-btn" id="mobileMenuBtn" aria-label="Toggle menu" type="button">
|
|
164
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
|
165
|
+
<line x1="4" y1="12" x2="20" y2="12"></line>
|
|
166
|
+
<line x1="4" y1="6" x2="20" y2="6"></line>
|
|
167
|
+
<line x1="4" y1="18" x2="20" y2="18"></line>
|
|
168
|
+
</svg>
|
|
169
|
+
</button>
|
|
170
|
+
<div class="search">
|
|
171
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none">
|
|
172
|
+
<path d="m21 21-4.3-4.3M10.8 18a7.2 7.2 0 1 1 0-14.4 7.2 7.2 0 0 1 0 14.4Z" stroke="currentColor"
|
|
173
|
+
stroke-width="2" stroke-linecap="round" />
|
|
174
|
+
</svg>
|
|
175
|
+
<input id="search" type="search" placeholder="Tìm group, member, userId, API...">
|
|
176
|
+
</div>
|
|
177
|
+
<div id="topbarBotFilter" style="margin-right: 12px; display: inline-flex; align-items: center;"></div>
|
|
178
|
+
<div id="headerLicenseBadge" class="header-license-badge" onclick="setSection('upgrade')"></div>
|
|
179
|
+
<button class="theme-toggle-btn" id="permBtn" type="button" aria-label="Phân quyền" title="Phân quyền DM / Group / Lệnh" style="font-size:16px">🔐</button>
|
|
180
|
+
<button class="theme-toggle-btn" id="themeToggle" type="button" aria-label="Toggle theme">
|
|
181
|
+
<svg class="icon theme-icon moon-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
182
|
+
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path>
|
|
183
|
+
</svg>
|
|
184
|
+
<svg class="icon theme-icon sun-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
185
|
+
<circle cx="12" cy="12" r="4"></circle>
|
|
186
|
+
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"></path>
|
|
187
|
+
</svg>
|
|
188
|
+
</button>
|
|
189
|
+
<div class="lang-toggle-switch" id="langToggle" role="group" aria-label="Đổi ngôn ngữ">
|
|
190
|
+
<span class="lang-slider-knob"></span>
|
|
191
|
+
<span class="lang-flag-option" id="langVi">
|
|
192
|
+
<svg viewBox="0 0 30 20" width="18" height="12">
|
|
193
|
+
<rect width="30" height="20" fill="#da251d"/>
|
|
194
|
+
<polygon points="15,4 16.2,8.3 20.3,8.3 17,10.8 18.2,15.1 15,12.5 11.8,15.1 13,10.8 9.7,8.3 13.8,8.3" fill="#ffff00"/>
|
|
195
|
+
</svg>
|
|
196
|
+
</span>
|
|
197
|
+
<span class="lang-flag-option" id="langEn">
|
|
198
|
+
<svg viewBox="0 0 30 20" width="18" height="12">
|
|
199
|
+
<rect width="30" height="20" fill="#ffffff"/>
|
|
200
|
+
<rect width="30" height="1.54" fill="#b22234"/>
|
|
201
|
+
<rect y="3.08" width="30" height="1.54" fill="#b22234"/>
|
|
202
|
+
<rect y="6.15" width="30" height="1.54" fill="#b22234"/>
|
|
203
|
+
<rect y="9.23" width="30" height="1.54" fill="#b22234"/>
|
|
204
|
+
<rect y="12.3" width="30" height="1.54" fill="#b22234"/>
|
|
205
|
+
<rect y="15.38" width="30" height="1.54" fill="#b22234"/>
|
|
206
|
+
<rect y="18.46" width="30" height="1.54" fill="#b22234"/>
|
|
207
|
+
<rect width="12" height="10.77" fill="#3c3b6e"/>
|
|
208
|
+
<circle cx="2.5" cy="2" r="0.4" fill="#fff"/>
|
|
209
|
+
<circle cx="5.5" cy="2" r="0.4" fill="#fff"/>
|
|
210
|
+
<circle cx="8.5" cy="2" r="0.4" fill="#fff"/>
|
|
211
|
+
<circle cx="4" cy="3.5" r="0.4" fill="#fff"/>
|
|
212
|
+
<circle cx="7" cy="3.5" r="0.4" fill="#fff"/>
|
|
213
|
+
<circle cx="2.5" cy="5" r="0.4" fill="#fff"/>
|
|
214
|
+
<circle cx="5.5" cy="5" r="0.4" fill="#fff"/>
|
|
215
|
+
<circle cx="8.5" cy="5" r="0.4" fill="#fff"/>
|
|
216
|
+
<circle cx="4" cy="6.5" r="0.4" fill="#fff"/>
|
|
217
|
+
<circle cx="7" cy="6.5" r="0.4" fill="#fff"/>
|
|
218
|
+
<circle cx="2.5" cy="8" r="0.4" fill="#fff"/>
|
|
219
|
+
<circle cx="5.5" cy="8" r="0.4" fill="#fff"/>
|
|
220
|
+
<circle cx="8.5" cy="8" r="0.4" fill="#fff"/>
|
|
221
|
+
<circle cx="4" cy="9.5" r="0.4" fill="#fff"/>
|
|
222
|
+
<circle cx="7" cy="9.5" r="0.4" fill="#fff"/>
|
|
223
|
+
</svg>
|
|
224
|
+
</span>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="owner-pill" id="ownerPill">
|
|
227
|
+
<div class="avatar">K</div>
|
|
228
|
+
<div class="owner-text">
|
|
229
|
+
<strong id="ownerName">Owner</strong>
|
|
230
|
+
<small id="ownerRole">Owner</small>
|
|
231
|
+
</div>
|
|
232
|
+
<div class="owner-dropdown" id="ownerDropdown">
|
|
233
|
+
<div class="owner-dropdown-item">
|
|
234
|
+
<span class="label" data-i18n="dropdownPlanLabel">Gói:</span>
|
|
235
|
+
<span class="value" id="dropdownPlan">FREE</span>
|
|
236
|
+
</div>
|
|
237
|
+
<div class="owner-dropdown-item">
|
|
238
|
+
<span class="label" data-i18n="dropdownExpiryLabel">Hạn dùng:</span>
|
|
239
|
+
<span class="value" id="dropdownExpiry">-</span>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
</header>
|
|
244
|
+
<div class="sub-topbar" id="mobileBotFilterBar"></div>
|
|
245
|
+
<section class="section active" id="overview">
|
|
246
|
+
<div class="page-head">
|
|
247
|
+
<div>
|
|
248
|
+
<h2>Tổng quan vận hành</h2>
|
|
249
|
+
<p>Theo dõi group, pending member, friend request và các action quan trọng trong một màn hình gọn cho owner.
|
|
250
|
+
</p>
|
|
251
|
+
</div>
|
|
252
|
+
<div class="actions">
|
|
253
|
+
<button class="btn" data-action="sync"><svg class="icon" viewBox="0 0 24 24" fill="none"
|
|
254
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
255
|
+
<path d="M20 12a8 8 0 0 1-14.8 4.2M4 12A8 8 0 0 1 18.8 7.8M20 5v5h-5M4 19v-5h5" />
|
|
256
|
+
</svg>Sync Account</button>
|
|
257
|
+
<button class="btn" data-action="open-upgrade"><svg class="icon" viewBox="0 0 24 24" fill="none"
|
|
258
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
|
259
|
+
style="width: 14px; height: 14px; margin-right: 6px; vertical-align: middle;">
|
|
260
|
+
<polygon
|
|
261
|
+
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2">
|
|
262
|
+
</polygon>
|
|
263
|
+
</svg>Nâng cấp</button>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
<div class="free-mode-banner">
|
|
268
|
+
<div>
|
|
269
|
+
<span class="free-pill">Free Mode</span>
|
|
270
|
+
<h3>Bạn vẫn dùng được UI miễn phí. Nâng cấp để mở khóa điều khiển nâng cao.</h3>
|
|
271
|
+
<p>Thanh toán qua Zalo bot → nhận key → nhập key để kích hoạt.</p>
|
|
272
|
+
</div>
|
|
273
|
+
<button class="btn primary" type="button" data-action="open-upgrade"><svg class="icon" viewBox="0 0 24 24"
|
|
274
|
+
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
|
275
|
+
style="width: 14px; height: 14px; margin-right: 6px; vertical-align: middle;">
|
|
276
|
+
<path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path>
|
|
277
|
+
<line x1="7" y1="7" x2="7.01" y2="7"></line>
|
|
278
|
+
</svg>Xem bảng giá</button>
|
|
279
|
+
</div>
|
|
280
|
+
<div class="grid stats">
|
|
281
|
+
<div class="card metric"><span>Nhóm quản lý</span><strong><span class="shimmer-placeholder"
|
|
282
|
+
style="width: 45px; height: 28px; margin: 4px 0;"></span></strong>
|
|
283
|
+
<div class="trend"><span class="shimmer-placeholder" style="width: 100px; height: 14px;"></span></div>
|
|
284
|
+
</div>
|
|
285
|
+
<div class="card metric"><span>Member đang chờ duyệt</span><strong><span class="shimmer-placeholder"
|
|
286
|
+
style="width: 45px; height: 28px; margin: 4px 0;"></span></strong>
|
|
287
|
+
<div class="trend"><span class="shimmer-placeholder" style="width: 120px; height: 14px;"></span></div>
|
|
288
|
+
</div>
|
|
289
|
+
<div class="card metric"><span>Friend requests</span><strong><span class="shimmer-placeholder"
|
|
290
|
+
style="width: 45px; height: 28px; margin: 4px 0;"></span></strong>
|
|
291
|
+
<div class="trend"><span class="shimmer-placeholder" style="width: 90px; height: 14px;"></span></div>
|
|
292
|
+
</div>
|
|
293
|
+
<div class="card metric"><span>Action rủi ro cao</span><strong><span class="shimmer-placeholder"
|
|
294
|
+
style="width: 45px; height: 28px; margin: 4px 0;"></span></strong>
|
|
295
|
+
<div class="trend"><span class="shimmer-placeholder" style="width: 110px; height: 14px;"></span></div>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
<div class="layout">
|
|
299
|
+
<div class="card">
|
|
300
|
+
<div class="panel-head">
|
|
301
|
+
<div>
|
|
302
|
+
<h3>Group cần chú ý</h3>
|
|
303
|
+
<p>Ưu tiên group có pending, spam hoặc member bị cảnh cáo.</p>
|
|
304
|
+
</div>
|
|
305
|
+
<button class="btn" data-section-target="groups">Xem tất cả</button>
|
|
306
|
+
</div>
|
|
307
|
+
<div class="table-wrap">
|
|
308
|
+
<table>
|
|
309
|
+
<thead>
|
|
310
|
+
<tr>
|
|
311
|
+
<th>Group</th>
|
|
312
|
+
<th>Thành viên</th>
|
|
313
|
+
<th>Cảnh báo</th>
|
|
314
|
+
<th>Mode</th>
|
|
315
|
+
<th>Action</th>
|
|
316
|
+
</tr>
|
|
317
|
+
</thead>
|
|
318
|
+
<tbody>
|
|
319
|
+
<tr>
|
|
320
|
+
<td>
|
|
321
|
+
<div class="shimmer-placeholder" style="width: 140px; height: 16px; margin-bottom: 4px;"></div>
|
|
322
|
+
<br>
|
|
323
|
+
<div class="shimmer-placeholder" style="width: 85px; height: 12px;"></div>
|
|
324
|
+
</td>
|
|
325
|
+
<td>
|
|
326
|
+
<div class="shimmer-placeholder" style="width: 35px; height: 16px;"></div>
|
|
327
|
+
</td>
|
|
328
|
+
<td>
|
|
329
|
+
<div class="shimmer-placeholder" style="width: 75px; height: 20px; border-radius: 20px;"></div>
|
|
330
|
+
</td>
|
|
331
|
+
<td>
|
|
332
|
+
<div class="shimmer-placeholder" style="width: 60px; height: 20px; border-radius: 20px;"></div>
|
|
333
|
+
</td>
|
|
334
|
+
<td>
|
|
335
|
+
<div class="shimmer-placeholder" style="width: 65px; height: 26px; border-radius: 6px;"></div>
|
|
336
|
+
</td>
|
|
337
|
+
</tr>
|
|
338
|
+
<tr>
|
|
339
|
+
<td>
|
|
340
|
+
<div class="shimmer-placeholder" style="width: 120px; height: 16px; margin-bottom: 4px;"></div>
|
|
341
|
+
<br>
|
|
342
|
+
<div class="shimmer-placeholder" style="width: 95px; height: 12px;"></div>
|
|
343
|
+
</td>
|
|
344
|
+
<td>
|
|
345
|
+
<div class="shimmer-placeholder" style="width: 35px; height: 16px;"></div>
|
|
346
|
+
</td>
|
|
347
|
+
<td>
|
|
348
|
+
<div class="shimmer-placeholder" style="width: 75px; height: 20px; border-radius: 20px;"></div>
|
|
349
|
+
</td>
|
|
350
|
+
<td>
|
|
351
|
+
<div class="shimmer-placeholder" style="width: 60px; height: 20px; border-radius: 20px;"></div>
|
|
352
|
+
</td>
|
|
353
|
+
<td>
|
|
354
|
+
<div class="shimmer-placeholder" style="width: 65px; height: 26px; border-radius: 6px;"></div>
|
|
355
|
+
</td>
|
|
356
|
+
</tr>
|
|
357
|
+
<tr>
|
|
358
|
+
<td>
|
|
359
|
+
<div class="shimmer-placeholder" style="width: 150px; height: 16px; margin-bottom: 4px;"></div>
|
|
360
|
+
<br>
|
|
361
|
+
<div class="shimmer-placeholder" style="width: 90px; height: 12px;"></div>
|
|
362
|
+
</td>
|
|
363
|
+
<td>
|
|
364
|
+
<div class="shimmer-placeholder" style="width: 35px; height: 16px;"></div>
|
|
365
|
+
</td>
|
|
366
|
+
<td>
|
|
367
|
+
<div class="shimmer-placeholder" style="width: 75px; height: 20px; border-radius: 20px;"></div>
|
|
368
|
+
</td>
|
|
369
|
+
<td>
|
|
370
|
+
<div class="shimmer-placeholder" style="width: 60px; height: 20px; border-radius: 20px;"></div>
|
|
371
|
+
</td>
|
|
372
|
+
<td>
|
|
373
|
+
<div class="shimmer-placeholder" style="width: 65px; height: 26px; border-radius: 6px;"></div>
|
|
374
|
+
</td>
|
|
375
|
+
</tr>
|
|
376
|
+
</tbody>
|
|
377
|
+
</table>
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
<div class="card">
|
|
381
|
+
<div class="panel-head">
|
|
382
|
+
<div>
|
|
383
|
+
<h3>Action log</h3>
|
|
384
|
+
<p>Audit log gần nhất.</p>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
387
|
+
<div class="list">
|
|
388
|
+
<div class="item" style="border: none;">
|
|
389
|
+
<div>
|
|
390
|
+
<div class="shimmer-placeholder" style="width: 110px; height: 15px; margin-bottom: 6px;"></div>
|
|
391
|
+
<div class="shimmer-placeholder" style="width: 170px; height: 11px;"></div>
|
|
392
|
+
</div>
|
|
393
|
+
<div class="shimmer-placeholder" style="width: 30px; height: 18px; border-radius: 4px;"></div>
|
|
394
|
+
</div>
|
|
395
|
+
<div class="item" style="border: none;">
|
|
396
|
+
<div>
|
|
397
|
+
<div class="shimmer-placeholder" style="width: 130px; height: 15px; margin-bottom: 6px;"></div>
|
|
398
|
+
<div class="shimmer-placeholder" style="width: 150px; height: 11px;"></div>
|
|
399
|
+
</div>
|
|
400
|
+
<div class="shimmer-placeholder" style="width: 30px; height: 18px; border-radius: 4px;"></div>
|
|
401
|
+
</div>
|
|
402
|
+
<div class="item" style="border: none;">
|
|
403
|
+
<div>
|
|
404
|
+
<div class="shimmer-placeholder" style="width: 120px; height: 15px; margin-bottom: 6px;"></div>
|
|
405
|
+
<div class="shimmer-placeholder" style="width: 190px; height: 11px;"></div>
|
|
406
|
+
</div>
|
|
407
|
+
<div class="shimmer-placeholder" style="width: 30px; height: 18px; border-radius: 4px;"></div>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
</div>
|
|
411
|
+
</div>
|
|
412
|
+
</section>
|
|
413
|
+
<section class="section" id="groups">
|
|
414
|
+
<div class="page-head">
|
|
415
|
+
<div>
|
|
416
|
+
<h2>Nhóm</h2>
|
|
417
|
+
<p>Quản lý danh sách group, link mời, admin, setting và trạng thái plugin theo từng group.</p>
|
|
418
|
+
</div>
|
|
419
|
+
<div class="actions">
|
|
420
|
+
<button class="btn" data-action="sync">Import session</button>
|
|
421
|
+
<button class="btn primary" type="button" disabled
|
|
422
|
+
title="Create group sẽ được bật sau khi thêm form member bắt buộc">Create group</button>
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
425
|
+
<div class="card">
|
|
426
|
+
<div class="panel-head" style="flex-wrap: wrap; gap: 12px;">
|
|
427
|
+
<div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap;">
|
|
428
|
+
<div class="segmented">
|
|
429
|
+
<button class="active" data-group-filter="all">All</button><button
|
|
430
|
+
data-group-filter="silent">Silent</button><button data-group-filter="welcome">Welcome</button><button
|
|
431
|
+
data-group-filter="muted">Muted</button><button data-group-filter="spam">Spam</button>
|
|
432
|
+
</div>
|
|
433
|
+
<div id="groupBotFilters" class="bot-filters-container"></div>
|
|
434
|
+
</div>
|
|
435
|
+
<div class="bulk-bar">
|
|
436
|
+
<strong id="bulkCount">0 group selected</strong>
|
|
437
|
+
<div class="bulk-actions" id="bulkActions"></div>
|
|
438
|
+
</div>
|
|
439
|
+
</div>
|
|
440
|
+
<div class="table-wrap">
|
|
441
|
+
<table>
|
|
442
|
+
<thead>
|
|
443
|
+
<tr>
|
|
444
|
+
<th>Group</th>
|
|
445
|
+
<th>Approval</th>
|
|
446
|
+
<th>Features</th>
|
|
447
|
+
<th>Smart modes</th>
|
|
448
|
+
</tr>
|
|
449
|
+
</thead>
|
|
450
|
+
<tbody>
|
|
451
|
+
<tr>
|
|
452
|
+
<td><strong>OpenClaw Zalo Setup</strong><small>1,284 members · 18 pending</small></td>
|
|
453
|
+
<td>1 owner · 6 admins</td>
|
|
454
|
+
<td><span class="status on">Enabled</span></td>
|
|
455
|
+
<td>Silent, Welcome, Tracking</td>
|
|
456
|
+
<td><button class="btn">Settings</button></td>
|
|
457
|
+
</tr>
|
|
458
|
+
<tr>
|
|
459
|
+
<td><strong>AI Automation VN</strong><small>846 members · 9 pending</small></td>
|
|
460
|
+
<td>1 owner · 3 admins</td>
|
|
461
|
+
<td><span class="status off">Disabled</span></td>
|
|
462
|
+
<td>Welcome</td>
|
|
463
|
+
<td><button class="btn">Settings</button></td>
|
|
464
|
+
</tr>
|
|
465
|
+
<tr>
|
|
466
|
+
<td><strong>Support Docker VPS</strong><small>392 members · 0 pending</small></td>
|
|
467
|
+
<td>1 owner · 2 admins</td>
|
|
468
|
+
<td><span class="status on">Enabled</span></td>
|
|
469
|
+
<td>Spam</td>
|
|
470
|
+
<td><button class="btn">Settings</button></td>
|
|
471
|
+
</tr>
|
|
472
|
+
</tbody>
|
|
473
|
+
</table>
|
|
474
|
+
</div>
|
|
475
|
+
</div>
|
|
476
|
+
</section>
|
|
477
|
+
<section class="section" id="members">
|
|
478
|
+
<div class="page-head">
|
|
479
|
+
<div>
|
|
480
|
+
<h2>Thành viên</h2>
|
|
481
|
+
<p>Duyệt member mới, xem member list, block hoặc xóa member với confirmation rõ ràng.</p>
|
|
482
|
+
</div>
|
|
483
|
+
</div>
|
|
484
|
+
<div style="width: 100%; margin-top: 14px;">
|
|
485
|
+
<div class="card" style="padding: 16px;">
|
|
486
|
+
<!-- Consolidated Toolbar: Merge Chọn nhóm and Bulk Bar to 1 Row -->
|
|
487
|
+
<div class="members-toolbar"
|
|
488
|
+
style="border-bottom: 1px solid var(--border); padding-bottom: 16px; margin-bottom: 16px;">
|
|
489
|
+
<div
|
|
490
|
+
style="display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; width: 100%;">
|
|
491
|
+
<!-- Group Select (Left side) -->
|
|
492
|
+
<div class="members-group-select" style="position: relative;">
|
|
493
|
+
<span style="font-weight: 600; color: var(--text-muted); font-size: 13px; white-space: nowrap;">Chọn
|
|
494
|
+
nhóm:</span>
|
|
495
|
+
<div id="memberBotFilters" class="bot-filters-container"></div>
|
|
496
|
+
<div class="custom-select-container" id="membersGroupSelectContainer">
|
|
497
|
+
<div class="custom-select-trigger" id="membersGroupSelectTrigger" style="width: 100%;">
|
|
498
|
+
<div class="custom-select-trigger-content">
|
|
499
|
+
<div class="custom-select-avatar" id="selectedGroupAvatar">G</div>
|
|
500
|
+
<span class="custom-select-name" id="selectedGroupName">Chọn nhóm...</span>
|
|
501
|
+
<span class="custom-select-badge" id="selectedGroupBadge">0</span>
|
|
502
|
+
</div>
|
|
503
|
+
<svg class="custom-select-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
504
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
505
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
506
|
+
</svg>
|
|
507
|
+
</div>
|
|
508
|
+
<div class="custom-select-dropdown" id="membersGroupSelectDropdown" style="width: 100%;"></div>
|
|
509
|
+
</div>
|
|
510
|
+
<select id="membersGroupSelect" style="display: none;"></select>
|
|
511
|
+
</div>
|
|
512
|
+
|
|
513
|
+
<!-- Bulk Actions (Right side) -->
|
|
514
|
+
<div class="bulk-bar"
|
|
515
|
+
style="display: flex; align-items: center; gap: 12px; border: none; padding: 0; background: transparent; box-shadow: none; margin: 0; flex-wrap: wrap;">
|
|
516
|
+
<strong id="memberBulkCount" style="font-size: 13px; color: var(--text-muted); white-space: nowrap;">0
|
|
517
|
+
member selected</strong>
|
|
518
|
+
<div class="bulk-actions" style="display: flex; gap: 8px;">
|
|
519
|
+
<button class="btn" type="button" data-select-all-members
|
|
520
|
+
style="padding: 6px 12px; font-size: 12px; min-height: auto; border-radius: 8px; display: inline-flex; align-items: center; gap: 6px;">
|
|
521
|
+
<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2"
|
|
522
|
+
stroke-linecap="round" stroke-linejoin="round">
|
|
523
|
+
<polyline points="9 11 12 14 22 4"></polyline>
|
|
524
|
+
<path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path>
|
|
525
|
+
</svg>
|
|
526
|
+
Select all
|
|
527
|
+
</button>
|
|
528
|
+
<button class="btn" type="button" data-bulk-member-action="friend"
|
|
529
|
+
style="padding: 6px 12px; font-size: 12px; min-height: auto; border-radius: 8px; display: inline-flex; align-items: center; gap: 6px;">
|
|
530
|
+
<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2"
|
|
531
|
+
stroke-linecap="round" stroke-linejoin="round">
|
|
532
|
+
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
|
533
|
+
<circle cx="8.5" cy="7" r="4"></circle>
|
|
534
|
+
<line x1="20" y1="8" x2="20" y2="14"></line>
|
|
535
|
+
<line x1="23" y1="11" x2="17" y2="11"></line>
|
|
536
|
+
</svg>
|
|
537
|
+
Kết bạn
|
|
538
|
+
</button>
|
|
539
|
+
<button class="btn" type="button" data-bulk-member-action="message"
|
|
540
|
+
style="padding: 6px 12px; font-size: 12px; min-height: auto; border-radius: 8px; display: inline-flex; align-items: center; gap: 6px;">
|
|
541
|
+
<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2"
|
|
542
|
+
stroke-linecap="round" stroke-linejoin="round">
|
|
543
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
|
544
|
+
</svg>
|
|
545
|
+
Nhắn tin
|
|
546
|
+
</button>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
</div>
|
|
550
|
+
</div>
|
|
551
|
+
|
|
552
|
+
<div class="panel-head members-panel-head">
|
|
553
|
+
<div class="segmented" id="membersFilterTabs">
|
|
554
|
+
<button class="active" data-member-filter="all">All members</button>
|
|
555
|
+
<button data-member-filter="pending">Pending</button>
|
|
556
|
+
<button data-member-filter="blocked">Blocked</button>
|
|
557
|
+
<button data-member-filter="admins">Admins</button>
|
|
558
|
+
</div>
|
|
559
|
+
<button class="btn" type="button" id="btnConfigureColumns"
|
|
560
|
+
style="padding: 8px 12px; display: inline-flex; align-items: center; justify-content: center; gap: 8px; border-radius: 8px; height: 36px; min-width: 0;"
|
|
561
|
+
title="Cấu hình hiển thị cột">
|
|
562
|
+
<!-- Table Icon -->
|
|
563
|
+
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"
|
|
564
|
+
stroke-linecap="round" stroke-linejoin="round">
|
|
565
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
566
|
+
<line x1="9" y1="3" x2="9" y2="21"></line>
|
|
567
|
+
<line x1="15" y1="3" x2="15" y2="21"></line>
|
|
568
|
+
<line x1="3" y1="9" x2="21" y2="9"></line>
|
|
569
|
+
<line x1="3" y1="15" x2="21" y2="15"></line>
|
|
570
|
+
</svg>
|
|
571
|
+
<span class="btn-text-lang" data-vi="Cài đặt bảng" data-en="Table settings">Cài đặt bảng</span>
|
|
572
|
+
</button>
|
|
573
|
+
</div>
|
|
574
|
+
|
|
575
|
+
<div id="membersTableWrapper" style="display: block; width: 100%;">
|
|
576
|
+
<!-- Beautiful paginated table will be rendered here dynamically -->
|
|
577
|
+
</div>
|
|
578
|
+
</div>
|
|
579
|
+
</div>
|
|
580
|
+
</section>
|
|
581
|
+
<section class="section" id="journal">
|
|
582
|
+
<div class="page-head">
|
|
583
|
+
<div>
|
|
584
|
+
<h2>Nhật ký nhóm</h2>
|
|
585
|
+
<p>Tóm tắt chat theo ngày, note, memory, chat thô và lịch báo cáo tự động của từng nhóm.</p>
|
|
586
|
+
</div>
|
|
587
|
+
</div>
|
|
588
|
+
<div style="width: 100%; margin-top: 14px;">
|
|
589
|
+
<div id="journalBody"></div>
|
|
590
|
+
</div>
|
|
591
|
+
</section>
|
|
592
|
+
<section class="section" id="reports">
|
|
593
|
+
<div class="page-head">
|
|
594
|
+
<div>
|
|
595
|
+
<h2>Lịch báo cáo</h2>
|
|
596
|
+
<p>Mỗi lịch chọn một tập nhóm, một giờ và nơi nhận. Báo cáo lẻ gửi riêng từng nhóm; báo cáo tổng hợp gộp tất cả nhóm đã chọn vào một tin.</p>
|
|
597
|
+
</div>
|
|
598
|
+
<div class="actions">
|
|
599
|
+
<button class="btn primary" data-action="report-job-new">+ Tạo lịch</button>
|
|
600
|
+
</div>
|
|
601
|
+
</div>
|
|
602
|
+
<div style="width: 100%; margin-top: 14px;">
|
|
603
|
+
<div id="reportsBody"></div>
|
|
604
|
+
</div>
|
|
605
|
+
</section>
|
|
606
|
+
<section class="section" id="reportlog">
|
|
607
|
+
<div class="page-head">
|
|
608
|
+
<div>
|
|
609
|
+
<h2>Lịch sử báo cáo</h2>
|
|
610
|
+
<p>Đúng nội dung bot đã gửi, lưu lại lúc gửi. Không phải dựng lại — nên đổi lịch về sau không làm sai bản cũ.</p>
|
|
611
|
+
</div>
|
|
612
|
+
</div>
|
|
613
|
+
<div style="width: 100%; margin-top: 14px;">
|
|
614
|
+
<div id="reportLogBody"></div>
|
|
615
|
+
</div>
|
|
616
|
+
</section>
|
|
617
|
+
<section class="section" id="chat">
|
|
618
|
+
<div class="page-head">
|
|
619
|
+
<div>
|
|
620
|
+
<h2>Khung chat</h2>
|
|
621
|
+
<p>Đọc lại hội thoại Zalo và trả lời trực tiếp — lịch sử kéo về khi bấm Sync account.</p>
|
|
622
|
+
</div>
|
|
623
|
+
<div class="actions" id="chatActions"></div>
|
|
624
|
+
</div>
|
|
625
|
+
<div id="chatBody"></div>
|
|
626
|
+
</section>
|
|
627
|
+
|
|
628
|
+
<section class="section" id="messages">
|
|
629
|
+
<div class="page-head">
|
|
630
|
+
<div>
|
|
631
|
+
<h2>Tin nhắn</h2>
|
|
632
|
+
<p>Gửi template, thông báo, link hoặc tin nhắn hàng loạt có preview và rate limit.</p>
|
|
633
|
+
</div>
|
|
634
|
+
</div>
|
|
635
|
+
<div class="layout">
|
|
636
|
+
<div class="card">
|
|
637
|
+
<div class="panel-head">
|
|
638
|
+
<div>
|
|
639
|
+
<h3>Composer</h3>
|
|
640
|
+
<p>Gửi tin theo group hoặc user.</p>
|
|
641
|
+
</div>
|
|
642
|
+
</div>
|
|
643
|
+
<form class="form">
|
|
644
|
+
<div style="display: flex; gap: 8px; margin-bottom: 12px;">
|
|
645
|
+
<button type="button" class="btn primary" id="targetTabGroup" onclick="setComposerTargetType('group')"
|
|
646
|
+
style="flex: 1; padding: 6px; font-size: 13px; font-weight: 600;">Group</button>
|
|
647
|
+
<button type="button" class="btn" id="targetTabUser" onclick="setComposerTargetType('user')"
|
|
648
|
+
style="flex: 1; padding: 6px; font-size: 13px; font-weight: 600;">User</button>
|
|
649
|
+
<button type="button" class="btn" id="targetTabCustom" onclick="setComposerTargetType('custom')"
|
|
650
|
+
style="flex: 1; padding: 6px; font-size: 13px; font-weight: 600;">Custom ID</button>
|
|
651
|
+
</div>
|
|
652
|
+
<div id="composerTargetContainer" style="margin-bottom: 12px;">
|
|
653
|
+
<label><span>Target Group</span>
|
|
654
|
+
<select id="composerTargetSelect">
|
|
655
|
+
<option>Loading...</option>
|
|
656
|
+
</select>
|
|
657
|
+
</label>
|
|
658
|
+
</div>
|
|
659
|
+
<label><span>Message</span><textarea placeholder="Nhập nội dung cần gửi..."
|
|
660
|
+
style="min-height: 100px;"></textarea></label>
|
|
661
|
+
<div class="actions">
|
|
662
|
+
<button class="btn" type="button" onclick="previewComposerMessage()"><svg class="icon"
|
|
663
|
+
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
664
|
+
stroke-linejoin="round"
|
|
665
|
+
style="width: 14px; height: 14px; margin-right: 6px; display: inline-block; vertical-align: middle;">
|
|
666
|
+
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
667
|
+
<circle cx="12" cy="12" r="3"></circle>
|
|
668
|
+
</svg>Preview</button>
|
|
669
|
+
<button class="btn primary" type="button" data-action="send"><svg class="icon" viewBox="0 0 24 24"
|
|
670
|
+
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
|
671
|
+
style="width: 14px; height: 14px; margin-right: 6px; display: inline-block; vertical-align: middle;">
|
|
672
|
+
<line x1="22" y1="2" x2="11" y2="13"></line>
|
|
673
|
+
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
|
|
674
|
+
</svg>Send message</button>
|
|
675
|
+
</div>
|
|
676
|
+
</form>
|
|
677
|
+
</div>
|
|
678
|
+
<div class="card">
|
|
679
|
+
<div class="panel-head">
|
|
680
|
+
<div>
|
|
681
|
+
<h3>Templates</h3>
|
|
682
|
+
<p>Nội quy, welcome, cảnh báo, maintenance.</p>
|
|
683
|
+
</div>
|
|
684
|
+
</div>
|
|
685
|
+
<div class="list">
|
|
686
|
+
<div class="item">
|
|
687
|
+
<div>
|
|
688
|
+
<div class="item-title">Nội quy group</div>
|
|
689
|
+
<div class="item-sub">sendMessage</div>
|
|
690
|
+
</div><button class="btn">Use</button>
|
|
691
|
+
</div>
|
|
692
|
+
<div class="item">
|
|
693
|
+
<div>
|
|
694
|
+
<div class="item-title">Cảnh báo spam link</div>
|
|
695
|
+
<div class="item-sub">sendMessage + audit</div>
|
|
696
|
+
</div><button class="btn">Use</button>
|
|
697
|
+
</div>
|
|
698
|
+
<div class="item">
|
|
699
|
+
<div>
|
|
700
|
+
<div class="item-title">Thông báo bảo trì bot</div>
|
|
701
|
+
<div class="item-sub">broadcast có rate limit</div>
|
|
702
|
+
</div><button class="btn">Use</button>
|
|
703
|
+
</div>
|
|
704
|
+
</div>
|
|
705
|
+
</div>
|
|
706
|
+
</div>
|
|
707
|
+
</section>
|
|
708
|
+
<section class="section" id="api">
|
|
709
|
+
<div class="page-head">
|
|
710
|
+
<div>
|
|
711
|
+
<h2>Danh mục API</h2>
|
|
712
|
+
<p>Catalog nhóm API ZCA thành workflow rõ ràng. Action nguy hiểm cần confirm và audit log.</p>
|
|
713
|
+
</div>
|
|
714
|
+
</div>
|
|
715
|
+
<div class="api-grid">
|
|
716
|
+
<div class="api-card">
|
|
717
|
+
<h4>Group info</h4>
|
|
718
|
+
<p>Đọc group, member, pending, blocked, invite link.</p>
|
|
719
|
+
<div class="chips"><span class="chip">getAllGroups</span><span class="chip">getGroupInfo</span><span
|
|
720
|
+
class="chip">getPendingGroupMembers</span></div>
|
|
721
|
+
</div>
|
|
722
|
+
<div class="api-card">
|
|
723
|
+
<h4>Member ops</h4>
|
|
724
|
+
<p>Duyệt, mời, thêm, xóa, block member.</p>
|
|
725
|
+
<div class="chips"><span class="chip">reviewPendingMemberRequest</span><span
|
|
726
|
+
class="chip">removeUserFromGroup</span><span class="chip">addUserToGroup</span></div>
|
|
727
|
+
</div>
|
|
728
|
+
<div class="api-card">
|
|
729
|
+
<h4>Bạn bè</h4>
|
|
730
|
+
<p>Quản lý request, danh bạ, alias, lời mời kết bạn.</p>
|
|
731
|
+
<div class="chips"><span class="chip">acceptFriendRequest</span><span
|
|
732
|
+
class="chip">sendFriendRequest</span><span class="chip">getAllFriends</span></div>
|
|
733
|
+
</div>
|
|
734
|
+
<div class="api-card">
|
|
735
|
+
<h4>Messaging</h4>
|
|
736
|
+
<p>Gửi text, link, sticker, voice, video, forward.</p>
|
|
737
|
+
<div class="chips"><span class="chip">sendMessage</span><span class="chip">sendLink</span><span
|
|
738
|
+
class="chip">forwardMessage</span></div>
|
|
739
|
+
</div>
|
|
740
|
+
<div class="api-card">
|
|
741
|
+
<h4>Engagement</h4>
|
|
742
|
+
<p>Poll, note, reminder cho group.</p>
|
|
743
|
+
<div class="chips"><span class="chip">createPoll</span><span class="chip">createNote</span><span
|
|
744
|
+
class="chip">createReminder</span></div>
|
|
745
|
+
</div>
|
|
746
|
+
<div class="api-card">
|
|
747
|
+
<h4>Settings</h4>
|
|
748
|
+
<p>Mute, pin, hidden, account setting, group setting.</p>
|
|
749
|
+
<div class="chips"><span class="chip">updateGroupSettings</span><span class="chip">setMute</span><span
|
|
750
|
+
class="chip">updateSettings</span></div>
|
|
751
|
+
</div>
|
|
752
|
+
</div>
|
|
753
|
+
</section>
|
|
754
|
+
<section class="section" id="upgrade">
|
|
755
|
+
<div class="page-head">
|
|
756
|
+
<div>
|
|
757
|
+
<h2>Nâng cấp</h2>
|
|
758
|
+
<p>Bạn vẫn dùng được UI miễn phí. Nâng cấp để mở khóa điều khiển nâng cao.</p>
|
|
759
|
+
</div>
|
|
760
|
+
</div>
|
|
761
|
+
<div class="upgrade-note license-box" id="unifiedLicenseBox"
|
|
762
|
+
style="padding: 24px; border-radius: 12px; background: var(--bg-card); border: 1px solid var(--border); display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 800px; margin: 0 auto 24px auto; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);">
|
|
763
|
+
<!-- Premium Shimmer Loader (Static Placeholder before API loads) -->
|
|
764
|
+
<div class="license-info" style="display: flex; flex-direction: column; gap: 12px; width: 100%;">
|
|
765
|
+
<div
|
|
766
|
+
style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; border-bottom: 1px solid var(--border); padding-bottom: 12px;">
|
|
767
|
+
<div>
|
|
768
|
+
<div class="shimmer-placeholder" style="width: 120px; height: 14px; margin-bottom: 6px;"></div>
|
|
769
|
+
<div class="shimmer-placeholder" style="width: 180px; height: 22px; border-radius: 20px;"></div>
|
|
770
|
+
</div>
|
|
771
|
+
<div style="display: flex; flex-direction: column; align-items: flex-end;">
|
|
772
|
+
<div class="shimmer-placeholder" style="width: 100px; height: 14px; margin-bottom: 6px;"></div>
|
|
773
|
+
<div class="shimmer-placeholder" style="width: 140px; height: 20px; border-radius: 6px;"></div>
|
|
774
|
+
</div>
|
|
775
|
+
</div>
|
|
776
|
+
<div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
|
|
777
|
+
<div style="display: flex; align-items: center; gap: 10px;">
|
|
778
|
+
<div class="shimmer-placeholder" style="width: 100px; height: 16px;"></div>
|
|
779
|
+
<div class="shimmer-placeholder" style="width: 160px; height: 20px; border-radius: 6px;"></div>
|
|
780
|
+
</div>
|
|
781
|
+
<div class="shimmer-placeholder" style="width: 110px; height: 32px; border-radius: 6px;"></div>
|
|
782
|
+
</div>
|
|
783
|
+
</div>
|
|
784
|
+
</div>
|
|
785
|
+
<div class="pricing-grid">
|
|
786
|
+
<article class="plan-card">
|
|
787
|
+
<div class="plan-badge" data-i18n-badge="free">Free</div>
|
|
788
|
+
<h3 data-i18n-title="free">Gói Free</h3>
|
|
789
|
+
<div class="plan-price-container">
|
|
790
|
+
<div class="plan-price">0đ</div>
|
|
791
|
+
<p class="plan-sub" data-i18n-sub="free">Mở đầu trải nghiệm</p>
|
|
792
|
+
</div>
|
|
793
|
+
<ul class="plan-list">
|
|
794
|
+
<li>
|
|
795
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
796
|
+
stroke-linejoin="round">
|
|
797
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
798
|
+
</svg>
|
|
799
|
+
<span data-i18n-feature="free-1">Dùng toàn bộ UI dashboard</span>
|
|
800
|
+
</li>
|
|
801
|
+
<li>
|
|
802
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
803
|
+
stroke-linejoin="round">
|
|
804
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
805
|
+
</svg>
|
|
806
|
+
<span data-i18n-feature="free-2">Xem dữ liệu group/member/log</span>
|
|
807
|
+
</li>
|
|
808
|
+
<li>
|
|
809
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
810
|
+
stroke-linejoin="round">
|
|
811
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
812
|
+
</svg>
|
|
813
|
+
<span data-i18n-feature="free-3">Thao tác từng group/member</span>
|
|
814
|
+
</li>
|
|
815
|
+
</ul>
|
|
816
|
+
<a class="plan-cta plan-cta--outline" data-i18n-btn="free" href="javascript:handlePricingUpgrade()">Trải
|
|
817
|
+
nghiệm ngay</a>
|
|
818
|
+
</article>
|
|
819
|
+
|
|
820
|
+
<article class="plan-card plan-card--featured">
|
|
821
|
+
<div class="plan-badge" data-i18n-badge="personal">Cá nhân</div>
|
|
822
|
+
<h3 data-i18n-title="personal">Gói Cá nhân</h3>
|
|
823
|
+
<div class="plan-price-container">
|
|
824
|
+
<div class="plan-price">99.000đ<span data-i18n-period="month">/tháng</span></div>
|
|
825
|
+
<p class="plan-sub" data-i18n-sub="personal">hoặc 990.000đ / 12 tháng</p>
|
|
826
|
+
</div>
|
|
827
|
+
<ul class="plan-list">
|
|
828
|
+
<li>
|
|
829
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
830
|
+
stroke-linejoin="round">
|
|
831
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
832
|
+
</svg>
|
|
833
|
+
<span data-i18n-feature="personal-1">Nhiều group, hàng loạt và All</span>
|
|
834
|
+
</li>
|
|
835
|
+
<li>
|
|
836
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
837
|
+
stroke-linejoin="round">
|
|
838
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
839
|
+
</svg>
|
|
840
|
+
<span data-i18n-feature="personal-2">Tặng 30 ngày Pro khi cài lần đầu</span>
|
|
841
|
+
</li>
|
|
842
|
+
<li>
|
|
843
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
844
|
+
stroke-linejoin="round">
|
|
845
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
846
|
+
</svg>
|
|
847
|
+
<span data-i18n-feature="personal-3">Dùng cho 1 owner account</span>
|
|
848
|
+
</li>
|
|
849
|
+
</ul>
|
|
850
|
+
<a class="plan-cta plan-cta--solid" data-i18n-btn="personal"
|
|
851
|
+
href="javascript:handlePricingUpgrade('personal')">Nâng cấp Cá nhân</a>
|
|
852
|
+
</article>
|
|
853
|
+
|
|
854
|
+
<article class="plan-card">
|
|
855
|
+
<div class="plan-badge" data-i18n-badge="team">Team</div>
|
|
856
|
+
<h3 data-i18n-title="team">Gói Team</h3>
|
|
857
|
+
<div class="plan-price-container">
|
|
858
|
+
<div class="plan-price">299.000đ<span data-i18n-period="month">/tháng</span></div>
|
|
859
|
+
<p class="plan-sub" data-i18n-sub="team">hoặc 2.990.000đ / 12 tháng</p>
|
|
860
|
+
</div>
|
|
861
|
+
<ul class="plan-list">
|
|
862
|
+
<li>
|
|
863
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
864
|
+
stroke-linejoin="round">
|
|
865
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
866
|
+
</svg>
|
|
867
|
+
<span data-i18n-feature="team-1">Thao tác nhiều bot cùng lúc</span>
|
|
868
|
+
</li>
|
|
869
|
+
<li>
|
|
870
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
871
|
+
stroke-linejoin="round">
|
|
872
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
873
|
+
</svg>
|
|
874
|
+
<span data-i18n-feature="team-2">Ưu tiên hỗ trợ nhanh hơn</span>
|
|
875
|
+
</li>
|
|
876
|
+
<li>
|
|
877
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
878
|
+
stroke-linejoin="round">
|
|
879
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
880
|
+
</svg>
|
|
881
|
+
<span data-i18n-feature="team-3">Bao gồm toàn bộ quyền Pro</span>
|
|
882
|
+
</li>
|
|
883
|
+
</ul>
|
|
884
|
+
<a class="plan-cta plan-cta--outline" data-i18n-btn="team"
|
|
885
|
+
href="javascript:handlePricingUpgrade('team')">Đăng ký Team</a>
|
|
886
|
+
</article>
|
|
887
|
+
|
|
888
|
+
<article class="plan-card">
|
|
889
|
+
<div class="plan-badge" data-i18n-badge="lifetime">Vĩnh viễn</div>
|
|
890
|
+
<h3 data-i18n-title="lifetime">Gói Lifetime</h3>
|
|
891
|
+
<div class="plan-price-container">
|
|
892
|
+
<div class="plan-price">5.000.000đ</div>
|
|
893
|
+
<p class="plan-sub" data-i18n-sub="lifetime">Thanh toán một lần duy nhất</p>
|
|
894
|
+
</div>
|
|
895
|
+
<ul class="plan-list">
|
|
896
|
+
<li>
|
|
897
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
898
|
+
stroke-linejoin="round">
|
|
899
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
900
|
+
</svg>
|
|
901
|
+
<span data-i18n-feature="lifetime-1">Sử dụng vĩnh viễn trọn đời</span>
|
|
902
|
+
</li>
|
|
903
|
+
<li>
|
|
904
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
905
|
+
stroke-linejoin="round">
|
|
906
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
907
|
+
</svg>
|
|
908
|
+
<span data-i18n-feature="lifetime-2">Kích hoạt theo chính sách plugin</span>
|
|
909
|
+
</li>
|
|
910
|
+
<li>
|
|
911
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"
|
|
912
|
+
stroke-linejoin="round">
|
|
913
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
914
|
+
</svg>
|
|
915
|
+
<span data-i18n-feature="lifetime-3">Phù hợp sử dụng lâu dài ổn định</span>
|
|
916
|
+
</li>
|
|
917
|
+
</ul>
|
|
918
|
+
<a class="plan-cta plan-cta--outline" data-i18n-btn="lifetime"
|
|
919
|
+
href="javascript:handlePricingUpgrade('lifetime')">Mua Lifetime</a>
|
|
920
|
+
</article>
|
|
921
|
+
</div>
|
|
922
|
+
</section>
|
|
923
|
+
<section class="section" id="settings">
|
|
924
|
+
<div class="page-head">
|
|
925
|
+
<div>
|
|
926
|
+
<h2>Cài đặt</h2>
|
|
927
|
+
<p>Tùy chỉnh ngôn ngữ, giao diện và xem thông tin thiết bị/phiên bản để tiện kích hoạt và hỗ trợ.</p>
|
|
928
|
+
</div>
|
|
929
|
+
</div>
|
|
930
|
+
<div id="settingsBody" style="width: 100%; margin-top: 14px;"></div>
|
|
931
|
+
</section>
|
|
932
|
+
<section class="section" id="templates">
|
|
933
|
+
<div class="page-head">
|
|
934
|
+
<div>
|
|
935
|
+
<h2>Quản lý Template</h2>
|
|
936
|
+
<p>Tùy chỉnh nội dung & gán lệnh slash cho từng template: nội quy, hướng dẫn, menu, welcome, cảnh báo spam, bảo trì.</p>
|
|
937
|
+
</div>
|
|
938
|
+
</div>
|
|
939
|
+
|
|
940
|
+
<div class="templates-layout">
|
|
941
|
+
<!-- Cột bên trái: Selector -->
|
|
942
|
+
<div class="templates-sidebar card">
|
|
943
|
+
<div class="template-item active" data-template-key="noi-quy">
|
|
944
|
+
<div class="template-item-icon">📋</div>
|
|
945
|
+
<div class="template-item-meta">
|
|
946
|
+
<strong>Nội quy nhóm</strong>
|
|
947
|
+
<span>noi-quy.txt</span>
|
|
948
|
+
</div>
|
|
949
|
+
</div>
|
|
950
|
+
<div class="template-item" data-template-key="huong-dan">
|
|
951
|
+
<div class="template-item-icon">📖</div>
|
|
952
|
+
<div class="template-item-meta">
|
|
953
|
+
<strong>Hướng dẫn dùng bot</strong>
|
|
954
|
+
<span>huong-dan.txt</span>
|
|
955
|
+
</div>
|
|
956
|
+
</div>
|
|
957
|
+
<div class="template-item" data-template-key="menu">
|
|
958
|
+
<div class="template-item-icon">🤖</div>
|
|
959
|
+
<div class="template-item-meta">
|
|
960
|
+
<strong>Menu lệnh</strong>
|
|
961
|
+
<span>menu.txt</span>
|
|
962
|
+
</div>
|
|
963
|
+
</div>
|
|
964
|
+
<div class="template-item" data-template-key="welcome">
|
|
965
|
+
<div class="template-item-icon">👋</div>
|
|
966
|
+
<div class="template-item-meta">
|
|
967
|
+
<strong>Chào mừng thành viên</strong>
|
|
968
|
+
<span>welcome.txt</span>
|
|
969
|
+
</div>
|
|
970
|
+
</div>
|
|
971
|
+
<div class="template-item" data-template-key="spam-warning">
|
|
972
|
+
<div class="template-item-icon">⚠️</div>
|
|
973
|
+
<div class="template-item-meta">
|
|
974
|
+
<strong>Cảnh báo spam link</strong>
|
|
975
|
+
<span>spam-warning.txt</span>
|
|
976
|
+
</div>
|
|
977
|
+
</div>
|
|
978
|
+
<div class="template-item" data-template-key="maintenance">
|
|
979
|
+
<div class="template-item-icon">🔧</div>
|
|
980
|
+
<div class="template-item-meta">
|
|
981
|
+
<strong>Thông báo bảo trì bot</strong>
|
|
982
|
+
<span>maintenance.txt</span>
|
|
983
|
+
</div>
|
|
984
|
+
</div>
|
|
985
|
+
</div>
|
|
986
|
+
|
|
987
|
+
<!-- Cột bên phải: Editor -->
|
|
988
|
+
<div class="templates-editor card">
|
|
989
|
+
<div class="editor-head">
|
|
990
|
+
<h4 id="current-template-title">Nội quy nhóm</h4>
|
|
991
|
+
<span class="file-badge" id="current-template-file">noi-quy.txt</span>
|
|
992
|
+
</div>
|
|
993
|
+
<div class="editor-cmd" id="template-cmd-row" style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 12px;">
|
|
994
|
+
<label for="template-command" style="font-size:13px;color:var(--muted);white-space:nowrap;font-weight:600;">Lệnh slash:</label>
|
|
995
|
+
<span id="template-command-prefix" style="font-family:ui-monospace,monospace;color:var(--muted);"></span>
|
|
996
|
+
<input type="text" id="template-command" placeholder="vd: noi-quy — để trống = không gán lệnh" style="flex:1;min-width:160px;padding:7px 10px;border:1px solid var(--border);border-radius:8px;background:var(--bg);color:var(--text);font-family:ui-monospace,monospace;" />
|
|
997
|
+
<span id="template-command-hint" style="font-size:12px;color:var(--muted);flex-basis:100%;"></span>
|
|
998
|
+
</div>
|
|
999
|
+
<div class="editor-body">
|
|
1000
|
+
<textarea id="template-textarea" spellcheck="false" placeholder="Nhập nội dung template..."></textarea>
|
|
1001
|
+
</div>
|
|
1002
|
+
|
|
1003
|
+
<!-- Bảng cheatsheet biến -->
|
|
1004
|
+
<div class="cheatsheet">
|
|
1005
|
+
<h5 style="margin: 0 0 10px; font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em;">Biến có thể sử dụng (Click để chèn):</h5>
|
|
1006
|
+
<div class="variable-tags">
|
|
1007
|
+
<span class="var-tag" title="Tên nhóm chat Zalo" data-var="{groupName}"><code>{groupName}</code> - Tên nhóm</span>
|
|
1008
|
+
<span class="var-tag" title="Tên bot" data-var="{botName}"><code>{botName}</code> - Tên bot</span>
|
|
1009
|
+
<span class="var-tag" title="Tên bot viết hoa" data-var="{BOTNAME}"><code>{BOTNAME}</code> - Tên bot viết hoa</span>
|
|
1010
|
+
<span class="var-tag" title="Prefix lệnh (ví dụ /williams-)" data-var="{cmdPrefix}"><code>{cmdPrefix}</code> - Prefix lệnh</span>
|
|
1011
|
+
<span class="var-tag var-member-only" title="Tên thành viên (welcome / cảnh báo spam)" data-var="{memberName}" style="display: none;"><code>{memberName}</code> - Tên thành viên</span>
|
|
1012
|
+
<span class="var-tag var-menu-only" title="Danh sách slash commands chế độ tính năng" data-var="{customModes}" style="display: none;"><code>{customModes}</code> - Chế độ tính năng</span>
|
|
1013
|
+
</div>
|
|
1014
|
+
</div>
|
|
1015
|
+
|
|
1016
|
+
<div class="editor-foot">
|
|
1017
|
+
<button class="btn" type="button" id="btn-preview-template">Xem trước</button>
|
|
1018
|
+
<button class="btn primary" type="button" id="btn-save-template">Lưu cấu hình</button>
|
|
1019
|
+
</div>
|
|
1020
|
+
</div>
|
|
1021
|
+
</div>
|
|
1022
|
+
</section>
|
|
1023
|
+
<section class="section" id="permissions">
|
|
1024
|
+
<div class="page-head">
|
|
1025
|
+
<div>
|
|
1026
|
+
<h2>Phân quyền</h2>
|
|
1027
|
+
<p>Kiểm soát ai được nhắn riêng (DM) với bot, bot hoạt động ở nhóm nào, và ai được dùng lệnh /note & /memory.</p>
|
|
1028
|
+
</div>
|
|
1029
|
+
</div>
|
|
1030
|
+
<div class="perm-grid" id="permContent"></div>
|
|
1031
|
+
</section>
|
|
1032
|
+
<section class="section" id="contacts">
|
|
1033
|
+
<div class="page-head">
|
|
1034
|
+
<div>
|
|
1035
|
+
<h2>Liên hệ</h2>
|
|
1036
|
+
<p>Bạn bè và khách hàng chưa kết bạn, gộp chung một chỗ — nhãn Zalo, sinh nhật, nhóm, liên kết lead.</p>
|
|
1037
|
+
</div>
|
|
1038
|
+
<div class="actions" id="crmContactsActions"></div>
|
|
1039
|
+
</div>
|
|
1040
|
+
<div id="crmContactsBody"></div>
|
|
1041
|
+
<div id="crmFriendOps"></div>
|
|
1042
|
+
</section>
|
|
1043
|
+
|
|
1044
|
+
<section class="section" id="leads">
|
|
1045
|
+
<div class="page-head">
|
|
1046
|
+
<div>
|
|
1047
|
+
<h2>Cơ hội bán hàng</h2>
|
|
1048
|
+
<p>Kéo thả lead qua các giai đoạn: Mới → Đã liên hệ → Tiềm năng → Đã báo giá → Thắng/Thua.</p>
|
|
1049
|
+
</div>
|
|
1050
|
+
<div class="actions" id="crmLeadsActions"></div>
|
|
1051
|
+
</div>
|
|
1052
|
+
<div id="crmUndoBar"></div>
|
|
1053
|
+
<div id="crmLeadsBody"></div>
|
|
1054
|
+
</section>
|
|
1055
|
+
|
|
1056
|
+
<section class="section" id="tasks">
|
|
1057
|
+
<div class="page-head">
|
|
1058
|
+
<div>
|
|
1059
|
+
<h2>Công việc</h2>
|
|
1060
|
+
<p>Việc cần làm, hạn chót, nhắc quá hạn — gắn với khách hàng hoặc lead.</p>
|
|
1061
|
+
</div>
|
|
1062
|
+
<div class="actions" id="crmTasksActions"></div>
|
|
1063
|
+
</div>
|
|
1064
|
+
<div id="crmTasksBody"></div>
|
|
1065
|
+
</section>
|
|
1066
|
+
|
|
1067
|
+
<footer class="site-footer">
|
|
1068
|
+
<div class="footer-content" style="width: 100%;">
|
|
1069
|
+
<p class="footer-copyright" style="margin: 0; font-size: 11px; opacity: 0.6;">
|
|
1070
|
+
Copyright © 2026 <strong>Được làm ❤️ bởi tuanminhole</strong>. Phát hành theo MIT.
|
|
1071
|
+
</p>
|
|
1072
|
+
<p class="footer-donate-text"
|
|
1073
|
+
style="margin: 0; font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 4px; flex-wrap: wrap; justify-content: center;">
|
|
1074
|
+
<span>Nếu công cụ này giúp ích cho bạn, hãy mời mình một ly cà phê nhé! <span
|
|
1075
|
+
class="heart-emoji">❤️</span></span>
|
|
1076
|
+
<button class="btn-donate" type="button" onclick="openDonateModal()">
|
|
1077
|
+
<svg class="donate-btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"
|
|
1078
|
+
stroke-linecap="round" stroke-linejoin="round"
|
|
1079
|
+
style="width: 12px; height: 12px; vertical-align: middle;">
|
|
1080
|
+
<path d="M18 8h1a4 4 0 0 1 0 8h-1"></path>
|
|
1081
|
+
<path d="M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z"></path>
|
|
1082
|
+
<line x1="6" y1="1" x2="6" y2="4"></line>
|
|
1083
|
+
<line x1="10" y1="1" x2="10" y2="4"></line>
|
|
1084
|
+
<line x1="14" y1="1" x2="14" y2="4"></line>
|
|
1085
|
+
</svg>
|
|
1086
|
+
<span>Mời Cafe</span>
|
|
1087
|
+
</button>
|
|
1088
|
+
</p>
|
|
1089
|
+
</div>
|
|
1090
|
+
</footer> </main>
|
|
1091
|
+
</div>
|
|
1092
|
+
<nav class="bottom-nav" data-bottom-nav aria-label="Mobile navigation">
|
|
1093
|
+
<button class="active" data-section="overview" aria-label="Overview"><svg class="icon" viewBox="0 0 24 24"
|
|
1094
|
+
fill="none">
|
|
1095
|
+
<path d="M4 13h6V4H4v9Zm10 7h6V4h-6v16ZM4 20h6v-4H4v4Z" stroke="currentColor" stroke-width="2" />
|
|
1096
|
+
</svg><span>Home</span></button>
|
|
1097
|
+
<button data-section="groups" aria-label="Nhóm"><svg class="icon" viewBox="0 0 24 24" fill="none">
|
|
1098
|
+
<path
|
|
1099
|
+
d="M16 11a4 4 0 1 0-8 0m8 0a4 4 0 1 1-8 0m8 0h3a3 3 0 0 1 3 3v3M8 11H5a3 3 0 0 0-3 3v3m5 3v-2a5 5 0 0 1 10 0v2"
|
|
1100
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
|
1101
|
+
</svg><span>Nhóm</span></button>
|
|
1102
|
+
<button data-section="members" aria-label="Thành viên"><svg class="icon" viewBox="0 0 24 24" fill="none">
|
|
1103
|
+
<path d="M15 8a4 4 0 1 1-8 0 4 4 0 0 1 8 0Zm-12 13a8 8 0 0 1 16 0m0-13h3m-1.5-1.5v3" stroke="currentColor"
|
|
1104
|
+
stroke-width="2" stroke-linecap="round" />
|
|
1105
|
+
</svg><span>Thành viên</span></button>
|
|
1106
|
+
<button data-section="messages" aria-label="Tin nhắn"><svg class="icon" viewBox="0 0 24 24" fill="none">
|
|
1107
|
+
<path d="M21 12a8 8 0 0 1-8 8H6l-4 2 1.4-4.2A8 8 0 1 1 21 12Z" stroke="currentColor" stroke-width="2"
|
|
1108
|
+
stroke-linejoin="round" />
|
|
1109
|
+
</svg><span>Inbox</span></button>
|
|
1110
|
+
<button data-section="templates" aria-label="Lệnh & Rules"><svg class="icon" viewBox="0 0 24 24" fill="none">
|
|
1111
|
+
<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1112
|
+
<path d="M14 2v6h6M16 13H8m8 4H8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1113
|
+
</svg><span>Rules</span></button>
|
|
1114
|
+
<button type="button" data-open-menu aria-label="Open more menu"><svg class="icon" viewBox="0 0 24 24" fill="none">
|
|
1115
|
+
<path d="M12 5.5a1.5 1.5 0 1 0 0 .01V5.5Zm0 5a1.5 1.5 0 1 0 0 .01v-.01Zm0 5a1.5 1.5 0 1 0 0 .01v-.01Z"
|
|
1116
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
|
1117
|
+
</svg><span>More</span></button>
|
|
1118
|
+
</nav>
|
|
1119
|
+
<div class="drawer-backdrop" data-close-drawer></div>
|
|
1120
|
+
<div class="drawer" role="dialog" aria-modal="true" aria-label="Menu mobile">
|
|
1121
|
+
<div class="grabber"></div>
|
|
1122
|
+
<nav class="nav" data-drawer-nav>
|
|
1123
|
+
<button class="active" data-section="overview"><svg viewBox="0 0 24 24" fill="none">
|
|
1124
|
+
<path d="M4 13h6V4H4v9Zm10 7h6V4h-6v16ZM4 20h6v-4H4v4Z" stroke="currentColor" stroke-width="2"
|
|
1125
|
+
stroke-linejoin="round" />
|
|
1126
|
+
</svg><span class="nav-label">Tổng quan</span></button>
|
|
1127
|
+
<button data-section="groups"><svg viewBox="0 0 24 24" fill="none">
|
|
1128
|
+
<path
|
|
1129
|
+
d="M16 11a4 4 0 1 0-8 0m8 0a4 4 0 1 1-8 0m8 0h3a3 3 0 0 1 3 3v3M8 11H5a3 3 0 0 0-3 3v3m5 3v-2a5 5 0 0 1 10 0v2"
|
|
1130
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
|
1131
|
+
</svg><span class="nav-label">Nhóm</span></button>
|
|
1132
|
+
<button data-section="members"><svg viewBox="0 0 24 24" fill="none">
|
|
1133
|
+
<path d="M15 8a4 4 0 1 1-8 0 4 4 0 0 1 8 0Zm-12 13a8 8 0 0 1 16 0m0-13h3m-1.5-1.5v3" stroke="currentColor"
|
|
1134
|
+
stroke-width="2" stroke-linecap="round" />
|
|
1135
|
+
</svg><span class="nav-label">Thành viên</span></button>
|
|
1136
|
+
<button data-section="journal"><svg viewBox="0 0 24 24" fill="none">
|
|
1137
|
+
<path d="M4 5a2 2 0 0 1 2-2h9l5 5v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5Z" stroke="currentColor" stroke-width="2"
|
|
1138
|
+
stroke-linejoin="round" />
|
|
1139
|
+
<path d="M14 3v5h5M8 13h8M8 17h5" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
1140
|
+
stroke-linejoin="round" />
|
|
1141
|
+
</svg><span class="nav-label">Theo nhóm</span></button>
|
|
1142
|
+
<button data-section="reports"><svg viewBox="0 0 24 24" fill="none">
|
|
1143
|
+
<path d="M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z"
|
|
1144
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
1145
|
+
</svg><span class="nav-label">Lịch báo cáo</span></button>
|
|
1146
|
+
<button data-section="chat"><svg viewBox="0 0 24 24" fill="none">
|
|
1147
|
+
<path d="M21 12a8 8 0 0 1-8 8H6l-4 2 1.4-4.2A8 8 0 1 1 21 12Z" stroke="currentColor" stroke-width="2"
|
|
1148
|
+
stroke-linejoin="round" />
|
|
1149
|
+
</svg><span class="nav-label">Khung chat</span></button>
|
|
1150
|
+
<button data-section="messages"><svg viewBox="0 0 24 24" fill="none">
|
|
1151
|
+
<path d="M4 4h16v12H7l-3 3V4Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
|
|
1152
|
+
</svg><span class="nav-label">Gửi hàng loạt</span></button>
|
|
1153
|
+
<button data-section="templates"><svg viewBox="0 0 24 24" fill="none">
|
|
1154
|
+
<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1155
|
+
<path d="M14 2v6h6M16 13H8m8 4H8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1156
|
+
</svg><span class="nav-label">Lệnh & Rules</span></button>
|
|
1157
|
+
<button data-section="permissions"><svg viewBox="0 0 24 24" fill="none">
|
|
1158
|
+
<path d="M12 2 4 5v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V5l-8-3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1159
|
+
<path d="M9 12l2 2 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1160
|
+
</svg><span class="nav-label">Phân quyền</span></button>
|
|
1161
|
+
<button data-section="contacts"><svg viewBox="0 0 24 24" fill="none">
|
|
1162
|
+
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2m12-14a4 4 0 1 1-8 0 4 4 0 0 1 8 0Zm10 14v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1163
|
+
</svg><span class="nav-label">Khách hàng</span></button>
|
|
1164
|
+
<button data-section="leads"><svg viewBox="0 0 24 24" fill="none">
|
|
1165
|
+
<path d="M22 3H2l8 9.46V19l4 2v-8.54L22 3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1166
|
+
</svg><span class="nav-label">Cơ hội bán hàng</span></button>
|
|
1167
|
+
<button data-section="tasks"><svg viewBox="0 0 24 24" fill="none">
|
|
1168
|
+
<path d="M9 11l3 3L22 4M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1169
|
+
</svg><span class="nav-label">Công việc</span></button>
|
|
1170
|
+
<button data-section="upgrade"><svg viewBox="0 0 24 24" fill="none">
|
|
1171
|
+
<path d="m12 3 2.7 5.5 6 .9-4.3 4.2 1 5.9L12 16.6l-5.4 2.9 1-5.9L3.3 9.4l6-.9L12 3Z" stroke="currentColor"
|
|
1172
|
+
stroke-width="2" stroke-linejoin="round" />
|
|
1173
|
+
</svg><span class="nav-label">Nâng cấp</span></button>
|
|
1174
|
+
<button data-section="settings"><svg viewBox="0 0 24 24" fill="none">
|
|
1175
|
+
<path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="2" />
|
|
1176
|
+
<path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-2.9 1.2V21a2 2 0 1 1-4 0v-.1A1.7 1.7 0 0 0 7 19.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0-1.2-2.9H3a2 2 0 1 1 0-4h.1A1.7 1.7 0 0 0 4.7 7l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.9.3H9.5A1.7 1.7 0 0 0 10.5 3V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 2.9 1.2l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.9v.1a1.7 1.7 0 0 0 1.6 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" />
|
|
1177
|
+
</svg><span class="nav-label">Cài đặt</span></button>
|
|
1178
|
+
</nav>
|
|
1179
|
+
</div>
|
|
1180
|
+
<div class="toast" id="toast" role="status" aria-live="polite"></div>
|
|
1181
|
+
<div class="modal-backdrop" id="modalBackdrop" role="dialog" aria-modal="true" aria-labelledby="modalTitle">
|
|
1182
|
+
<div class="modal">
|
|
1183
|
+
<div class="modal-head">
|
|
1184
|
+
<h3 id="modalTitle">Action</h3>
|
|
1185
|
+
<p id="modalDesc"></p>
|
|
1186
|
+
</div>
|
|
1187
|
+
<div class="modal-body" id="modalBody"></div>
|
|
1188
|
+
<div class="modal-foot">
|
|
1189
|
+
<button class="btn" type="button" id="modalCancel">Hủy</button>
|
|
1190
|
+
<button class="btn primary" type="button" id="modalConfirm">OK</button>
|
|
1191
|
+
</div>
|
|
1192
|
+
</div>
|
|
1193
|
+
</div>
|
|
1194
|
+
<div class="modal-backdrop" id="previewModalBackdrop" role="dialog" aria-modal="true" aria-labelledby="previewModalTitle">
|
|
1195
|
+
<div class="modal">
|
|
1196
|
+
<div class="modal-head">
|
|
1197
|
+
<h3 id="previewModalTitle">Xem trước</h3>
|
|
1198
|
+
<p id="previewModalDesc">Bản xem trước giả lập tin nhắn trên ứng dụng Zalo</p>
|
|
1199
|
+
</div>
|
|
1200
|
+
<div class="modal-body" id="previewModalBody" style="background: var(--surface-2); font-family: monospace; white-space: pre-wrap; padding: 16px; border-radius: 8px; border: 1px solid var(--line); font-size: 13px; line-height: 1.5; max-height: 380px; overflow-y: auto;"></div>
|
|
1201
|
+
<div class="modal-foot">
|
|
1202
|
+
<button class="btn primary" type="button" id="previewModalClose">Đóng</button>
|
|
1203
|
+
</div>
|
|
1204
|
+
</div>
|
|
1205
|
+
</div>
|
|
1206
|
+
<!-- ══════════════════════════════════════════════════════════════════════ -->
|
|
1207
|
+
<!-- TIỆN ÍCH — FB Crawler Manager -->
|
|
1208
|
+
<!-- ══════════════════════════════════════════════════════════════════════ -->
|
|
1209
|
+
|
|
1210
|
+
</body>
|
|
1211
|
+
|
|
1212
|
+
</html>
|