📊 Дашборд
Лиды сегодня: 12
В обработке: 5
Аккаунты: 4 / 4
Bitrix: n/a Auto: OFF Cache: none Ready: n/a
⚡ Live
🔔 Уведомления 3
Прочитать все
Новый лид из парсинга — @brand_spb
2 минуты назад
📨
Рассылка завершена — 340 отправлено, 18 ответов
14 минут назад
🎬
Видео опубликовано на VK и Telegram
1 час назад
📞
Звонок завершён — Казань, 4:20 мин
2 часа назад
🤝
Договор подписан — Екатеринбург, 2.5M ₽
Вчера 16:40
💰 ROI-калькулятор франшизы
Рассчитайте окупаемость, прибыль и срок возврата инвестиций
🎯
127
Лидов за месяц
↑ +23% к пред. месяцу
🤝
8
Договоров подписано
↑ +2 к пред. месяцу
📤
4 230
Сообщений отправлено
↑ за 30 дней
📞
342
Звонков совершено
↑ конверсия 14%
📱
18 600
Охват контента
↑ +41%
💰
2.4M ₽
Выручка франшиз
↑ +12% MoM
🗂 Источники лидов
Распределение по каналу привлечения (май)
127
лидов
Парсинг TG
57 45%
Рассылки
41 32%
Звонки
29 23%
Конверсия в сделку:
6.3% ↑ +0.8%
⚡ Live-события
Обновляется в реальном времени
Воронка продаж франшизы
Активные лиды по этапам
Новый лид 38
Квалификация 24
Презентация 15
Переговоры 9
Договор 8
Активность
Последние события
Новый лид из парсинга
@brand_spb — 2 мин назад
📨
Рассылка запущена
340 получателей — 14 мин
🎬
Видео опубликовано
ВКонтакте + TG — 1 ч назад
📞
Звонок завершён
Казань, 4:20 мин — 2 ч назад
🤝
Договор подписан
Екатеринбург — вчера

📈 Лиды по дням (май)

🟡 Парсинг 🔵 Рассылка 🟢 Звонки

🏭 Контент Завод

🧠
Генерация контента
AI пишет посты, сценарии, заголовки
🎬
Автомонтаж видео
Нарезка, субтитры, брендирование
📁
Перетащите видео или кликните
MP4, MOV до 2GB
🚀
Автопубликация
Расписание выхода по площадкам

📅 Контент-календарь

8 – 14 Май 2026

📋 Очередь публикаций

Тема Тип Площадка Время Статус Действие
Успех партнёра в Казани Видео Telegram + VK 09.05 10:00 ⏳ Ожидание
5 причин открыть ADONIS MERCH Пост Telegram 09.05 14:00 ⏳ Ожидание
Цифры за апрель Карусель VK + Instagram 10.05 12:00 🔄 Генерация
Реклама на Авито Франшизы Объявление Авито 08.05 09:00 ✅ Опубликовано
Короткое видео — отзыв партнёра Видео YouTube Shorts 07.05 18:00 ✅ Опубликовано

🎯 Воронка лидов

Всего: 0 Bitrix24: 0 Локальные: 0 Договор: 0 Bitrix sync: —

📋 Все лиды

Имя / Компания Источник Город Этап Сумма Обновлён

🔍 B2B Базы и дубли

⚙️ Парсинг в процессе...
Инициализация... 0%
🎯 Поиск каналов / групп
Ищем потенциальных покупателей франшизы
📊 Результаты последнего парсинга
Запущен: 08.05.2026 09:15
1 247
Найдено каналов
384
Подходящих
89
Контактов извлечено
23
Добавлено в CRM
⚡ Быстрые действия

📋 Найденные каналы

Канал / Группа Подписчики Тематика Активность Релевантность Действие
Выбрано: 0

📨 Омниканал рассылки

✉️ Новая кампания
Настройка рассылки по базе лидов
👁 Превью сообщения
П
ADONIS MERCH
сейчас
Привет! Вы когда-нибудь думали об открытии собственной студии брендирования? 🧵 ADONIS MERCH — сеть из 14 франшиз по всей России. Срок окупаемости от 11 месяцев, поддержка 24/7. Хотите узнать подробнее?
✓✓ 09:41
📡 Каналы доставки
Telegram WhatsApp Email Bitrix24 tasks
Сценарий: Telegram + WhatsApp на холодную базу, Email и Bitrix-задача на тёплые лиды.
Активные кампании
3 запущены
Запуск апрель — горячие
Активна
Отправлено: 240 / 340 · Ответов: 18 · Конв.: 7.5%
Холодная база — май
Пауза
Отправлено: 120 / 500 · Ответов: 7 · Конв.: 5.8%
👥
7
Участников команды
↑ Активны сейчас
🔑
3
Ролей доступа
Маркетолог · Звонарь · Аналитик
🔗
5
Подключённых платформ
Kilbil · 1С · Авито · Я.Директ · TG
📋
2
Ожидают приглашения
⏳ Отправить ссылку

👥 Участники команды

🔑 Роли и права доступа
Что видит каждая роль

🔗 Привязанные платформы

👤 TG Аккаунты

🤖 Аккаунты для рассылок
Управление аккаунтами и прокси
🌐 Настройки прокси
SOCKS5 / HTTP прокси для аккаунтов
Сохранённые прокси

Управление репутацией

4.7
Средний рейтинг
↑ Яндекс + 2ГИС
💬
347
Отзывов всего
↑ +23 за неделю
🔴
7
Без ответа
⚠ Требуют внимания
🤖
89%
Авто-ответов
↑ 194 из 218 ответов
🗺
Яндекс Бизнес
52 кабинета · Подключено
Активен
🟢
2ГИС
Подключено
Активен
🌐
Google Бизнес
Частичное покрытие
Частично

💬 Последние отзывы

🤖 Шаблоны авто-ответов

📡 Трафик & Источники лидов

🎯
127
Лидов за май
↑ +23% к апрелю
💰
1 840 ₽
CPL средний
↑ Оптимально
📊
6.3%
Конверсия в сделку
↑ +0.8% к норме
📱
234K
Охват за месяц
↑ Все каналы
🏷
Авито
34 лида · CPL 1 250 ₽
🔴
Яндекс.Директ
41 лид · CPL 2 100 ₽
✈️
Telegram Парсинг
28 лидов · CPL 890 ₽

💡 Рекомендуемые источники лидов

БИБОСС / Franshiza.ru
Теплые лиды с намерением купить
CPL: 3 000-8 000 ₽
SEO + авто-постинг
Дзен, vc.ru, TenChat
CPL: 200-800 ₽
Реферальная программа
Лиды от действующих партнеров
CPL: 0 ₽ (бонус)

🤖 Агент Авто-постинг

AI публикует контент 3 раза в неделю и отправляет сводку в Telegram.

📞 Звонилка

342
Звонков за месяц
14%
Конверсия в встречу
4:20
Ср. длительность
48
Перезвонить
12
Отказов сегодня
5
Сделок из звонков

📋 Очередь обзвона

⏳ 48 контактов
Контакт Город Источник Попытки Статус
Алексей К.
+7 912 xxx-12
Самара TG 0 Новый
Марина Д.
+7 985 xxx-44
Тула Рассылка 1 Перезвон
Дмитрий В.
+7 903 xxx-77
Ростов Входящий 2 Перезвон
Наталья С.
+7 926 xxx-90
Краснодар Звонок 1 В работе
📝 Скрипт звонка
Франшиза ADONIS MERCH — холодный

Открытие: «Добрый день! Меня зовут [имя], компания ADONIS MERCH. Вы рассматриваете открытие своего бизнеса?»

Квалификация: «Есть ли у вас опыт в торговле? Какой бюджет рассматриваете?»

Презентация: «Мы предлагаем готовую франшизу с окупаемостью от 11 месяцев, 350+ тыс/мес прибыли...»

Закрытие: «Можем провести презентацию онлайн на 20 минут. Когда удобно?»

📊 Итог звонка

⚙️ Настройки системы

🔐 Доступ и безопасность
Пользователи и пароли
📬 Интеграции
Подключённые сервисы
📱
Telegram API
4 аккаунта активно
✓ Подключён
🤖
OpenAI GPT-4o
Генерация контента
✓ Подключён
📞
Zvonok.online
IP-телефония
⚠ Настроить
🎬
HeyGen (авто-монтаж)
AI-видео
✗ Не подключён
🏢 Данные компании
Бренд и контакты сети
📥 Импорт реальных данных
CSV: city,owner,points,rev,rating | JSON: {franchises: [{city, owner, points}]}
🔔 Уведомления
Что и куда присылать
🏪
41
Баз в сети (1С)
✅ 2 актуальных · ⚠ 28 · 🔴 11
💰
145M ₽
Выручка сети / мес
↑ +12% к прошлому мес · Kilbil
🔄
3
Открытий в процессе
⏳ Новые переговоры
4.8
Средний рейтинг сети
↑ по Google & 2Gis
📦
758
Паушальный взнос (т.р.)
Срок окупаемости 11 мес
🌍
41
Городов присутствия
↑ вся Россия: Урал, Сибирь, Юг
🗺 Карта сети ADONIS MERCH
Кликните на точку — подробности о франшизе
🏆 Башкирия (17+ точек)
Уфа · Нефтекамск · Янаул · Дюртюли
Кумертау · Мелеуз · Мраково...
Сети 1,3,6,14,25,26,34,41-43,46-50,52 · ⭐ 4.8
Лен. область (4 точки)
Петергоф · Гатчина · Кингисепп · Кудрово
Сети 12, 13, 20 · ⭐ 4.7
Москва и МО (2 точки)
Ивантеевка · Щелково
Сети 9, 45 · ⭐ 4.9
Нижний Новгород
Сеть 30 · ул. Страж Революции 7/5
⭐ 4.6
Волгоград + юг (4 точки)
Михайловка · Новоаннинский · Ленинск · Волгоград
Сети 10, 16, 51 · ⭐ 4.6
Ростовская обл. (2 точки)
Белая Калитва · Шахты
Сеть 5 · ⭐ 4.7
Новороссийск
Сеть 23 · ул. Ленина, 47
⭐ 4.8
Нытва, Пермский кр.
Сеть 27 · ул. К. Либкнехта, 52
⭐ 4.5
Камбарка, Удмуртия
Сеть 21 · ул. Манохина, 40Б
⭐ 4.5
Татарстан (2 точки)
Заинск (Сеть 24) · Куюки (Сеть 37)
⭐ 4.7
Слободской, Кировская
Сеть 8 · ул. Советская, 66
⭐ 4.5
Сыктывкар
Сеть 18 · ул. Пушкина, 63
⭐ 4.5
Челябинская обл. (3 точки)
Юрюзань (Сеть 11) · Чебаркуль (28) · Верхнеуральск (29)
⭐ 4.6
Новомосковск
Сеть 47 · ул. Маяковского, 20В
⭐ 4.5
Приволжск, Ивановская
Сеть 39 · ул. Революционная, 87
⭐ 4.5
Ялуторовск
Сеть 33 · ул. Полевая, 73
⭐ 4.5
ХМАО-Югра (3 точки)
Сургут (Сеть 22) · Лянтор (36) · Ханты-Мансийск (40)
⭐ 4.7
Новосибирск
Сеть 35 · ул. Габова, 25
⭐ 4.8
Барнаул
Сеть 38 · пр. Строителей 18к1
⭐ 4.6
Борзя, Забайкалье
Сеть 31 · ул. Карла Маркса, 207а
⭐ 4.4
Чишмы
Сеть 2 · ул. Тополиная, 1/3
⭐ 4.6
Активна
Открытие
🏆 Топ точек по выручке
Май 2026
1
Москва
3.2M ₽
2
Санкт-Петербург
2.8M ₽
3
Краснодар
1.7M ₽
4
Екатеринбург
1.9M ₽
5
Новосибирск
1.4M ₽
6
Казань
1.5M ₽
7
Ростов-на-Дону
1.3M ₽

🏪 Все франшизы сети

Активных: 20 В открытии: 3 Пауза: 1
ГородФранчайзиС датыВыручка / месРейтинг1С версияСтатусДействие
📋 Онбординг франшизы
Чеклист запуска точки по этапам
0 из 0 задач выполнено
🔎 Esc
🩺 Здоровье интеграций
🚦 Готовность к запуску

💰 ROI-калькулятор ADONIS MERCH

Дата расчёта: ${now}

ПараметрЗначение
Город${cityOpt}
Площадь${area} м²
Инвестиции${fmtM(parseInt(invest))}
Выручка / мес${revenue}
Прибыль / мес${profit}
Окупаемость${payback}
Годовой ROI${roi}
`; const blob = new Blob([html], {type:'text/html'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'roi-adonis-' + now.replace(/\./g,'-') + '.html'; a.click(); showToast('📄','Отчёт сохранён','ROI-расчёт скачан как HTML-файл'); } function exportLeadsReport() { if (!ensureLeadsExportPreflight('HTML отчёт')) return; const rows = Array.isArray(filteredLeadsData) ? filteredLeadsData : unifiedLeadsData; const byStage = {}; const bySource = {}; rows.forEach(r => { byStage[r.stage] = (byStage[r.stage] || 0) + 1; bySource[r.source] = (bySource[r.source] || 0) + 1; }); const stageRows = Object.entries(byStage).map(([stage, cnt]) => `${stage}${cnt}`).join('') || '—0'; const sourceRows = Object.entries(bySource).map(([source, cnt]) => `${source}${cnt}`).join('') || '—0'; const mode = document.getElementById('leadsFunnelMode')?.selectedOptions?.[0]?.textContent || 'Общая воронка'; const source = document.getElementById('leadsSourceFilter')?.value || 'Все источники'; const stage = document.getElementById('leadsStageFilter')?.value || 'Все этапы'; const period = document.getElementById('leadsPeriodFilter')?.selectedOptions?.[0]?.textContent || 'За всё время'; const syncText = formatBitrixSyncMeta(bitrixSyncMeta); const syncEndpoint = bitrixSyncMeta.endpoint || '—'; const html = `Отчёт по воронке лидов

📄 Отчёт по воронке лидов

Режим: ${mode}Период: ${period}Источник: ${source}Этап: ${stage}Лидов: ${rows.length}
${syncText}Endpoint: ${syncEndpoint}

По этапам

${stageRows}
ЭтапКол-во

По источникам

${sourceRows}
ИсточникКол-во

Детализация

${rows.map(r => ``).join('')}
Имя / КомпанияИсточникГородЭтапСуммаОбновлён
${r.name}${r.source}${r.city}${r.stage}${r.budget}${r.date}
`; const blob = new Blob([html], {type:'text/html;charset=utf-8'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'leads-report-' + new Date().toISOString().slice(0,10) + '.html'; a.click(); showToast('📄','Отчёт готов','Сформирован отчёт по текущему срезу воронки'); } function exportLeadsReportCSV() { if (!ensureLeadsExportPreflight('CSV отчёт')) return; const rows = Array.isArray(filteredLeadsData) ? filteredLeadsData : unifiedLeadsData; const mode = document.getElementById('leadsFunnelMode')?.selectedOptions?.[0]?.textContent || 'Общая воронка'; const source = document.getElementById('leadsSourceFilter')?.value || 'Все источники'; const stage = document.getElementById('leadsStageFilter')?.value || 'Все этапы'; const period = document.getElementById('leadsPeriodFilter')?.selectedOptions?.[0]?.textContent || 'За всё время'; const syncText = formatBitrixSyncMeta(bitrixSyncMeta); const byStage = {}; const bySource = {}; rows.forEach(r => { byStage[r.stage] = (byStage[r.stage] || 0) + 1; bySource[r.source] = (bySource[r.source] || 0) + 1; }); const csvRows = [ ['СЕКЦИЯ','Параметр','Значение'], ['Фильтры','Режим',mode], ['Фильтры','Период',period], ['Фильтры','Источник',source], ['Фильтры','Этап',stage], ['Фильтры','Bitrix sync',syncText], ['Фильтры','Bitrix endpoint',bitrixSyncMeta.endpoint || '—'], ['Итог','Лидов',String(rows.length)], ['','',''], ['Сводка по этапам','Этап','Кол-во'], ...Object.entries(byStage).map(([k,v]) => ['Этап',k,String(v)]), ['','',''], ['Сводка по источникам','Источник','Кол-во'], ...Object.entries(bySource).map(([k,v]) => ['Источник',k,String(v)]), ['','',''], ['Детализация','Имя / Компания','Источник | Город | Этап | Сумма | Обновлён'], ...rows.map(r => ['Лид', r.name, `${r.source} | ${r.city} | ${r.stage} | ${r.budget} | ${r.date}`]), ]; const csv = csvRows.map(r => r.map(c => '"' + String(c).replace(/"/g,'""') + '"').join(',')).join('\n'); const blob = new Blob(['\uFEFF' + csv], {type:'text/csv;charset=utf-8'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'leads-report-' + new Date().toISOString().slice(0,10) + '.csv'; a.click(); showToast('📑','CSV отчёт готов','Сформирована сводка и детализация по текущему срезу'); } // ── LEADS CSV EXPORT ── function exportLeadsCSV() { if (!ensureLeadsExportPreflight('CSV лидов')) return; const rows = [['Имя','Источник','Город','Этап','Сумма','Обновлён']]; (Array.isArray(filteredLeadsData) ? filteredLeadsData : unifiedLeadsData).forEach(row => { rows.push([row.name, row.source, row.city, row.stage, row.budget, row.date]); }); const csv = rows.map(r => r.map(c => '"' + c.replace(/"/g,'""') + '"').join(',')).join('\n'); const blob = new Blob(['\uFEFF' + csv], {type:'text/csv;charset=utf-8'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'leads-adonis-' + new Date().toLocaleDateString('ru-RU').replace(/\./g,'-') + '.csv'; a.click(); showToast('📥','Экспорт завершён','Лиды сохранены в CSV-файл'); } function filterLeadsTable(q) { leadsSearchTerm = q || ''; applyLeadsFilters(); } // ── LEAFLET MAP INITIALIZATION FOR RUSSIA ── let leafletMap = null; function initLeafletMap() { // Only init once if (leafletMap) return; const container = document.getElementById('leafletMap'); if (!container) return; // Center on Russia (approximate center: ~60°N, 105°E) leafletMap = L.map('leafletMap').setView([60, 105], 3); // Use OpenStreetMap tiles with dark theme styling L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap', maxZoom: 13, minZoom: 2, className: 'osm-tiles' }).addTo(leafletMap); // Disable scrollZoom to prevent accidental zoom while clicking city dots leafletMap.scrollWheelZoom.disable(); // Disable dragging to keep the map focused leafletMap.dragging.disable(); // Re-enable zoom with Ctrl+scroll leafletMap.on('wheel', function(e) { if (e.originalEvent.ctrlKey) { e.originalEvent.preventDefault(); const zoomDelta = e.originalEvent.deltaY > 0 ? -1 : 1; leafletMap.setZoom(leafletMap.getZoom() + zoomDelta); } }); // Add custom CSS to darken the map const style = document.createElement('style'); style.textContent = ` #leafletMap .osm-tiles { filter: brightness(0.85) contrast(1.1) hue-rotate(15deg) saturate(0.8); } #leafletMap .leaflet-control-zoom { background: rgba(220,20,60,0.1) !important; } #leafletMap .leaflet-control-zoom-in, #leafletMap .leaflet-control-zoom-out { background: rgba(220,20,60,0.15) !important; color: var(--gold) !important; border: 1px solid rgba(220,20,60,0.2) !important; } #leafletMap .leaflet-control-attribution { background: rgba(220,20,60,0.08) !important; color: var(--text) !important; font-size: 10px !important; } `; document.head.appendChild(style); } // Extended keyboard shortcuts let gPressed = false, gTimer; document.addEventListener('keydown', e => { const tag = document.activeElement.tagName; if (tag === 'INPUT' || tag === 'TEXTAREA') return; if ((e.ctrlKey || e.metaKey) && e.key === '/') { e.preventDefault(); openShortcuts(); return; } if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'A') { e.preventDefault(); toggleAI(); return; } if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'T') { e.preventDefault(); toggleTheme(); return; } if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'N') { e.preventDefault(); toggleNotif(); return; } // G+key navigation if (e.key === 'g' || e.key === 'G') { gPressed = true; clearTimeout(gTimer); gTimer = setTimeout(() => { gPressed = false; }, 1200); return; } if (gPressed) { const map = { d:'dashboard', n:'network', l:'leads', p:'parsing', m:'messaging', c:'calls', a:'accounts', s:'settings' }; const k = e.key.toLowerCase(); if (map[k]) { e.preventDefault(); goTab(map[k]); gPressed = false; } } }); // ── DEFERRED INITS (after all declarations) ── renderParseTable(_parseResults); renderAccountsList(); renderProxyList(); // ── REPUTATION TAB ── const _reviewsData = [ { id:1, platform:'yandex', rating:5, author:'Дмитрий К.', city:'Уфа', text:'Отличное место! Всегда свежее мерч, хорошая атмосфера. Рекомендую!', date:'09.05.2026', answered:false }, { id:2, platform:'2gis', rating:5, author:'Ирина В.', city:'Нефтекамск', text:'Были вчера с семьёй — просто замечательно! Персонал приятный, всё чисто.', date:'08.05.2026', answered:true, reply:'Спасибо, Ирина! Ждём вас снова!' }, { id:3, platform:'yandex', rating:1, author:'Алексей С.', city:'Янаул', text:'Долго ждали, заказ перепутали. Разочарован.', date:'08.05.2026', answered:false }, { id:4, platform:'google', rating:4, author:'Михаил Н.', city:'Ивантеевка', text:'В целом хорошо. Жигулёвское — топ. Чуть дороговато, но качество.', date:'07.05.2026', answered:false }, { id:5, platform:'yandex', rating:2, author:'Ольга П.', city:'Сыктывкар', text:'Пришли в 18:00, а половины меню не было. Кассир нагрубил.', date:'07.05.2026', answered:false }, { id:6, platform:'2gis', rating:5, author:'Анна Т.', city:'Новосибирск', text:'Любим это место всей компанией. Всегда вкусно и весело!', date:'06.05.2026', answered:true, reply:'Анна, спасибо! Будем рады снова!' }, { id:7, platform:'yandex', rating:3, author:'Пётр Ж.', city:'Казань', text:'Средне. Мерч нормальное, но зал шумноват.', date:'06.05.2026', answered:false }, { id:8, platform:'yandex', rating:5, author:'Надежда К.', city:'Барнаул', text:'Просто восторг! Лучший брендинговый бар города, без вопросов.', date:'05.05.2026', answered:true, reply:'Надежда, это лучшее, что мы могли услышать! Ждём!' }, ]; const _autoReplyTemplates = [ { id:1, rating:'5', name:'5 звёзд — благодарность', text:'Большое спасибо за отзыв, {author}! Очень рады, что вам понравилось. Ждём вас снова! 🧵', active:true }, { id:2, rating:'4', name:'4 звезды — позитив', text:'Спасибо за оценку, {author}! Рады, что в целом всё понравилось. Ваш отзыв поможет нам стать лучше!', active:true }, { id:3, rating:'3', name:'3 звезды — нейтральный', text:'{author}, спасибо за честный отзыв. Мы принимаем к сведению и работаем над улучшением. Ждём снова!', active:true }, { id:4, rating:'1-2', name:'1-2 звезды — проблема', text:'Уважаемый(ая) {author}, нам очень жаль, что визит не оправдал ожиданий. Просим связаться с нами по телефону для решения вопроса.', active:true }, ]; function renderReviews() { const container = document.getElementById('reviewsList'); if (!container) return; const platform = document.getElementById('repFilterPlatform')?.value || 'all'; const status = document.getElementById('repFilterStatus')?.value || 'all'; let list = _reviewsData.filter(r => { if (platform !== 'all' && r.platform !== platform) return false; if (status === 'unanswered' && r.answered) return false; if (status === 'answered' && !r.answered) return false; return true; }); const platIcon = { yandex:'🗺', '2gis':'🟢', google:'🌐' }; const starColor = r => r >= 4 ? 'var(--green)' : r === 3 ? 'var(--gold)' : 'var(--red)'; container.innerHTML = list.map(r => `
${platIcon[r.platform]||'💬'}
${r.author} ${r.city} · ${r.date}
${'★'.repeat(r.rating)}${'☆'.repeat(5-r.rating)}
${r.answered ? '✓ Отвечено' : 'Без ответа'}

"${r.text}"

${r.answered && r.reply ? `
💬 Ответ: ${r.reply}
` : ''} ${!r.answered ? `
` : ''}
`).join(''); } function renderAutoReplyTemplates() { const container = document.getElementById('autoReplyTemplates'); if (!container) return; container.innerHTML = _autoReplyTemplates.map(t => `
${t.rating}★
${t.name}
${t.text.substring(0,60)}...
`).join(''); } function autoReplyReview(id) { const r = _reviewsData.find(x => x.id === id); if (!r) return; const tpl = _autoReplyTemplates.find(t => { if (t.rating === '5' && r.rating === 5) return true; if (t.rating === '4' && r.rating === 4) return true; if (t.rating === '3' && r.rating === 3) return true; if (t.rating === '1-2' && r.rating <= 2) return true; return false; }); if (!tpl) return; r.answered = true; r.reply = tpl.text.replace('{author}', r.author.split(' ')[0]); renderReviews(); const unanswered = _reviewsData.filter(x => !x.answered).length; const repBadge = Array.from(document.querySelectorAll('.nav-item')).find(b => (b.getAttribute('onclick') || '').includes("goTab('reputation')"))?.querySelector('.nav-badge'); if (repBadge) repBadge.textContent = unanswered; showToast('🤖','Авто-ответ','Ответ на отзыв отправлен!'); } function manualReplyReview(id) { showToast('✍️','Ответ','Открываем редактор ответа...'); } function syncReviews() { showToast('🔄','Синхронизация','Загружаем отзывы со всех площадок...'); } function openAutoReplySettings() { showToast('⚡','Авто-ответы','Настройки автоматических ответов...'); } function openPlatformReviews(p) { showToast('💬','Отзывы','Открываем ' + p + '...'); } function addAutoReplyTemplate() { showToast('➕','Шаблон','Добавление нового шаблона ответа...'); } function toggleAutoReplyTemplate(id, cb) { const t = _autoReplyTemplates.find(x=>x.id===id); if(t) t.active = cb.checked; } // ── TRAFFIC TAB ── function toggleTrafficChannel(ch, cb) { const el = document.getElementById('traffic' + ch.charAt(0).toUpperCase() + ch.slice(1)); if (el) el.style.opacity = cb.checked ? '1' : '0.4'; showToast(cb.checked ? '✅' : '⏸', 'Канал ' + ch, cb.checked ? 'Канал включён' : 'Канал приостановлен'); } function createAvitoAd() { showToast('🏷','Авито','Создаём новое объявление...'); } function startAutoPosting() { showToast('🤖','Авто-постинг','Запускаем публикацию статьи...'); } function toggleAutoPosting(cb) { document.getElementById('autoPostingStatus').textContent = cb.checked ? '🟢 Активен' : 'Выключен'; showToast(cb.checked ? '🤖' : '⏸', 'Авто-постинг', cb.checked ? 'Запущен' : 'Остановлен'); } // ── KILBIL BONUS SNAPSHOT (ready for 1C sync) ── const _kilbilSnapshot = { revenue: 2793977, checks: 4290, bonusAccrued: 98011, bonusUsed: 58903, clients: 171421, newClients: 1784, avgCheck: 531.69, period: '01.05-07.05', source: 'Kilbil' }; function fmtMoney(num) { return Number(num || 0).toLocaleString('ru-RU') + ' ₽'; } function render1cDatabases() { const el = document.getElementById('db1cList'); if (!el) return; const statusIcon = {ok:'✅',warn:'⚠️',old:'🔴'}; const statusColor = {ok:'var(--green)',warn:'var(--gold)',old:'var(--red)'}; el.innerHTML = _1cDatabases.map(d => `
${statusIcon[d.status]} ${d.city} ${d.version} Открыть ↗
`).join(''); } function renderKilbilEconomics() { const revWithBonus = _kilbilSnapshot.revenue; const bonusUsed = _kilbilSnapshot.bonusUsed; const revWithoutBonus = revWithBonus + bonusUsed; const bonusShare = revWithoutBonus ? (bonusUsed / revWithoutBonus) * 100 : 0; const burnRate = _kilbilSnapshot.bonusAccrued ? (_kilbilSnapshot.bonusUsed / _kilbilSnapshot.bonusAccrued) * 100 : 0; const withEl = document.getElementById('revWithBonus'); const withoutEl = document.getElementById('revWithoutBonus'); const spentEl = document.getElementById('bonusSpent'); const shareEl = document.getElementById('bonusShare'); const burnEl = document.getElementById('bonusBurnRate'); if (withEl) withEl.textContent = fmtMoney(revWithBonus); if (withoutEl) withoutEl.textContent = fmtMoney(revWithoutBonus); if (spentEl) spentEl.textContent = fmtMoney(bonusUsed); if (shareEl) shareEl.textContent = bonusShare.toFixed(2) + '%'; if (burnEl) burnEl.textContent = burnRate.toFixed(1) + '%'; } // ── 1C MOCK SNAPSHOT (управленческий учёт) ── const _1cSnapshot = { revenue: 2789450, checks: 4285, bonusAccrued: 98011, bonusUsed: 57920, clients: 171400, newClients: 1780, avgCheck: 531.40, period: '01.05-07.05', source: '1С Dinness' }; // ── РЕАЛЬНЫЕ БАЗЫ 1С (из файла «1с Партнеры.xlsx», 08.05.2026) ── const _1cDatabases = [ {city:'Благовещенск',db:'blagoveshchensk',url:'http://80.93.187.34/unf_blagoveshchensk',version:'3.0.12.214',status:'warn'}, {city:'Борзя',db:'borzya',url:'http://80.93.187.34/unf_borzya',version:'3.0.12.214',status:'warn'}, {city:'Буздяк',db:'buzdyak',url:'http://80.93.187.34/unf_buzdyak',version:'3.0.12.185',status:'old'}, {city:'Булгаково',db:'bulgakovo',url:'http://80.93.187.34/unf_bulgakovo',version:'3.0.12.214',status:'warn'}, {city:'Бураево',db:'buraevo',url:'http://80.93.187.34/unf_buraevo',version:'3.0.12.214',status:'warn'}, {city:'Верхнеуральск',db:'verhneuralsk',url:'http://80.93.187.34/unf_verhneuralsk',version:'3.0.12.214',status:'warn'}, {city:'Верхнеяркеево',db:'verhneyarkeevo',url:'http://80.93.187.34/unf_verhneyarkeevo',version:'3.0.12.226',status:'warn'}, {city:'Дюртюли',db:'durtuli',url:'http://80.93.187.34/unf_durtuli',version:'3.0.12.214',status:'warn'}, {city:'Заинск',db:'zainsk',url:'http://80.93.187.34/unf_zainsk',version:'3.0.12.226',status:'warn'}, {city:'Ивантеевка',db:'ivanteevka',url:'http://80.93.187.34/unf_ivanteevka',version:'3.0.11.119',status:'old'}, {city:'Калитва / Шахты',db:'kalitva',url:'http://80.93.187.34/unf_kalitva',version:'3.0.12.185',status:'old'}, {city:'Камбарка',db:'kambarka',url:'http://80.93.187.34/unf_kambarka',version:'3.0.11.169',status:'old'}, {city:'Караидель',db:'karaidel',url:'http://80.93.187.34/unf_karaidel',version:'3.0.12.214',status:'warn'}, {city:'Кармаскалы',db:'karmaskali',url:'http://80.93.187.34/unf_karmaskali',version:'3.0.12.185',status:'old'}, {city:'Киров (Слободской)',db:'kirov',url:'http://80.93.187.34/unf_kirov',version:'3.0.12.185',status:'old'}, {city:'Краснохолмский',db:'krasnoholmskiy',url:'http://80.93.187.34/unf_krasnoholmskiy',version:'3.0.12.214',status:'warn'}, {city:'Кумертау',db:'kumertau',url:'http://80.93.187.34/unf_kumertau/',version:'3.0.13.251',status:'warn'}, {city:'Куюки',db:'kuyuki',url:'http://80.93.187.34/unf_kuyuki',version:'3.0.12.214',status:'warn'}, {city:'Лянтор',db:'lyantor',url:'http://80.93.187.34/unf_lyantor',version:'3.0.12.214',status:'warn'}, {city:'Мелеуз',db:'meleus',url:'http://80.93.187.34/unf_meleus',version:'3.0.12.185',status:'old'}, {city:'Ниж. Новгород',db:'nn',url:'http://80.93.187.34/unf_nn',version:'3.0.12.214',status:'warn'}, {city:'Новоанненский/Михайловка',db:'novoanninsky',url:'http://80.93.187.34/unf_novoanninsky',version:'3.0.12.185',status:'old'}, {city:'Новомосковск',db:'novomoskovsk',url:'http://80.93.187.34/unf_novomoskovsk',version:'3.0.13.251',status:'warn'}, {city:'Новосибирск',db:'novosibirsk',url:'http://80.93.187.34/unf_novosibirsk',version:'3.0.12.214',status:'warn'}, {city:'Нытва',db:'nitva',url:'http://80.93.187.34/unf_nitva',version:'3.0.12.214',status:'warn'}, {city:'Петергоф',db:'peterhof',url:'http://80.93.187.34/unf_peterhof',version:'3.0.12.185',status:'old'}, {city:'Приволжск',db:'privolzhsk',url:'http://80.93.187.34/unf_privolzhsk',version:'3.0.12.214',status:'warn'}, {city:'Сибай',db:'sibai',url:'http://80.93.187.34/unf_sibai',version:'3.0.12.214',status:'warn'}, {city:'Собственная сеть',db:'pvm_rmk',url:'http://80.93.187.34/pvm_rmk',version:'3.0.13.300',status:'ok'}, {city:'Сургут',db:'surgut',url:'http://80.93.187.34/unf_surgut',version:'3.0.12.214',status:'warn'}, {city:'Сыктывкар',db:'siktivkar',url:'http://80.93.187.34/unf_siktivkar',version:'3.0.12.185',status:'old'}, {city:'Татышлы / Старобалтачево',db:'tatishli',url:'http://80.93.187.34/unf_tatishli',version:'3.0.12.185',status:'old'}, {city:'Толбазы',db:'tolbazi',url:'http://80.93.187.34/unf_tolbazi',version:'3.0.13.251',status:'warn'}, {city:'Ханты-Мансийск',db:'hm',url:'http://80.93.187.34/unf_hm',version:'3.0.12.214',status:'warn'}, {city:'Чебаркуль',db:'chebarkul',url:'http://80.93.187.34/unf_chebarkul',version:'3.0.12.214',status:'warn'}, {city:'Чишмы',db:'chishmi',url:'http://80.93.187.34/unf_chishmi',version:'3.0.13.300',status:'ok'}, {city:'Щелково',db:'shchelkovo',url:'http://80.93.187.34/unf_shchelkovo',version:'3.0.12.214',status:'warn'}, {city:'Ялуторовск (Тюмень)',db:'yalutorovsk',url:'http://80.93.187.34/unf_yalutorovsk',version:'3.0.12.226',status:'warn'}, {city:'Нагаево',db:'nagaevo',url:'http://80.93.187.34/unf_nagaevo',version:'3.0.13.251',status:'warn'}, {city:'Мраково',db:'mrakovo',url:'http://80.93.187.34/unf_mrakovo',version:'3.0.12.237',status:'warn'}, {city:'Волгоград',db:'volgograd',url:'http://80.93.187.34/unf_volgograd',version:'3.0.13.251',status:'warn'}, ]; // Row definitions for reconciliation const _reconcileFields = [ { key: 'revenue', label: 'Выручка', fmt: 'money', tolerance: 10000 }, { key: 'checks', label: 'Количество чеков', fmt: 'int', tolerance: 10 }, { key: 'bonusAccrued', label: 'Бонусов начислено', fmt: 'money', tolerance: 500 }, { key: 'bonusUsed', label: 'Бонусов списано', fmt: 'money', tolerance: 500 }, { key: 'clients', label: 'Уникальных клиентов',fmt: 'int', tolerance: 50 }, { key: 'newClients', label: 'Новых клиентов', fmt: 'int', tolerance: 20 }, { key: 'avgCheck', label: 'Средний чек', fmt: 'money2',tolerance: 5 } ]; const _apiContract = { version: '1.0', description: 'Контракт обмена данными Kilbil → 1С Dinness', endpoint: 'POST /api/1c/sync', auth: 'Bearer ', schedule: '0 * * * *', payload: { period: { type: 'string', example: '2026-05-01/2026-05-07' }, source: { type: 'string', value: 'kilbil' }, data: { ВыручкаРозница: { type: 'number', unit: 'RUB', source: 'revenue' }, КоличествоЧеков: { type: 'integer', source: 'checks' }, БонусыНачислено: { type: 'number', unit: 'RUB', source: 'bonusAccrued' }, БонусыСписано: { type: 'number', unit: 'RUB', source: 'bonusUsed' }, КлиентыУникальные: { type: 'integer', source: 'clients' }, НовыеКлиенты: { type: 'integer', source: 'newClients' }, СреднийЧек: { type: 'number', unit: 'RUB', source: 'avgCheck' } }, reconciliation: { tolerancePolicy: 'absolute', alertOnDiff: true, alertThreshold: 'field.tolerance' } }, response: { ok: true, imported: '', warnings: '', synced_at: '' } }; function _fmtField(val, fmt) { if (fmt === 'money') return Number(val).toLocaleString('ru-RU') + ' ₽'; if (fmt === 'money2') return Number(val).toLocaleString('ru-RU', {minimumFractionDigits:2, maximumFractionDigits:2}) + ' ₽'; if (fmt === 'int') return Number(val).toLocaleString('ru-RU'); return val; } function renderReconcile() { const tbody = document.getElementById('reconcileTbody'); if (!tbody) return; const kb = _kilbilSnapshot, c1 = _1cSnapshot; let rows = '', warns = 0; _reconcileFields.forEach(f => { const kv = kb[f.key] ?? 0, cv = c1[f.key] ?? 0; const diff = kv - cv; const absDiff = Math.abs(diff); const ok = absDiff <= f.tolerance; if (!ok) warns++; const diffStr = diff === 0 ? '—' : (diff > 0 ? '+' : '') + _fmtField(diff, f.fmt); const badge = ok ? '✓ Норма' : '⚠ Расхождение'; const diffColor = ok ? 'color:var(--text-muted)' : 'color:#ff7850;font-weight:600'; const fixBtn = ok ? '' : ``; rows += ` ${f.label} ${_fmtField(kv, f.fmt)} ${_fmtField(cv, f.fmt)} ${diffStr} ${badge} ${fixBtn} `; }); tbody.innerHTML = rows; // Update status badge const sb = document.getElementById('syncStatusBadge'); if (sb) { if (warns === 0) { sb.textContent = '🟢 Без расхождений'; sb.style.background = 'rgba(50,200,100,0.15)'; sb.style.color = '#32c864'; } else { sb.textContent = `🟡 ${warns} расхождени${warns === 1 ? 'е' : warns < 5 ? 'я' : 'й'}`; sb.style.background = 'rgba(220,20,60,0.15)'; sb.style.color = 'var(--gold)'; } } } function toggleNetworkAnalytics() { const body = document.getElementById('networkAnalyticsBody'); const chevron = document.getElementById('networkAnalyticsChevron'); const btn = document.getElementById('networkAnalyticsBtn'); if (!body) return; const open = body.style.display !== 'none'; body.style.display = open ? 'none' : 'block'; if (chevron) chevron.style.transform = open ? 'rotate(0deg)' : 'rotate(180deg)'; if (btn) btn.style.borderColor = open ? 'var(--border)' : 'rgba(220,20,60,0.4)'; if (!open) { try { renderKilbilEconomics(); renderReconcile(); render1cDatabases(); } catch(_) {} } } // ── TEAM & ROLES DATA ── const _roles = [ { id: 'owner', name: 'Собственник', color: '#dc143c', icon: '👑', perms: ['dashboard','network','reputation','content','leads','parsing','messaging','calls','traffic','team','accounts','settings'] }, { id: 'marketer', name: 'Маркетолог', color: '#60a5fa', icon: '📢', perms: ['dashboard','network','reputation','content','leads','parsing','messaging','traffic'] }, { id: 'caller', name: 'Звонарь', color: '#a78bfa', icon: '📞', perms: ['dashboard','leads','calls'] }, { id: 'analyst', name: 'Аналитик', color: '#34c464', icon: '📊', perms: ['dashboard','network','reputation','traffic'] }, ]; const _teamMembers = [ { id: 1, name: 'Гедэон Сотворцов', role: 'owner', login: 'gedeon', email: 'sotvorcov@gmail.com', active: true, avatar: '👑', lastSeen: 'Сейчас' }, { id: 2, name: 'Алексей Маркетов', role: 'marketer', login: 'alex.m', email: 'alex.m@adonis.ru', active: true, avatar: '📢', lastSeen: '5 мин назад' }, { id: 3, name: 'Ирина Звонова', role: 'caller', login: 'irina.z', email: 'irina.z@adonis.ru', active: true, avatar: '📞', lastSeen: '12 мин назад' }, { id: 4, name: 'Дмитрий Аналит', role: 'analyst', login: 'dima.a', email: 'dima.a@adonis.ru', active: false, avatar: '📊', lastSeen: '3 ч назад' }, { id: 5, name: 'Наталья Смолова', role: 'caller', login: 'natalia.s', email: '', active: false, avatar: '📞', lastSeen: 'Ожидает' }, ]; const _platforms = [ { id: 'kilbil', name: 'Kilbil', icon: '💳', color: '#dc143c', status: 'connected', login: 'sotvorcov@gmail.com', url: 'https://lk.kilbil.ru', note: 'ID 2637 · Тариф КОРП' }, { id: '1c', name: '1С Dinness', icon: '📦', color: '#60a5fa', status: 'ready', login: 'admin', url: 'https://dinness.ru', note: 'Схема готова, синхронизация' }, { id: 'avito', name: 'Авито', icon: '🏷', color: '#34c464', status: 'partial', login: '', url: 'https://www.avito.ru/profile', note: 'Добавьте аккаунт' }, { id: 'yandex', name: 'Яндекс.Директ',icon: '🎯', color: '#ff7c5c', status: 'partial', login: '', url: 'https://direct.yandex.ru', note: 'Добавьте аккаунт' }, { id: 'tg', name: 'Telegram', icon: '✈️', color: '#34b7f1', status: 'connected', login: '+7 (xxx) xxx-xx-xx', url: '', note: '3 аккаунта активны' }, ]; const _tabLabels = { dashboard:'Дашборд', network:'Сеть', reputation:'Репутация', content:'Контент', leads:'Лиды', parsing:'Парсинг', messaging:'Рассылки', calls:'Звонилка', traffic:'Трафик', team:'Команда', accounts:'Аккаунты', settings:'Настройки' }; function renderTeamTab() { renderTeamMembers(); renderRolesPanel(); renderPlatforms(); } function renderTeamMembers() { const el = document.getElementById('teamMembersList'); if (!el) return; el.innerHTML = _teamMembers.map(m => { const role = _roles.find(r => r.id === m.role) || _roles[0]; return `
${m.avatar}
${m.name}
@${m.login} ${m.email ? '· ' + m.email : ''}
${role.icon} ${role.name} ${m.lastSeen}
${m.role !== 'owner' ? `` : ''}
`; }).join(''); } function renderRolesPanel() { const el = document.getElementById('rolesPanel'); if (!el) return; el.innerHTML = _roles.map(role => `
${role.icon} ${role.name} ${_teamMembers.filter(m=>m.role===role.id).length} чел.
${role.perms.map(p => `${_tabLabels[p]||p}`).join('')}
`).join(''); } function renderPlatforms() { const el = document.getElementById('platformsList'); if (!el) return; const statusLabel = { connected: ['🟢','Подключено','rgba(34,197,94,0.15)','var(--green)'], ready: ['🟡','Готово','rgba(220,20,60,0.15)','var(--gold)'], partial: ['⚪','Не настроено','var(--surface2)','var(--muted)'] }; el.innerHTML = _platforms.map(p => { const [icon, label, bg, col] = statusLabel[p.status] || statusLabel.partial; return `
${p.icon}
${p.name}
${p.note}
${icon} ${label}
${p.login ? `
Логин: ${p.login}
` : ''}
${p.status !== 'connected' ? `` : ``} ${p.url ? `Открыть ↗` : ''}
`; }).join(''); } function openAddTeamMember() { const name = prompt('Имя сотрудника:'); if (!name) return; const role = prompt('Роль (owner/marketer/caller/analyst):', 'marketer') || 'marketer'; const email = prompt('Email (необязательно):') || ''; const login = name.toLowerCase().replace(/\s+/g, '.').replace(/[^a-z.]/g, ''); const newMember = { id: Date.now(), name, role, login, email, active: false, avatar: _roles.find(r=>r.id===role)?.icon || '👤', lastSeen: 'Приглашение отправлено' }; _teamMembers.push(newMember); renderTeamMembers(); showToast('✅', 'Команда', `Добавлен: ${name} (${role})`); } function editTeamMember(id) { const m = _teamMembers.find(x => x.id === id); if (!m) return; const role = prompt(`Роль для ${m.name}:`, m.role); if (!role) return; if (!_roles.find(r => r.id === role)) { showToast('⚠', 'Ошибка', 'Роль не найдена: ' + role); return; } m.role = role; renderTeamMembers(); renderRolesPanel(); showToast('✅', 'Команда', `Роль обновлена: ${m.name} → ${role}`); } function removeTeamMember(id) { const idx = _teamMembers.findIndex(x => x.id === id); if (idx < 0) return; if (!confirm('Удалить сотрудника?')) return; const name = _teamMembers[idx].name; _teamMembers.splice(idx, 1); renderTeamMembers(); renderRolesPanel(); showToast('🗑', 'Команда', `Удалён: ${name}`); } function openAddPlatform() { showToast('🔗', 'Платформы', 'Мастер подключения в разработке — скоро!'); } function connectPlatform(id) { const p = _platforms.find(x => x.id === id); if (!p) return; const login = prompt(`Логин для ${p.name}:`); if (!login) return; p.login = login; p.status = 'connected'; renderPlatforms(); showToast('🔗', 'Подключение', `${p.name} подключена как ${login}`); } function reconnectPlatform(id) { const p = _platforms.find(x => x.id === id); if (!p) return; const login = prompt(`Обновить логин для ${p.name}:`, p.login); if (login !== null) { p.login = login; renderPlatforms(); showToast('⚙', 'Настройки', `${p.name} обновлена`); } } function runKilbilSync() { showToast('⟳', 'Синхронизация', 'Загружаем данные из Kilbil...'); const sb = document.getElementById('syncStatusBadge'); if (sb) { sb.textContent = '⟳ Синхронизация...'; sb.style.color = 'var(--text-muted)'; } setTimeout(() => { const now = new Date().toLocaleString('ru-RU', {day:'2-digit',month:'2-digit',year:'numeric',hour:'2-digit',minute:'2-digit'}).replace(',',''); const el = document.getElementById('lastSyncTime'); if (el) el.textContent = now; renderReconcile(); showToast('✅', 'Синхронизация', 'Данные обновлены. 3 расхождения обнаружено.'); }, 1800); } function downloadReconcileAct() { // Build CSV and trigger download let csv = 'Поле,Kilbil,1С Dinness,Расхождение,Статус\n'; _reconcileFields.forEach(f => { const kv = _kilbilSnapshot[f.key] ?? 0, cv = _1cSnapshot[f.key] ?? 0; const diff = kv - cv; const ok = Math.abs(diff) <= f.tolerance ? 'Норма' : 'Расхождение'; csv += `"${f.label}","${kv}","${cv}","${diff}","${ok}"\n`; }); const blob = new Blob(['\uFEFF' + csv], {type:'text/csv;charset=utf-8'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `sverka_kilbil_1c_${new Date().toISOString().slice(0,10)}.csv`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showToast('📄', 'Акт сверки', 'CSV скачан'); } function toggleApiContract() { const block = document.getElementById('apiContractBlock'); if (!block) return; const visible = block.style.display !== 'none'; block.style.display = visible ? 'none' : 'block'; if (!visible) { const pre = document.getElementById('apiContractPre'); if (pre) pre.textContent = JSON.stringify(_apiContract, null, 2); } } function reconcileField(key) { const labels = { revenue:'Выручка', checks:'Чеки', bonusUsed:'Бонусы списано' }; showToast('🔍', 'Разбор расхождения', `Открываем детализацию по полю: ${labels[key] || key}`); } // Export functions to global scope for inline onclick handlers. // Some sections can end up block-scoped after iterative edits, this keeps UI controls stable. [ 'goTab','toggleNotif','markAllRead','toggleTheme','toggleSidebar','doLogout','openCmd','runCmd','showToast', 'openROI','closeROI','openReport','closeReport','printReport','exportReportCSV','openCompare','closeCompare', 'openBriefing','closeBriefing','exportBriefingPDF','startTour','tourNext','tourPrev','closeTour', 'showFranchise','closeFModal','saveSettingsSecurity','saveSettingsCompany','checkProxy','saveProxy', 'openAddAccount','closeAddAccount','openEditAccount','saveAccount','toggleAccount','deleteProxy', 'runParsing','stopParsing','showParseHistory','bulkAddToCRM','bulkSendMsg','addAllToCRM','addChannelToCRM', 'launchCampaign','schedulePublication','generateContent','copyGeneratedContent','addGeneratedToQueue', 'openCStats','closeCStats','cstatsAction','exportCStatsCSV','openCall','closeCall','callToggleMute', 'callToggleHold','callGoStep','scriptPrev','scriptNext','callSetTag','callOutcome','openOnboarding', 'closeOnboarding','onbSelectCity','onbToggle','onbMarkAll','toggleAI','aiQuickMsg','sendAI', 'syncReviews','openAutoReplySettings','openPlatformReviews','addAutoReplyTemplate','autoReplyReview', 'manualReplyReview','toggleTrafficChannel','createAvitoAd','startAutoPosting','toggleAutoPosting', 'runKilbilSync','downloadReconcileAct','toggleApiContract','reconcileField','renderReconcile','render1cDatabases', 'renderNetworkTable','filterNetworkTable', 'toggleNetworkAnalytics','renderTeamTab','openAddTeamMember','editTeamMember','removeTeamMember', 'openAddPlatform','connectPlatform','reconnectPlatform','openIntegrationHealthModal', 'closeIntegrationHealthModal','clearIntegrationHealthHistory','runIntegrationDiagnostics', 'openServiceReadinessModal','closeServiceReadinessModal','runServiceReadinessChecks', 'clearServiceReadinessHistory','setLeadsBitrixPipeline','onBitrixCardDragStart', 'allowBitrixColumnDrop','handleBitrixCardDrop' ].forEach(fn => { try { if (typeof window[fn] === 'function') return; const maybe = eval(fn); if (typeof maybe === 'function') window[fn] = maybe; } catch (_) {} }); // Init all dynamic tabs setTimeout(() => { renderReviews(); renderAutoReplyTemplates(); renderKilbilEconomics(); renderReconcile(); render1cDatabases(); renderNetworkTable(); }, 500);
🤖
ADONIS MERCH AI
● Онлайн — готов помочь
🤖
Привет! Я ваш AI-ассистент ADONIS AI. Могу помочь с аналитикой, рассылками, лидами и настройками системы.

Что вас интересует?
📊 Статистика лидов
📨 Запустить рассылку
🏪 Франшизы
💰 Лучший город
👤
📊 Сравнение городов
Ключевые показатели по всем точкам сети
ГородВыручка / месПрибыль / месРейтингС открытияТочекТренд
➕ Добавить аккаунт
Подключите Telegram аккаунт для рассылок

ADONIS MERCH — Сводный отчёт

🏙 Результаты по городам
#ГородВладелецВыручка/месПрибыльРейтингСтатусВыручка (бар)
Активна
📈 Ответы по дням
Отправлено Ответов Конверсий
💬 Типичные ответы
С добрым утром, владелец! ☕
Вот что важно на сегодня по сети ADONIS MERCH
💰
Выручка вчера
🔥
Новых лидов
📞
Звонков
Ср. рейтинг сети
🏆 Топ-5 городов по выручке
✅ Задачи на сегодня
🔥 Горячие лиды
⚠️ Требуют внимания
Звонок активен
00:00
📝 Скрипт звонка
Заметки по звонку
Температура лида
🔥 Горячий 🌡 Тёплый ❄️ Холодный
Результат звонка
💰 ROI-калькулятор
Прогноз окупаемости вашей франшизы ADONIS MERCH
Выручка / мес
Чистая прибыль / мес
Окупаемость
Годовой ROI
Возврат инвестиций0%
* Расчёт является прогнозным. Реальные показатели зависят от локации, операционных расходов и сезонности. Средние данные основаны на показателях действующих партнёров сети.
Шаг 1 из 6
⌨️ Горячие клавиши
Навигация
Командная палитра
CtrlK
Горячие клавиши
Ctrl/
AI-ассистент
CtrlShiftA
Закрыть / Отменить
Esc
Вкладки
Дашборд
GD
Сеть франшиз
GN
Воронка лидов
GL
Парсинг
GP
Рассылки
GM
Звонилка
GC
Интерфейс
Переключить тему
CtrlShiftT
Уведомления
CtrlShiftN