work-license-server 1.0.22 → 1.0.23
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/assets/admin.js +639 -180
- package/assets/landing.css +158 -0
- package/package.json +1 -1
- package/src/admin.js +219 -73
- package/src/server.js +159 -17
- package/src/store.js +246 -9
- package/src/yookassa.js +9 -4
package/assets/landing.css
CHANGED
|
@@ -764,6 +764,164 @@ html[data-theme="dark"] .sec-nav-item.active {
|
|
|
764
764
|
.sec-item:first-child { padding-top: 2px; }
|
|
765
765
|
.sec-item:last-child { border-bottom: 0; padding-bottom: 2px; }
|
|
766
766
|
|
|
767
|
+
/* ---------- Раскрывающиеся панели (аккордеоны) клиентов и франчайзеров в /admin ---------- */
|
|
768
|
+
.adm-acc-list {
|
|
769
|
+
display: flex;
|
|
770
|
+
flex-direction: column;
|
|
771
|
+
gap: 10px;
|
|
772
|
+
}
|
|
773
|
+
.adm-acc-card {
|
|
774
|
+
background: var(--panel-solid);
|
|
775
|
+
border: 1px solid var(--line-strong);
|
|
776
|
+
border-radius: 12px;
|
|
777
|
+
overflow: hidden;
|
|
778
|
+
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
|
|
779
|
+
transition: border-color .15s ease, box-shadow .15s ease;
|
|
780
|
+
}
|
|
781
|
+
.adm-acc-card.open {
|
|
782
|
+
border-color: color-mix(in srgb, #3b82f6 50%, var(--line-strong));
|
|
783
|
+
box-shadow: 0 3px 10px rgba(15, 23, 42, 0.06);
|
|
784
|
+
}
|
|
785
|
+
.adm-acc-head {
|
|
786
|
+
display: flex;
|
|
787
|
+
align-items: center;
|
|
788
|
+
justify-content: space-between;
|
|
789
|
+
gap: 14px;
|
|
790
|
+
padding: 13px 18px;
|
|
791
|
+
cursor: pointer;
|
|
792
|
+
user-select: none;
|
|
793
|
+
transition: background .15s ease;
|
|
794
|
+
flex-wrap: wrap;
|
|
795
|
+
}
|
|
796
|
+
.adm-acc-head:hover {
|
|
797
|
+
background: color-mix(in srgb, var(--brand) 4%, transparent);
|
|
798
|
+
}
|
|
799
|
+
.adm-acc-ident {
|
|
800
|
+
display: flex;
|
|
801
|
+
align-items: center;
|
|
802
|
+
gap: 12px;
|
|
803
|
+
min-width: 0;
|
|
804
|
+
}
|
|
805
|
+
.adm-acc-chev {
|
|
806
|
+
display: inline-flex;
|
|
807
|
+
align-items: center;
|
|
808
|
+
justify-content: center;
|
|
809
|
+
width: 22px;
|
|
810
|
+
height: 22px;
|
|
811
|
+
border-radius: 6px;
|
|
812
|
+
background: color-mix(in srgb, var(--brand) 8%, transparent);
|
|
813
|
+
color: var(--text-2);
|
|
814
|
+
font-size: 11px;
|
|
815
|
+
font-weight: 700;
|
|
816
|
+
transition: transform .18s ease, background .15s ease, color .15s ease;
|
|
817
|
+
flex-shrink: 0;
|
|
818
|
+
}
|
|
819
|
+
.adm-acc-card.open .adm-acc-chev {
|
|
820
|
+
transform: rotate(90deg);
|
|
821
|
+
background: rgba(59, 130, 246, 0.14);
|
|
822
|
+
color: #2563eb;
|
|
823
|
+
}
|
|
824
|
+
html[data-theme="dark"] .adm-acc-card.open .adm-acc-chev {
|
|
825
|
+
color: #60a5fa;
|
|
826
|
+
}
|
|
827
|
+
.adm-acc-email {
|
|
828
|
+
font-weight: 700;
|
|
829
|
+
font-size: 14.5px;
|
|
830
|
+
color: var(--text);
|
|
831
|
+
word-break: break-all;
|
|
832
|
+
}
|
|
833
|
+
.adm-acc-sub {
|
|
834
|
+
font-size: 12.5px;
|
|
835
|
+
color: var(--muted);
|
|
836
|
+
margin-top: 2px;
|
|
837
|
+
}
|
|
838
|
+
.adm-acc-badges {
|
|
839
|
+
display: flex;
|
|
840
|
+
align-items: center;
|
|
841
|
+
gap: 8px;
|
|
842
|
+
flex-wrap: wrap;
|
|
843
|
+
}
|
|
844
|
+
.adm-acc-body {
|
|
845
|
+
display: none;
|
|
846
|
+
border-top: 1px solid var(--line);
|
|
847
|
+
padding: 14px 18px 16px;
|
|
848
|
+
}
|
|
849
|
+
.adm-acc-card.open .adm-acc-body {
|
|
850
|
+
display: block;
|
|
851
|
+
}
|
|
852
|
+
.adm-profile-strip {
|
|
853
|
+
display: flex;
|
|
854
|
+
align-items: center;
|
|
855
|
+
justify-content: space-between;
|
|
856
|
+
gap: 12px;
|
|
857
|
+
flex-wrap: wrap;
|
|
858
|
+
padding: 10px 14px;
|
|
859
|
+
margin-bottom: 12px;
|
|
860
|
+
border-radius: 10px;
|
|
861
|
+
border: 1px solid var(--line);
|
|
862
|
+
background: color-mix(in srgb, var(--brand) 3%, var(--panel));
|
|
863
|
+
font-size: 12.5px;
|
|
864
|
+
}
|
|
865
|
+
.adm-profile-meta {
|
|
866
|
+
display: flex;
|
|
867
|
+
align-items: center;
|
|
868
|
+
gap: 14px;
|
|
869
|
+
flex-wrap: wrap;
|
|
870
|
+
color: var(--text-2);
|
|
871
|
+
}
|
|
872
|
+
.adm-profile-actions {
|
|
873
|
+
display: flex;
|
|
874
|
+
align-items: center;
|
|
875
|
+
gap: 8px;
|
|
876
|
+
flex-wrap: wrap;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/* ---------- Горизонтальные формы настроек в /admin (SMTP, ЮKassa, Боты, Реквизиты оферты) ---------- */
|
|
880
|
+
.adm-form-grid {
|
|
881
|
+
display: flex;
|
|
882
|
+
flex-direction: column;
|
|
883
|
+
gap: 12px;
|
|
884
|
+
}
|
|
885
|
+
.adm-form-row {
|
|
886
|
+
display: grid;
|
|
887
|
+
grid-template-columns: 220px minmax(0, 1fr);
|
|
888
|
+
align-items: center;
|
|
889
|
+
gap: 16px;
|
|
890
|
+
}
|
|
891
|
+
@media (max-width: 720px) {
|
|
892
|
+
.adm-form-row {
|
|
893
|
+
grid-template-columns: 1fr;
|
|
894
|
+
gap: 6px;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
.adm-form-label {
|
|
898
|
+
font-size: 13.5px;
|
|
899
|
+
color: var(--text-2);
|
|
900
|
+
font-weight: 500;
|
|
901
|
+
}
|
|
902
|
+
.adm-preset-bar {
|
|
903
|
+
display: flex;
|
|
904
|
+
align-items: center;
|
|
905
|
+
gap: 8px;
|
|
906
|
+
flex-wrap: wrap;
|
|
907
|
+
margin-bottom: 6px;
|
|
908
|
+
}
|
|
909
|
+
.adm-preset-btn {
|
|
910
|
+
padding: 5px 12px;
|
|
911
|
+
border-radius: 8px;
|
|
912
|
+
border: 1px solid var(--line-strong);
|
|
913
|
+
background: var(--panel);
|
|
914
|
+
color: var(--text);
|
|
915
|
+
font-size: 12.5px;
|
|
916
|
+
font-weight: 600;
|
|
917
|
+
cursor: pointer;
|
|
918
|
+
transition: border-color .15s ease, background .15s ease;
|
|
919
|
+
}
|
|
920
|
+
.adm-preset-btn:hover {
|
|
921
|
+
border-color: #3b82f6;
|
|
922
|
+
background: color-mix(in srgb, #3b82f6 8%, var(--panel));
|
|
923
|
+
}
|
|
924
|
+
|
|
767
925
|
/* ---------- Оферта и вход администратора ---------- */
|
|
768
926
|
.oferta-banner {
|
|
769
927
|
padding: 16px 22px;
|
package/package.json
CHANGED
package/src/admin.js
CHANGED
|
@@ -121,15 +121,21 @@ export function renderAdminPage({ publicKey = '', assetVersion = '' } = {}) {
|
|
|
121
121
|
|
|
122
122
|
<section class="stage active" style="padding-top:24px">
|
|
123
123
|
<div class="sec-layout">
|
|
124
|
-
<!-- Левое вертикальное меню разделов со счётчиками в скобках
|
|
124
|
+
<!-- Левое вертикальное меню разделов со счётчиками в скобках -->
|
|
125
125
|
<aside class="sec-nav" aria-label="Разделы администрирования">
|
|
126
|
-
<button type="button" class="sec-nav-item active" data-adm-tab="
|
|
127
|
-
<button type="button" class="sec-nav-item" data-adm-tab="
|
|
128
|
-
<div class="sec-nav-sep"></div>
|
|
126
|
+
<button type="button" class="sec-nav-item active" data-adm-tab="clients" id="navAdmClients">Клиенты (0)</button>
|
|
127
|
+
<button type="button" class="sec-nav-item" data-adm-tab="franchisers" id="navAdmFranchisers">Франчайзеры (0)</button>
|
|
129
128
|
<button type="button" class="sec-nav-item" data-adm-tab="orders" id="navAdmOrders">Заказы и счета (0)</button>
|
|
130
|
-
<button type="button" class="sec-nav-item" data-adm-tab="users" id="navAdmUsers">Клиенты и администраторы (0)</button>
|
|
131
129
|
<button type="button" class="sec-nav-item" data-adm-tab="tickets" id="navAdmTickets">Тикеты поддержки (0)</button>
|
|
132
130
|
<div class="sec-nav-sep"></div>
|
|
131
|
+
<button type="button" class="sec-nav-item" data-adm-tab="smtp" id="navAdmSmtp">
|
|
132
|
+
<span>Почта SMTP</span>
|
|
133
|
+
<span class="tag ok" id="navBadgeSmtp" style="padding:2px 8px;font-size:11px">активна</span>
|
|
134
|
+
</button>
|
|
135
|
+
<button type="button" class="sec-nav-item" data-adm-tab="yookassa" id="navAdmYookassa">Платёжный шлюз ЮKassa</button>
|
|
136
|
+
<button type="button" class="sec-nav-item" data-adm-tab="bots" id="navAdmBots">Боты</button>
|
|
137
|
+
<button type="button" class="sec-nav-item" data-adm-tab="legal" id="navAdmLegal">Реквизиты оферты</button>
|
|
138
|
+
<div class="sec-nav-sep"></div>
|
|
133
139
|
<div style="padding:10px 12px;border-radius:10px;border:1px solid var(--line);background:var(--panel);display:flex;flex-direction:column;gap:6px">
|
|
134
140
|
<div class="small muted" style="font-weight:700;font-size:11.5px;text-transform:uppercase;letter-spacing:.04em">Резервная копия базы</div>
|
|
135
141
|
<button type="button" class="btn btn-ghost btn-sm" style="width:100%;justify-content:flex-start;font-size:12px;padding:6px 10px" data-action="admin-export-backup">📥 Скачать бэкап (.json)</button>
|
|
@@ -142,43 +148,34 @@ export function renderAdminPage({ publicKey = '', assetVersion = '' } = {}) {
|
|
|
142
148
|
|
|
143
149
|
<!-- Правая область выбранного раздела -->
|
|
144
150
|
<div class="sec-main">
|
|
145
|
-
<!-- 1.
|
|
146
|
-
<div data-adm-sec="
|
|
151
|
+
<!-- 1. КЛИЕНТЫ (РАСКРЫВАЮЩИЕСЯ ПАНЕЛИ С СЕРВЕРАМИ И ЛИЦЕНЗИЯМИ) -->
|
|
152
|
+
<div data-adm-sec="clients">
|
|
147
153
|
<div class="sec-bar" style="margin-bottom:12px">
|
|
148
|
-
<h2 class="sec-title"
|
|
154
|
+
<h2 class="sec-title">Клиенты (серверы WORK и лицензии)</h2>
|
|
149
155
|
<div class="sec-controls">
|
|
150
|
-
<input type="search" id="
|
|
151
|
-
<select id="
|
|
152
|
-
<option value="all">Все
|
|
153
|
-
<option value="base_active">Базовая активна</option>
|
|
156
|
+
<input type="search" id="inpFilterClients" placeholder="Поиск по Email, HWID, ИНН…">
|
|
157
|
+
<select id="selFilterClients">
|
|
158
|
+
<option value="all">Все клиенты</option>
|
|
159
|
+
<option value="base_active">Базовая лицензия активна</option>
|
|
154
160
|
<option value="base_inactive">Без базовой лицензии</option>
|
|
155
161
|
<option value="hwid_bound">HWID привязан</option>
|
|
162
|
+
<option value="admins">Администраторы</option>
|
|
156
163
|
</select>
|
|
157
164
|
<button type="button" class="btn btn-primary btn-sm" data-action="open-create-server-modal">+ Добавить сервер</button>
|
|
158
165
|
</div>
|
|
159
166
|
</div>
|
|
160
|
-
<div class="
|
|
161
|
-
<
|
|
162
|
-
<thead><tr>
|
|
163
|
-
<th>Сервер / ID</th>
|
|
164
|
-
<th>Владелец / Организация</th>
|
|
165
|
-
<th>Железо (HWID)</th>
|
|
166
|
-
<th>Базовая лицензия</th>
|
|
167
|
-
<th>Доп. места и SLA</th>
|
|
168
|
-
<th style="text-align:right">Файлы</th>
|
|
169
|
-
</tr></thead>
|
|
170
|
-
<tbody id="admLicensesBody"><tr><td colspan="6" class="muted">Загрузка…</td></tr></tbody>
|
|
171
|
-
</table>
|
|
167
|
+
<div class="adm-acc-list" id="admClientsList">
|
|
168
|
+
<div class="sec-box muted">Загрузка…</div>
|
|
172
169
|
</div>
|
|
173
170
|
</div>
|
|
174
171
|
|
|
175
|
-
<!-- 2.
|
|
176
|
-
<div data-adm-sec="
|
|
172
|
+
<!-- 2. ФРАНЧАЙЗЕРЫ (РАСКРЫВАЮЩИЕСЯ ПАНЕЛИ С РЕГИОНАМИ И СТАТУСАМИ) -->
|
|
173
|
+
<div data-adm-sec="franchisers" style="display:none">
|
|
177
174
|
<div class="sec-bar" style="margin-bottom:12px">
|
|
178
|
-
<h2 class="sec-title"
|
|
175
|
+
<h2 class="sec-title">Франчайзеры (регионы РФ и текущие статусы)</h2>
|
|
179
176
|
<div class="sec-controls">
|
|
180
|
-
<input type="search" id="
|
|
181
|
-
<select id="
|
|
177
|
+
<input type="search" id="inpFilterFranchisers" placeholder="Поиск по Email, региону, ИНН…">
|
|
178
|
+
<select id="selFilterFranchisers">
|
|
182
179
|
<option value="all">Все активные</option>
|
|
183
180
|
<option value="pending_deposit">Ожидают залога (15 мин)</option>
|
|
184
181
|
<option value="deposit_paid">Погашение по графику</option>
|
|
@@ -188,18 +185,8 @@ export function renderAdminPage({ publicKey = '', assetVersion = '' } = {}) {
|
|
|
188
185
|
</select>
|
|
189
186
|
</div>
|
|
190
187
|
</div>
|
|
191
|
-
<div class="
|
|
192
|
-
<
|
|
193
|
-
<thead><tr>
|
|
194
|
-
<th>Субъект РФ / ID</th>
|
|
195
|
-
<th>Франчайзи</th>
|
|
196
|
-
<th>Залог (100 тыс. ₽)</th>
|
|
197
|
-
<th>График (12 мес.)</th>
|
|
198
|
-
<th>Оплачено / Остаток</th>
|
|
199
|
-
<th style="text-align:right">Управление</th>
|
|
200
|
-
</tr></thead>
|
|
201
|
-
<tbody id="admFranchisesBody"><tr><td colspan="6" class="muted">Загрузка…</td></tr></tbody>
|
|
202
|
-
</table>
|
|
188
|
+
<div class="adm-acc-list" id="admFranchisersList">
|
|
189
|
+
<div class="sec-box muted">Загрузка…</div>
|
|
203
190
|
</div>
|
|
204
191
|
</div>
|
|
205
192
|
|
|
@@ -232,30 +219,7 @@ export function renderAdminPage({ publicKey = '', assetVersion = '' } = {}) {
|
|
|
232
219
|
</div>
|
|
233
220
|
</div>
|
|
234
221
|
|
|
235
|
-
<!-- 4.
|
|
236
|
-
<div data-adm-sec="users" style="display:none">
|
|
237
|
-
<div class="sec-bar" style="margin-bottom:12px">
|
|
238
|
-
<h2 class="sec-title">Зарегистрированные клиенты и администраторы</h2>
|
|
239
|
-
<div class="sec-controls">
|
|
240
|
-
<input type="search" id="inpFilterUsers" placeholder="Поиск по Email, организации, ИНН…">
|
|
241
|
-
</div>
|
|
242
|
-
</div>
|
|
243
|
-
<div class="sec-box">
|
|
244
|
-
<table class="sec-table">
|
|
245
|
-
<thead><tr>
|
|
246
|
-
<th>Email / ID</th>
|
|
247
|
-
<th>Роль</th>
|
|
248
|
-
<th>Организация / ИНН</th>
|
|
249
|
-
<th>Реестры клиента</th>
|
|
250
|
-
<th>Оферта (ПЭП)</th>
|
|
251
|
-
<th style="text-align:right">Вход</th>
|
|
252
|
-
</tr></thead>
|
|
253
|
-
<tbody id="admUsersBody"><tr><td colspan="6" class="muted">Загрузка…</td></tr></tbody>
|
|
254
|
-
</table>
|
|
255
|
-
</div>
|
|
256
|
-
</div>
|
|
257
|
-
|
|
258
|
-
<!-- 5. ТИКЕТЫ ПОДДЕРЖКИ SLA -->
|
|
222
|
+
<!-- 4. ТИКЕТЫ ПОДДЕРЖКИ SLA -->
|
|
259
223
|
<div data-adm-sec="tickets" style="display:none">
|
|
260
224
|
<div class="sec-bar" style="margin-bottom:12px">
|
|
261
225
|
<h2 class="sec-title">Тикеты техподдержки SLA (MAX · Telegram · VK)</h2>
|
|
@@ -281,6 +245,183 @@ export function renderAdminPage({ publicKey = '', assetVersion = '' } = {}) {
|
|
|
281
245
|
</table>
|
|
282
246
|
</div>
|
|
283
247
|
</div>
|
|
248
|
+
|
|
249
|
+
<!-- 5. ПОЧТА SMTP -->
|
|
250
|
+
<div data-adm-sec="smtp" style="display:none">
|
|
251
|
+
<div class="sec-bar" style="margin-bottom:12px">
|
|
252
|
+
<h2 class="sec-title">Почтовый сервер SMTP (отправка кодов входа)</h2>
|
|
253
|
+
<span class="tag ok" id="admSmtpStatusTag">✓ Подключена</span>
|
|
254
|
+
</div>
|
|
255
|
+
<div class="sec-box">
|
|
256
|
+
<div class="adm-preset-bar" style="margin-bottom:14px">
|
|
257
|
+
<span class="adm-form-label" style="margin-right:4px">Шаблон сервера:</span>
|
|
258
|
+
<button type="button" class="adm-preset-btn" data-smtp-preset="yandex">Яндекс (465)</button>
|
|
259
|
+
<button type="button" class="adm-preset-btn" data-smtp-preset="gmail">Gmail (465)</button>
|
|
260
|
+
<button type="button" class="adm-preset-btn" data-smtp-preset="mailru">Mail.ru (465)</button>
|
|
261
|
+
</div>
|
|
262
|
+
<div class="adm-form-grid">
|
|
263
|
+
<div class="adm-form-row">
|
|
264
|
+
<label class="adm-form-label" for="admSmtpHost">SMTP сервер (Host)</label>
|
|
265
|
+
<input type="text" id="admSmtpHost" placeholder="smtp.yandex.ru">
|
|
266
|
+
</div>
|
|
267
|
+
<div class="adm-form-row">
|
|
268
|
+
<label class="adm-form-label" for="admSmtpPort">Порт</label>
|
|
269
|
+
<input type="number" id="admSmtpPort" placeholder="465">
|
|
270
|
+
</div>
|
|
271
|
+
<div class="adm-form-row">
|
|
272
|
+
<span class="adm-form-label">Прямой TLS (465)</span>
|
|
273
|
+
<label style="display:flex;align-items:center;gap:10px;font-size:13.5px;cursor:pointer">
|
|
274
|
+
<input type="checkbox" id="admSmtpSecure" checked style="width:17px;height:17px">
|
|
275
|
+
<span>Включён (выключите для порта 587 STARTTLS)</span>
|
|
276
|
+
</label>
|
|
277
|
+
</div>
|
|
278
|
+
<div class="adm-form-row">
|
|
279
|
+
<label class="adm-form-label" for="admSmtpUser">Логин SMTP</label>
|
|
280
|
+
<input type="text" id="admSmtpUser" placeholder="user@yandex.ru">
|
|
281
|
+
</div>
|
|
282
|
+
<div class="adm-form-row">
|
|
283
|
+
<label class="adm-form-label" for="admSmtpPass">Пароль приложения</label>
|
|
284
|
+
<input type="text" id="admSmtpPass" placeholder="Пароль приложения SMTP">
|
|
285
|
+
</div>
|
|
286
|
+
<div class="adm-form-row">
|
|
287
|
+
<label class="adm-form-label" for="admSmtpFrom">Отправитель (From)</label>
|
|
288
|
+
<input type="text" id="admSmtpFrom" placeholder="user@yandex.ru">
|
|
289
|
+
</div>
|
|
290
|
+
<div class="adm-form-row">
|
|
291
|
+
<label class="adm-form-label" for="admSmtpSenderName">Имя отправителя</label>
|
|
292
|
+
<input type="text" id="admSmtpSenderName" placeholder="ODANT-WORK">
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
<div style="display:flex;align-items:center;gap:10px;margin-top:18px;flex-wrap:wrap">
|
|
296
|
+
<button type="button" class="btn btn-primary" data-action="save-smtp-settings">Сохранить настройки SMTP</button>
|
|
297
|
+
<button type="button" class="btn btn-ghost" data-action="test-smtp-settings">Отправить тестовое письмо</button>
|
|
298
|
+
<span class="small" id="admSmtpFeedback"></span>
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<!-- 6. ПЛАТЁЖНЫЙ ШЛЮЗ ЮKASSA -->
|
|
304
|
+
<div data-adm-sec="yookassa" style="display:none">
|
|
305
|
+
<div class="sec-bar" style="margin-bottom:12px">
|
|
306
|
+
<h2 class="sec-title">Платёжный шлюз ЮKassa (API v3)</h2>
|
|
307
|
+
<span class="tag" id="admYookassaStatusTag">Режим песочницы</span>
|
|
308
|
+
</div>
|
|
309
|
+
<div class="sec-box">
|
|
310
|
+
<div style="margin-bottom:16px;font-size:13.5px;color:var(--text-2)">
|
|
311
|
+
Webhook URL для личного кабинета ЮKassa:
|
|
312
|
+
<code id="admYookassaWebhookUrl" style="padding:3px 8px;border-radius:6px;background:color-mix(in srgb,var(--brand) 8%,var(--panel))">https://${esc(P.domain)}/api/payments/yookassa/webhook</code>
|
|
313
|
+
</div>
|
|
314
|
+
<div class="adm-form-grid">
|
|
315
|
+
<div class="adm-form-row">
|
|
316
|
+
<label class="adm-form-label" for="admYkShopId">Shop ID магазина</label>
|
|
317
|
+
<input type="text" id="admYkShopId" placeholder="123456">
|
|
318
|
+
</div>
|
|
319
|
+
<div class="adm-form-row">
|
|
320
|
+
<label class="adm-form-label" for="admYkSecretKey">Секретный ключ</label>
|
|
321
|
+
<input type="text" id="admYkSecretKey" placeholder="live_... или test_...">
|
|
322
|
+
</div>
|
|
323
|
+
<div class="adm-form-row">
|
|
324
|
+
<span class="adm-form-label">Онлайн-чеки 54-ФЗ</span>
|
|
325
|
+
<label style="display:flex;align-items:center;gap:10px;font-size:13.5px;cursor:pointer">
|
|
326
|
+
<input type="checkbox" id="admYkSendReceipt" style="width:17px;height:17px">
|
|
327
|
+
<span>Передавать структуру чека (receipt)</span>
|
|
328
|
+
</label>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
<div style="display:flex;align-items:center;gap:10px;margin-top:18px;flex-wrap:wrap">
|
|
332
|
+
<button type="button" class="btn btn-primary" data-action="save-yookassa-settings">Сохранить ЮKassa</button>
|
|
333
|
+
<span class="small" id="admYkFeedback"></span>
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
</div>
|
|
337
|
+
|
|
338
|
+
<!-- 7. БОТЫ TELEGRAM И MAX -->
|
|
339
|
+
<div data-adm-sec="bots" style="display:none">
|
|
340
|
+
<div class="sec-bar" style="margin-bottom:12px">
|
|
341
|
+
<h2 class="sec-title">Боты Telegram / MAX</h2>
|
|
342
|
+
</div>
|
|
343
|
+
<div class="sec-box">
|
|
344
|
+
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:8px">
|
|
345
|
+
<h3 class="h3" style="margin:0;font-size:15.5px">Единые боты платформы Telegram и MAX</h3>
|
|
346
|
+
<div style="display:flex;gap:8px;flex-wrap:wrap" id="admBotsBadges">
|
|
347
|
+
<span class="tag" id="admBadgeTgBot">TG: не задан</span>
|
|
348
|
+
<span class="tag" id="admBadgeMaxBot">MAX: не задан</span>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
<p class="small muted" style="margin:0 0 16px;line-height:1.5">
|
|
352
|
+
Вставьте токен бота — имя бота (<code>@username</code>) определится по API автоматически. Каждый клиент привязывает свой личный чат в 1 клик и получает строго только свои собственные уведомления.
|
|
353
|
+
</p>
|
|
354
|
+
<div class="adm-form-grid">
|
|
355
|
+
<div class="adm-form-row">
|
|
356
|
+
<label class="adm-form-label" for="admBotTgToken">Токен Telegram Bot API</label>
|
|
357
|
+
<input type="text" id="admBotTgToken" placeholder="123456789:AA...">
|
|
358
|
+
</div>
|
|
359
|
+
<div class="adm-form-row">
|
|
360
|
+
<label class="adm-form-label" for="admBotTgUsername">Имя Telegram-бота (авто)</label>
|
|
361
|
+
<input type="text" id="admBotTgUsername" placeholder="odant_work_bot">
|
|
362
|
+
</div>
|
|
363
|
+
<div class="adm-form-row">
|
|
364
|
+
<label class="adm-form-label" for="admBotMaxToken">Токен MAX Bot API</label>
|
|
365
|
+
<input type="text" id="admBotMaxToken" placeholder="f9LHod...">
|
|
366
|
+
</div>
|
|
367
|
+
<div class="adm-form-row">
|
|
368
|
+
<label class="adm-form-label" for="admBotMaxUsername">Имя бота MAX (авто)</label>
|
|
369
|
+
<input type="text" id="admBotMaxUsername" placeholder="id6234049193_bot">
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
<div style="display:flex;align-items:center;gap:10px;margin-top:18px;flex-wrap:wrap">
|
|
373
|
+
<button type="button" class="btn btn-primary" data-action="save-bots-settings">Сохранить ботов платформы</button>
|
|
374
|
+
<span class="small" id="admBotsFeedback"></span>
|
|
375
|
+
</div>
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
|
|
379
|
+
<!-- 8. РЕКВИЗИТЫ ОФЕРТЫ -->
|
|
380
|
+
<div data-adm-sec="legal" style="display:none">
|
|
381
|
+
<div class="sec-bar" style="margin-bottom:12px">
|
|
382
|
+
<h2 class="sec-title">Юридические реквизиты оферты (<code>/api/oferta</code>)</h2>
|
|
383
|
+
</div>
|
|
384
|
+
<div class="sec-box">
|
|
385
|
+
<div class="adm-form-grid">
|
|
386
|
+
<div class="adm-form-row">
|
|
387
|
+
<label class="adm-form-label" for="admLegalCompany">Оператор / Наименование</label>
|
|
388
|
+
<input type="text" id="admLegalCompany" placeholder="ООО «БИС» («Бизнес Интер Софт»)">
|
|
389
|
+
</div>
|
|
390
|
+
<div class="adm-form-row">
|
|
391
|
+
<label class="adm-form-label" for="admLegalAuthor">Автор ПО</label>
|
|
392
|
+
<input type="text" id="admLegalAuthor" placeholder="Перепелкин Роман Александрович">
|
|
393
|
+
</div>
|
|
394
|
+
<div class="adm-form-row">
|
|
395
|
+
<label class="adm-form-label" for="admLegalStatus">Правовой статус</label>
|
|
396
|
+
<input type="text" id="admLegalStatus" placeholder="Правообладатель и Оператор платформы · Проприетарное ПО (Все права защищены)">
|
|
397
|
+
</div>
|
|
398
|
+
<div class="adm-form-row">
|
|
399
|
+
<label class="adm-form-label" for="admLegalInn">ИНН</label>
|
|
400
|
+
<input type="text" id="admLegalInn" placeholder="6234049193">
|
|
401
|
+
</div>
|
|
402
|
+
<div class="adm-form-row">
|
|
403
|
+
<label class="adm-form-label" for="admLegalOgrn">ОГРН / ОГРНИП</label>
|
|
404
|
+
<input type="text" id="admLegalOgrn" placeholder="">
|
|
405
|
+
</div>
|
|
406
|
+
<div class="adm-form-row">
|
|
407
|
+
<label class="adm-form-label" for="admLegalEmail">Email поддержки</label>
|
|
408
|
+
<input type="email" id="admLegalEmail" placeholder="support@odant.org">
|
|
409
|
+
</div>
|
|
410
|
+
<div class="adm-form-row">
|
|
411
|
+
<label class="adm-form-label" for="admLegalPhone">Телефон</label>
|
|
412
|
+
<input type="text" id="admLegalPhone" placeholder="+7 (4912) 77-70-21">
|
|
413
|
+
</div>
|
|
414
|
+
<div class="adm-form-row">
|
|
415
|
+
<label class="adm-form-label" for="admLegalAddress">Адрес</label>
|
|
416
|
+
<input type="text" id="admLegalAddress" placeholder="390000, г. Рязань, ул. Ленина, 47">
|
|
417
|
+
</div>
|
|
418
|
+
</div>
|
|
419
|
+
<div style="display:flex;align-items:center;gap:10px;margin-top:18px;flex-wrap:wrap">
|
|
420
|
+
<button type="button" class="btn btn-primary" data-action="save-legal-settings">Сохранить реквизиты</button>
|
|
421
|
+
<span class="small" id="admLegalFeedback"></span>
|
|
422
|
+
</div>
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
284
425
|
</div>
|
|
285
426
|
</div>
|
|
286
427
|
</section>
|
|
@@ -295,23 +436,28 @@ export function renderAdminPage({ publicKey = '', assetVersion = '' } = {}) {
|
|
|
295
436
|
|
|
296
437
|
<!-- Модальное окно: Создание сервера / Выпуск лицензии клиенту -->
|
|
297
438
|
<div class="modal" id="admCreateServerModal" role="dialog" aria-modal="true">
|
|
298
|
-
<div class="card" style="max-width:
|
|
439
|
+
<div class="card" style="max-width:500px">
|
|
299
440
|
<div class="modal-head">
|
|
300
441
|
<img src="/assets/odant-logo.png" alt="">
|
|
301
442
|
<div>
|
|
302
|
-
<h3 class="h3" style="margin:0">Добавить сервер
|
|
443
|
+
<h3 class="h3" style="margin:0">Добавить сервер клиенту</h3>
|
|
303
444
|
<div class="small muted">Создание записи сервера в реестре с подписью Ed25519</div>
|
|
304
445
|
</div>
|
|
305
446
|
<button class="icon-btn" data-action="close-create-server-modal" aria-label="Закрыть">${icon('close')}</button>
|
|
306
447
|
</div>
|
|
307
|
-
<div class="field"
|
|
308
|
-
|
|
309
|
-
<
|
|
310
|
-
<div class="field"><label for="admNewSrvInn">ИНН</label><input type="text" id="admNewSrvInn" placeholder="7701234567"></div>
|
|
448
|
+
<div class="field">
|
|
449
|
+
<label for="admNewSrvEmail">Email клиента *</label>
|
|
450
|
+
<input type="email" id="admNewSrvEmail" placeholder="client@company.ru">
|
|
311
451
|
</div>
|
|
312
452
|
<div class="row2">
|
|
313
|
-
<div class="field"
|
|
314
|
-
|
|
453
|
+
<div class="field">
|
|
454
|
+
<label for="admNewSrvName">Название сервера (устройства)</label>
|
|
455
|
+
<input type="text" id="admNewSrvName" placeholder="Сервер WORK #1">
|
|
456
|
+
</div>
|
|
457
|
+
<div class="field">
|
|
458
|
+
<label for="admNewSrvHwid">HWID (необязательно)</label>
|
|
459
|
+
<input type="text" id="admNewSrvHwid" placeholder="PAK-...">
|
|
460
|
+
</div>
|
|
315
461
|
</div>
|
|
316
462
|
<label style="display:flex;align-items:center;gap:10px;font-size:13.5px;margin:8px 0 14px;cursor:pointer">
|
|
317
463
|
<input type="checkbox" id="admNewSrvActivateBase" checked style="width:17px;height:17px">
|