diff --git a/mockup.html b/mockup.html
index 0b43d08..d2140ba 100644
--- a/mockup.html
+++ b/mockup.html
@@ -79,7 +79,67 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei
.plan .pd{font-size:13px;color:var(--mut);margin-top:4px}
.field{margin:14px 0}.field label{font-size:12px;font-weight:600;display:block;margin-bottom:5px}
.field input{width:100%;border:1.5px solid var(--line);border-radius:10px;padding:11px 13px;font-size:14px;font-family:inherit}
-.pdn{font-size:11px;color:var(--mut);margin:10px 0 16px}.pdn a{color:var(--bg)}
+.pdn{font-size:11px;color:var(--mut);margin:10px 0 16px}
+/* ── PAY HYBRID ── */
+.pay-bal{background:linear-gradient(135deg,#4f46e5 0%,#7c3aed 100%);color:#fff;border-radius:14px;padding:14px 18px;display:flex;align-items:center;gap:12px;margin-bottom:20px}
+.pay-bal-ico{font-size:22px;flex-shrink:0}
+.pay-bal-body{flex:1}
+.pay-bal-lbl{font-size:11px;opacity:.75;font-weight:600;text-transform:uppercase;letter-spacing:.05em}
+.pay-bal-val{font-size:20px;font-weight:800;line-height:1.1}
+.pay-bal-sub{font-size:11px;opacity:.75;margin-top:2px}
+.pay-bal-use{background:rgba(255,255,255,.2);border:1.5px solid rgba(255,255,255,.35);color:#fff;border-radius:8px;padding:7px 14px;font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap;flex-shrink:0}
+.pay-bal-use:hover{background:rgba(255,255,255,.3)}
+.pay-tabs{display:flex;gap:8px;margin-bottom:20px}
+.pay-tab{flex:1;padding:10px;border:2px solid #e5e7eb;border-radius:12px;text-align:center;cursor:pointer;font-size:13px;font-weight:700;color:#6b7280;background:#fff;transition:all .15s}
+.pay-tab.on{border-color:var(--bg);color:var(--bg);background:#fef2f2}
+.pay-pane{display:none}
+.pay-pane.on{display:block}
+.pkg-grid{display:flex;flex-direction:column;gap:10px;margin-bottom:16px}
+.pkg-card{border:2px solid #e5e7eb;border-radius:14px;padding:14px 16px;cursor:pointer;transition:all .15s;position:relative}
+.pkg-card:hover{border-color:#d1d5db}
+.pkg-card.sel{border-color:var(--bg);background:#fff5f5}
+.pkg-card.rec::before{content:"Выгоднее всего";position:absolute;top:-1px;right:14px;background:var(--bg);color:#fff;font-size:10px;font-weight:700;padding:2px 8px;border-radius:0 0 6px 6px}
+.pkg-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:3px}
+.pkg-name{font-size:14px;font-weight:700;color:var(--ink)}
+.pkg-price{font-size:18px;font-weight:800;color:var(--bg)}
+.pkg-desc{font-size:12px;color:var(--mut)}
+.pkg-per{font-size:11px;color:#9ca3af;margin-top:2px}
+.sub-grid{display:flex;flex-direction:column;gap:10px;margin-bottom:16px}
+.sub-card{border:2px solid #e5e7eb;border-radius:14px;padding:14px 16px;cursor:pointer;transition:all .15s;position:relative}
+.sub-card:hover{border-color:#d1d5db}
+.sub-card.sel{border-color:var(--bg);background:#fff5f5}
+.sub-card.rec::before{content:"Популярно";position:absolute;top:-1px;right:14px;background:var(--bg);color:#fff;font-size:10px;font-weight:700;padding:2px 8px;border-radius:0 0 6px 6px}
+.sub-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:3px}
+.sub-name{font-size:14px;font-weight:700;color:var(--ink)}
+.sub-price{font-size:18px;font-weight:800;color:var(--bg)}
+.sub-period{font-size:11px;color:#9ca3af;margin-left:3px}
+.sub-desc{font-size:12px;color:var(--mut)}
+.sub-feat{font-size:11px;color:#6b7280;margin-top:6px;display:flex;flex-wrap:wrap;gap:4px}
+.sub-feat span{background:#f3f4f6;padding:2px 7px;border-radius:6px}
+.pay-refund-note{font-size:11px;color:var(--mut);text-align:center;margin-bottom:12px}
+.pay-refund-note a{color:var(--bg);text-decoration:none}
+/* ЮKassa modal */
+.yk-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:1000;align-items:flex-end;justify-content:center}
+.yk-overlay.on{display:flex}
+.yk-modal{background:#fff;border-radius:20px 20px 0 0;padding:24px;width:100%;max-width:480px;animation:slideUp .25s ease}
+@keyframes slideUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
+.yk-hdr{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px}
+.yk-ttl{font-size:16px;font-weight:800;color:var(--ink)}
+.yk-close{font-size:20px;cursor:pointer;color:#9ca3af;background:none;border:none;padding:4px}
+.yk-amount{font-size:28px;font-weight:800;color:var(--bg);text-align:center;margin-bottom:20px}
+.yk-methods{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:18px}
+.yk-method{border:2px solid #e5e7eb;border-radius:12px;padding:12px;cursor:pointer;text-align:center;transition:all .15s}
+.yk-method:hover,.yk-method.sel{border-color:var(--bg);background:#fff5f5}
+.yk-method-ico{font-size:22px;margin-bottom:4px}
+.yk-method-lbl{font-size:11px;font-weight:700;color:var(--ink)}
+.yk-sbp{background:linear-gradient(135deg,#00b27a,#00913c);color:#fff;border:none!important}
+.yk-sbp .yk-method-lbl{color:#fff}
+.yk-card-form{margin-bottom:16px}
+.yk-card-form input{width:100%;border:1.5px solid #e5e7eb;border-radius:10px;padding:10px 12px;font-size:14px;box-sizing:border-box;margin-bottom:8px}
+.yk-card-row{display:grid;grid-template-columns:1fr 1fr;gap:8px}
+.yk-pay-btn{width:100%;background:var(--bg);color:#fff;border:none;border-radius:12px;padding:14px;font-size:15px;font-weight:700;cursor:pointer}
+.yk-pay-btn:hover{background:var(--bghv)}
+.yk-secure{font-size:10px;color:#9ca3af;text-align:center;margin-top:8px}.pdn a{color:var(--bg)}
/* ── кабинет (общий каркас) ── */
.app{display:flex;min-height:100vh;background:#f4f5f7}
@@ -250,6 +310,66 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei
.dl-empty-ico{font-size:40px;margin-bottom:12px}
.dl-empty-txt{font-size:14px;font-weight:600;margin-bottom:6px;color:var(--ink)}
.dl-empty-sub{font-size:12px}
+/* ── ADMIN SCREEN ── */
+.admin-wrap{padding:24px 20px;max-width:900px;margin:0 auto}
+.admin-kpi{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:24px}
+@media(max-width:600px){.admin-kpi{grid-template-columns:1fr 1fr}}
+.akpi{background:#fff;border:1.5px solid #e5e7eb;border-radius:14px;padding:14px 16px}
+.akpi-num{font-size:24px;font-weight:800;line-height:1;margin-bottom:4px}
+.akpi-lbl{font-size:11px;color:var(--mut);font-weight:600}
+.akpi-trend{font-size:11px;margin-top:3px}
+.akpi-trend.up{color:#16a34a}
+.akpi-trend.dn{color:#dc2626}
+.admin-section{margin-bottom:24px}
+.admin-section-hdr{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}
+.admin-section-ttl{font-size:15px;font-weight:800;color:var(--ink)}
+.admin-section-link{font-size:12px;color:var(--bg);cursor:pointer;font-weight:600}
+.pay-table{width:100%;border-collapse:collapse;background:#fff;border-radius:12px;overflow:hidden;border:1.5px solid #e5e7eb}
+.pay-table th{background:#f9fafb;font-size:11px;font-weight:700;color:var(--mut);text-transform:uppercase;padding:8px 12px;text-align:left}
+.pay-table td{padding:10px 12px;font-size:13px;border-top:1px solid #f3f4f6;color:var(--ink)}
+.pay-table tr:hover td{background:#fafafa}
+.pay-badge{font-size:10px;font-weight:700;padding:2px 7px;border-radius:6px}
+.pay-badge.paid{background:#dcfce7;color:#166534}
+.pay-badge.ref{background:#fee2e2;color:#991b1b}
+.pay-badge.pend{background:#fef3c7;color:#92400e}
+.refund-card{background:#fff;border:1.5px solid #e5e7eb;border-radius:12px;padding:14px 16px;margin-bottom:8px;display:flex;gap:12px;align-items:flex-start}
+.refund-card.urgent{border-left:3px solid #ef4444}
+.refund-body{flex:1}
+.refund-ttl{font-size:13px;font-weight:700;color:var(--ink);margin-bottom:3px}
+.refund-meta{font-size:11px;color:var(--mut)}
+.refund-amt{font-size:14px;font-weight:800;color:#ef4444;flex-shrink:0;text-align:right}
+.refund-actions{display:flex;gap:6px;margin-top:8px}
+.refund-btn{font-size:11px;font-weight:700;padding:5px 10px;border-radius:7px;border:1.5px solid;cursor:pointer}
+.refund-btn.approve{border-color:#16a34a;color:#16a34a;background:#f0fdf4}
+.refund-btn.decline{border-color:#dc2626;color:#dc2626;background:#fef2f2}
+.admin-chart{background:#fff;border:1.5px solid #e5e7eb;border-radius:14px;padding:16px;margin-bottom:24px}
+.chart-bars{display:flex;align-items:flex-end;gap:3px;height:80px;margin-top:8px}
+.chart-bar{flex:1;border-radius:4px 4px 0 0;min-height:4px;transition:height .3s}
+.chart-bar.cur{background:var(--bg)}
+.chart-bar:not(.cur){background:#fecaca}
+.chart-lbl{display:flex;gap:3px;margin-top:4px}
+.chart-lbl span{flex:1;font-size:9px;color:var(--mut);text-align:center;overflow:hidden}
+/* Balance tab */
+.bal-hero{background:linear-gradient(135deg,#4f46e5,#7c3aed);border-radius:16px;padding:20px;color:#fff;margin-bottom:20px;text-align:center}
+.bal-hero-num{font-size:48px;font-weight:800;line-height:1}
+.bal-hero-lbl{font-size:13px;opacity:.8;margin-top:4px}
+.bal-hero-sub{font-size:12px;opacity:.65;margin-top:6px}
+.bal-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:20px}
+.bal-action-btn{padding:12px;border:2px solid #e5e7eb;border-radius:12px;text-align:center;cursor:pointer;font-size:13px;font-weight:700;color:var(--ink);background:#fff;transition:all .15s}
+.bal-action-btn:hover{border-color:var(--bg);color:var(--bg)}
+.pay-hist-item{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid #f3f4f6}
+.phi-left{}
+.phi-desc{font-size:13px;font-weight:600;color:var(--ink)}
+.phi-date{font-size:11px;color:var(--mut);margin-top:2px}
+.phi-right{text-align:right;flex-shrink:0}
+.phi-amt{font-size:14px;font-weight:700}
+.phi-amt.cr{color:#16a34a}
+.phi-amt.db{color:#ef4444}
+.phi-status{font-size:10px;color:var(--mut);margin-top:2px}
+.ref-form{background:#fff5f5;border:1.5px solid #fecaca;border-radius:12px;padding:14px;margin-top:16px}
+.ref-form h4{font-size:13px;font-weight:700;color:var(--ink);margin-bottom:10px}
+.ref-form textarea{width:100%;border:1.5px solid #e5e7eb;border-radius:8px;padding:8px;font-size:13px;box-sizing:border-box;height:70px;resize:none;margin-bottom:8px}
+.ref-form-hint{font-size:11px;color:var(--mut);margin-bottom:10px}
.dl-summary{display:flex;gap:12px;margin-bottom:20px;flex-wrap:wrap}
.dl-sum-card{background:#fff;border:1.5px solid #e5e7eb;border-radius:12px;padding:12px 16px;flex:1;min-width:100px;text-align:center}
.dl-sum-num{font-size:22px;font-weight:800;line-height:1}
@@ -1182,21 +1302,69 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei
-
-
-
1 490 ₽
-
Без комментариев
-
Все спорные пункты — готовый список изменений без пояснений
+
+
+
💳
+
+
Ваш баланс
+
0 кредитов
+
Пополните баланс ниже или оплатите разово
+
+
-
-
2 480 ₽
-
С комментариями
-
Все 12 пунктов + пояснение зачем каждое изменение. Контрагент понимает логику — меньше споров.
+
+
+
+
Разовая покупка
+
Подписка 💛
-
-
от 3 900 ₽
-
Партнёрская редакция
-
Чистый договор, учитывающий интересы обеих сторон. Контрагент подпишет без лишних раундов переговоров + Елена сопровождает до подписания.
+
+
+
+
+
+
Одна проверка249 ₽
+
1 кредит — только для этого договора
+
249 ₽ за кредит
+
+
+
Пакет Старт · 3 проверки490 ₽
+
3 кредита — первый сразу на этот договор
+
163 ₽ за кредит · экономия 34%
+
+
+
Пакет Бизнес · 10 проверок1 290 ₽
+
10 кредитов — хватит на несколько месяцев
+
129 ₽ за кредит · экономия 48%
+
+
+
Пакет Корпоратив · 30 проверок2 990 ₽
+
30 кредитов — для команды или активных сделок
+
100 ₽ за кредит · экономия 60%
+
+
+
+
+
+
+
+
+
Старт990 ₽/мес
+
До 10 проверок в месяц
+
Проверка рисковСписок изменений
+
+
+
Бизнес1 990 ₽/мес
+
До 30 проверок + комментарии Елены
+
Всё из СтартаОбоснование измененийСроки из договоров
+
+
+
Безлимит4 900 ₽/мес
+
Без ограничений · партнёрские редакции
+
Всё из БизнесПартнёрская редакцияПриоритетная поддержка
+
+
+
Отмена подписки — в любой момент. Неиспользованный остаток возвращается пропорционально.
Условия возврата →
@@ -1209,9 +1377,9 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei
-
+
Нажимая «Оплатить», вы соглашаетесь с
офертой и
обработкой ПДн. Данные договора остаются на вашем устройстве.
-
+
@@ -1303,7 +1471,9 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei
⏱️ Сроки
📋 Шаблоны
✍️ Составить документ
+ 💳 Баланс и оплата
↩ Выйти (в начало)
+ ⚙️ Администратор
Среда
28 мая 2025
@@ -1935,6 +2105,38 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei
+
+
+
+
+
Кабинет
Баланс и оплата
+
+
+
0
+
кредитов на балансе
+
Подписка не активна
+
+
+
+
➕ Пополнить баланс
+
↩ Запросить возврат
+
+
+
+
+
+
+
@@ -2360,7 +2562,8 @@ function toast(msg){
el.classList.add('show'); clearTimeout(_toastT);
_toastT=setTimeout(()=>el.classList.remove('show'),2600);
}
-function go(id){document.querySelectorAll('.screen').forEach(s=>s.classList.toggle('on',s.id===id));window.scrollTo(0,0);}
+function go(id){document.querySelectorAll('.screen').forEach(s=>s.classList.toggle('on',s.id===id));
+ if(id==='admin' && typeof _initAdmin==='function') setTimeout(_initAdmin,50);;window.scrollTo(0,0);}
/* ── СВОЙ ЗАПРОС ── */
let _customOpen = false;
let _voiceRec = null;
@@ -3081,6 +3284,279 @@ window.addEventListener('DOMContentLoaded', function() {
if (document.getElementById('dl-list')) renderDeadlines();
});
+/* ── PAY HYBRID ── */
+var _payMode = 'once'; // once | sub
+var _selPkg = 2; // selected package id
+var _selSub = 2; // selected sub id
+var _selPkgPrice = 490;
+var _selSubPrice = 1990;
+var _ykMethod = 'sbp';
+
+var _PKG_PRICES = {1:249, 2:490, 3:1290, 4:2990};
+var _PKG_CREDITS = {1:1, 2:3, 3:10, 4:30};
+var _SUB_PRICES = {1:990, 2:1990, 3:4900};
+
+function payTab(mode) {
+ _payMode = mode;
+ document.getElementById('ptab-once').classList.toggle('on', mode==='once');
+ document.getElementById('ptab-sub').classList.toggle('on', mode==='sub');
+ document.getElementById('ppane-once').classList.toggle('on', mode==='once');
+ document.getElementById('ppane-sub').classList.toggle('on', mode==='sub');
+ _updatePayBtn();
+}
+
+function selectPkg(id, price) {
+ _selPkg = id; _selPkgPrice = price;
+ document.querySelectorAll('.pkg-card').forEach(function(c){ c.classList.remove('sel'); });
+ var el = document.getElementById('pkg-'+id);
+ if (el) el.classList.add('sel');
+ _updatePayBtn();
+}
+
+function selectSub(id, price) {
+ _selSub = id; _selSubPrice = price;
+ document.querySelectorAll('.sub-card').forEach(function(c){ c.classList.remove('sel'); });
+ var el = document.getElementById('sub-'+id);
+ if (el) el.classList.add('sel');
+ _updatePayBtn();
+}
+
+function _updatePayBtn() {
+ var price = _payMode === 'once' ? _selPkgPrice : _selSubPrice;
+ var suffix = _payMode === 'sub' ? '/мес' : '';
+ var btn = document.getElementById('pay-price-btn');
+ if (btn) btn.textContent = 'Оплатить ' + price.toLocaleString('ru') + ' ₽' + suffix;
+ var ykBtn = document.getElementById('yk-pay-btn');
+ var ykAmt = document.getElementById('yk-amount');
+ if (ykBtn) ykBtn.textContent = 'Оплатить ' + price.toLocaleString('ru') + ' ₽' + suffix;
+ if (ykAmt) ykAmt.textContent = price.toLocaleString('ru') + ' ₽';
+ var ykTtl = document.getElementById('yk-ttl');
+ if (ykTtl) ykTtl.textContent = _payMode === 'sub' ? 'Подписка · первый платёж' : 'Пополнение баланса';
+}
+
+function _refreshBalance() {
+ var bal = parseInt(localStorage.getItem('zashita_credits') || '0');
+ var el = document.getElementById('pay-bal-credits');
+ var sub = document.getElementById('pay-bal-sub');
+ var btn = document.getElementById('pay-bal-use-btn');
+ if (el) el.textContent = bal;
+ if (bal > 0) {
+ if (sub) sub.textContent = 'Спишем 1 кредит на эту проверку';
+ if (btn) btn.style.display = '';
+ } else {
+ if (sub) sub.textContent = 'Пополните баланс ниже или оплатите разово';
+ if (btn) btn.style.display = 'none';
+ }
+}
+
+function useBalance() {
+ var bal = parseInt(localStorage.getItem('zashita_credits') || '0');
+ if (bal <= 0) return;
+ localStorage.setItem('zashita_credits', bal - 1);
+ // record usage
+ var hist = JSON.parse(localStorage.getItem('zashita_pay_history') || '[]');
+ hist.unshift({date: new Date().toISOString(), type: 'use', amount: 0, desc: 'Использован 1 кредит'});
+ localStorage.setItem('zashita_pay_history', JSON.stringify(hist));
+ toast('✅ 1 кредит использован — запускаю полный анализ');
+ setTimeout(function(){ go('cabinet'); tab('cases'); }, 1200);
+}
+
+// ЮKassa modal
+function ykOpen() {
+ _updatePayBtn();
+ document.getElementById('yk-overlay').classList.add('on');
+}
+function ykClose(e) {
+ if (!e || e.target === document.getElementById('yk-overlay')) {
+ document.getElementById('yk-overlay').classList.remove('on');
+ }
+}
+function ykMethod(m, el) {
+ _ykMethod = m;
+ document.querySelectorAll('.yk-method').forEach(function(x){ x.classList.remove('sel'); });
+ if (el) el.classList.add('sel');
+ document.getElementById('yk-card-form').style.display = (m === 'card') ? '' : 'none';
+}
+function fmtCard(inp) {
+ var v = inp.value.replace(/\D/g,'').substring(0,16);
+ inp.value = v.replace(/(\d{4})(?=\d)/g,'$1 ');
+}
+function ykPay() {
+ var price = _payMode === 'once' ? _selPkgPrice : _selSubPrice;
+ var credits = _payMode === 'once' ? _PKG_CREDITS[_selPkg] : 999;
+ // Mock: зачислить кредиты
+ if (_payMode === 'once') {
+ var cur = parseInt(localStorage.getItem('zashita_credits') || '0');
+ localStorage.setItem('zashita_credits', cur + credits);
+ } else {
+ localStorage.setItem('zashita_sub_plan', _selSub);
+ localStorage.setItem('zashita_sub_since', new Date().toISOString());
+ }
+ // Save to payment history
+ var hist = JSON.parse(localStorage.getItem('zashita_pay_history') || '[]');
+ hist.unshift({
+ date: new Date().toISOString(),
+ type: _payMode,
+ amount: price,
+ credits: _payMode === 'once' ? credits : null,
+ method: _ykMethod,
+ status: 'paid',
+ desc: _payMode === 'once' ? 'Пополнение баланса +' + credits + ' кредитов' : 'Подписка · ' + ['','Старт','Бизнес','Безлимит'][_selSub]
+ });
+ localStorage.setItem('zashita_pay_history', JSON.stringify(hist));
+ // Save last order for hero screen
+ localStorage.setItem('zashita_last_order', JSON.stringify({
+ ttl: 'Баланс пополнен', plan: _payMode === 'once' ? credits + ' кредитов' : 'Подписка',
+ price: price.toLocaleString('ru') + ' ₽'
+ }));
+ ykClose();
+ toast('✅ Оплата прошла — кредиты зачислены!');
+ _refreshBalance();
+ setTimeout(function(){ go('cabinet'); }, 1500);
+}
+
+window.addEventListener('DOMContentLoaded', function(){
+ // default: select pkg-2
+ selectPkg(2, 490);
+ _refreshBalance();
+});
+
+/* ── ADMIN + BALANCE ── */
+
+// ── Admin dashboard ──
+var _ADM_PAYS = [
+ {date:'28.05.2026',client:'Р.В.',type:'Пакет Бизнес',amount:1290,status:'paid'},
+ {date:'28.05.2026',client:'М.С.',type:'Подписка Бизнес',amount:1990,status:'paid'},
+ {date:'27.05.2026',client:'А.П.',type:'Разовая',amount:249,status:'paid'},
+ {date:'27.05.2026',client:'О.К.',type:'Пакет Старт',amount:490,status:'paid'},
+ {date:'26.05.2026',client:'В.Н.',type:'Подписка Старт',amount:990,status:'paid'},
+ {date:'25.05.2026',client:'Т.Ю.',type:'Пакет Бизнес',amount:1290,status:'ref'},
+];
+
+var _ADM_REFUNDS = [
+ {id:1,client:'Т.Ю.',date:'25.05.2026',amount:1290,credits:7,
+ reason:'Не понравился формат отчёта',urgent:true},
+ {id:2,client:'С.В.',date:'22.05.2026',amount:490,credits:2,
+ reason:'Дублирующая покупка',urgent:false},
+];
+
+function _initAdmin() {
+ // Chart
+ var vals = [28,32,18,45,22,38,29,52,41,34,47,56,39,44,31,58,42,37,49,53,36,41,55,62,48,44,57,59,43,47];
+ var max = Math.max.apply(null, vals);
+ var bars = document.getElementById('adm-chart');
+ var lbls = document.getElementById('adm-chart-lbl');
+ if (!bars) return;
+ bars.innerHTML = vals.map(function(v, i){
+ var h = Math.round((v/max)*100);
+ return '';
+ }).join('');
+ if (lbls) {
+ var days = [];
+ for (var i=vals.length;i>0;i--) {
+ if (i===vals.length||i===vals.length-7||i===vals.length-14||i===vals.length-21||i===1) {
+ days.push(i+'д');
+ } else { days.push(''); }
+ }
+ lbls.innerHTML = days.map(function(d){ return ''+d+''; }).join('');
+ }
+ // Payments table
+ var tbody = document.getElementById('adm-pay-table');
+ if (tbody) {
+ tbody.innerHTML = _ADM_PAYS.map(function(p){
+ var badge = p.status==='paid'?'Оплачено':
+ p.status==='ref'?'Возврат':
+ 'Ожидание';
+ return '| '+p.date+' | '+p.client+' | '+p.type+' | '+p.amount.toLocaleString('ru')+'₽ | '+badge+' |
';
+ }).join('');
+ }
+ // Refunds
+ var rlist = document.getElementById('adm-refunds-list');
+ if (rlist) {
+ if (_ADM_REFUNDS.length === 0) {
+ rlist.innerHTML = '✅ Активных заявок нет
';
+ } else {
+ rlist.innerHTML = _ADM_REFUNDS.map(function(r){
+ return ''
+ +'
'
+ +'
'+r.client+' · '+r.date+'
'
+ +'
'+r.reason+'
'
+ +'
Неиспользованных кредитов: '+r.credits+'
'
+ +'
'
+ +''
+ +''
+ +'
'
+ +'
'+r.amount.toLocaleString('ru')+'₽
'
+ +'
';
+ }).join('');
+ }
+ }
+}
+
+function admRefund(id, approve) {
+ var card = document.getElementById('rcard-'+id);
+ if (card) card.style.opacity = '.4';
+ toast(approve ? '✅ Возврат одобрен — отправлен в ЮKassa' : '✕ Заявка отклонена — клиент уведомлён');
+ setTimeout(function(){ if(card) card.remove(); }, 800);
+}
+
+// ── Balance tab ──
+function _refreshBalanceTab() {
+ var credits = parseInt(localStorage.getItem('zashita_credits') || '0');
+ var subPlan = localStorage.getItem('zashita_sub_plan');
+ var el = document.getElementById('bal-credits-num');
+ var sub = document.getElementById('bal-sub-status');
+ if (el) el.textContent = credits;
+ if (sub) {
+ var subNames = {1:'Старт', 2:'Бизнес', 3:'Безлимит'};
+ sub.textContent = subPlan ? ('Подписка ' + (subNames[subPlan]||'') + ' активна 💛') : 'Подписка не активна';
+ }
+ // History
+ var hist = JSON.parse(localStorage.getItem('zashita_pay_history') || '[]');
+ var hel = document.getElementById('bal-history');
+ if (hel) {
+ if (!hist.length) {
+ hel.innerHTML = 'Платежей пока нет
';
+ } else {
+ hel.innerHTML = hist.slice(0,10).map(function(h){
+ var d = new Date(h.date);
+ var ds = d.getDate()+'.'+(d.getMonth()+1)+'.'+d.getFullYear();
+ var isCredit = h.type === 'use';
+ return ''
+ +'
'
+ +'
'
+ +(isCredit?'−1 кредит':'+'+(h.credits||'∞')+' кредитов')+'
'
+ +(h.amount?'
'+h.amount.toLocaleString('ru')+'₽
':'')
+ +'
';
+ }).join('');
+ }
+ }
+}
+
+function toggleRefundForm() {
+ var f = document.getElementById('ref-form');
+ if (f) f.style.display = f.style.display === 'none' ? '' : 'none';
+}
+
+function submitRefund() {
+ var reason = (document.getElementById('ref-reason')||{}).value || '';
+ var credits = parseInt(localStorage.getItem('zashita_credits') || '0');
+ if (credits <= 0) { toast('⚠ Неиспользованных кредитов нет'); return; }
+ // Save refund request
+ var refs = JSON.parse(localStorage.getItem('zashita_refund_requests') || '[]');
+ refs.push({date: new Date().toISOString(), credits: credits, reason: reason, status: 'pending'});
+ localStorage.setItem('zashita_refund_requests', JSON.stringify(refs));
+ toggleRefundForm();
+ toast('✅ Заявка отправлена — ответим в течение 10 рабочих дней');
+}
+
+// Hook into tab switch
+var _origTab = typeof tab === 'function' ? tab : null;
+window.addEventListener('DOMContentLoaded', function(){
+ _initAdmin();
+ _refreshBalanceTab();
+});
+
/* ── ГОЛОСОВОЙ ВВОД ── */
var _voiceActive = false;
var _voiceRecog = null;
@@ -3587,7 +4063,8 @@ window.addEventListener('DOMContentLoaded', handleHash);
window.addEventListener('hashchange', handleHash);
function tab(name){
document.querySelectorAll('.tabpane').forEach(p=>p.classList.toggle('on',p.id==='p-'+name));
- if(name==='sroki' && typeof renderDeadlines==='function') renderDeadlines();;
+ if(name==='sroki' && typeof renderDeadlines==='function') renderDeadlines();
+ if(name==='balance' && typeof _refreshBalanceTab==='function') _refreshBalanceTab();;
document.querySelectorAll('.side a').forEach(a=>a.classList.remove('on'));
const map={cases:'t-cases',case:'t-case',sroki:'t-sroki',shab:'t-shab',create:'t-create'};
const el=document.getElementById(map[name]); if(el) el.classList.add('on');
@@ -3646,4 +4123,109 @@ function tab(name){
+
+
+
+
+
+
490 ₽
+
+
+
+
🔒 Защищено ЮKassa · 3D Secure · чек на email
+
+
+
+
+
+
+

+
Кабинет администратора
+
← выйти
+
+
+
Администратор
+
Дашборд
+
+
+
+
+
47 300 ₽
+
Выручка за месяц
+
↑ +18% к прошлому
+
+
+
134
+
Клиентов всего
+
↑ +12 новых
+
+
+
28
+
Активных подписок
+
↑ +3 этой неделе
+
+
+
2
+
Заявки на возврат
+
⚠ Требуют решения
+
+
+
+
+
+
+
Выручка — последние 30 дней
+
По неделям
+
+
+
+
+
+
+
+
+
Последние платежи
+
Все платежи →
+
+
+ | Дата | Клиент | Тип | Сумма | Статус |
+
+
+
+
+
+
+
+