import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const out=path.dirname(fileURLToPath(import.meta.url)); const C={bg:'#F5EFDF',paper:'#FFF9ED',ink:'#26342C',muted:'#77776E',line:'#DCCFB8',green:'#2E684A',green2:'#DDE9DA',gold:'#A8752F',red:'#A94C3F',dark:'#20352A'}; const e=s=>String(s).replace(/&/g,'&').replace(/`${e(s)}`; const rect=(x,y,w,h,fill=C.paper,rx=12,stroke=C.line)=>``; const pill=(x,y,w,s,fill=C.green2,color=C.green)=>`${rect(x,y,w,28,fill,14,null)}${text(x+w/2,y+19,s,11,color,700,'middle')}`; const nav=['Главная','Аналитика','Маркетинг','Коммуникации','CRM','Продажи','Склад','Закупки','Финансы','Сотрудники','Проекты','Задачи']; function shell(title,sub,body,action='+ Новая сделка'){ const n=nav.map((s,i)=>`${rect(0,-25,196,39,s==='CRM'?'#486B55':'transparent',9,null)}${text(30,0,s,12,'#F8F1E2',s==='CRM'?700:400)}`).join(''); return `${text(28,42,'♛ KRONA',25,'#E8C47A',700)}${text(29,62,'БИЗНЕС-ПЛАТФОРМА',9,'#DCC58F',700)}${n}${text(28,970,'Владелец бизнеса',11,'#F8F1E2',700)}${text(28,990,'Горский 1/1',9,'#9CB0A3')}${rect(250,15,228,40,'#F5EEDC',10,C.line)}${text(268,40,'Ресторан: Зал + Доставка⌄',12)}${rect(800,15,366,40,'#FCF8EF',10,C.line)}${text(824,40,'⌕ Поиск по платформе…',12,'#89877E')}${text(1446,40,'Виктор ⌄',12,C.ink,700,'end')}${text(258,116,title,30,C.ink,700)}${text(258,143,sub,12,C.muted)}${rect(1320,96,184,42,C.green,10,null)}${text(1412,122,action,12,'#FFF9EC',700,'middle')}${body}`; } function pipeline(){ const stages=[['Новые','7','840 000 ₽'],['Квалификация','5','1 120 000 ₽'],['Предложение','4','920 000 ₽'],['Переговоры','3','1 480 000 ₽'],['Согласование','2','610 000 ₽']]; const cards=[['Поставка упаковки','ООО «Ресурс»','180 000 ₽','Сегодня, 15:00'],['Корпоративное меню','БЦ «Север»','240 000 ₽','Нет задачи'],['Сеть кофеен «Маяк»','Анна Белова','450 000 ₽','Звонок · 16:30'],['Банкеты на октябрь','Отель «Гранд»','680 000 ₽','Завтра'],['Линия бизнес-ланчей','IT Park','520 000 ₽','Просрочено']]; let s=`${rect(0,0,1260,58,'#FCF8EF',12,C.line)}${text(20,35,'Воронка B2B продаж⌄',13,C.ink,700)}${pill(208,15,108,'Канбан')}${pill(324,15,82,'Список','#F3EBDD',C.muted)}${text(480,35,'⌕ Поиск сделок, контактов и компаний',12,C.muted)}${text(1218,35,'Фильтры 3 ···',12,C.ink,700,'end')}`; s+=`${rect(0,72,1260,56,'#EDF3EA',10,'#C8D8CA')}${text(18,96,'План сентября',11,C.muted)}${text(18,118,'6 400 000 ₽',18,C.green,700)}${text(210,96,'В работе',11,C.muted)}${text(210,118,'4 970 000 ₽',18,C.ink,700)}${text(420,96,'Прогноз',11,C.muted)}${text(420,118,'5 860 000 ₽ · 92%',18,C.gold,700)}`; stages.forEach((st,i)=>{const x=i*250;s+=`${rect(x,144,238,680,'#F9F4E8',12,C.line)}${text(x+14,172,st[0],13,C.ink,700)}${pill(x+184,153,38,st[1],'#E8DECB',C.ink)}${text(x+14,196,st[2],11,C.muted)}${rect(x+10,218,218,188,'#FFFDF6',10,C.line)}${text(x+24,248,cards[i][0],13,C.ink,700)}${text(x+24,274,cards[i][1],11,C.muted)}${text(x+24,308,cards[i][2],17,C.ink,700)}${pill(x+24,324,88,i===0?'40% шанс':'60% шанс')}${text(x+24,382,cards[i][3],10,i===4?C.red:C.gold,700)}${text(x+200,382,'●',12,i===4?C.red:C.green)}${rect(x+10,418,218,146,'#FFFDF6',10,C.line)}${text(x+24,450,i%2?'Поставка обедов':'Осенний кейтеринг',12,C.ink,700)}${text(x+24,475,i%2?'Новый клиент':'Повторная продажа',10,C.muted)}${text(x+24,512,i%2?'320 000 ₽':'260 000 ₽',15,C.ink,700)}${text(x+24,545,'+ Запланировать дело',10,C.green,700)}${text(x+119,804,'+ Быстро добавить',11,C.green,700,'middle')}`});return s; } function deal(){ let s=`${rect(0,0,1260,62,'#FCF8EF',12,C.line)}${text(18,25,'← Сделки / Поставка упаковки',11,C.muted)}${text(18,49,'Поставка упаковки',19,C.ink,700)}${pill(248,17,118,'Квалификация')}${text(1228,39,'♡ ···',18,C.gold,700,'end')}`; s+=`${rect(0,76,374,748,'#FCF8EF',12,C.line)}${text(20,110,'ДАННЫЕ СДЕЛКИ',11,C.muted,700)}${text(20,148,'180 000 ₽',26,C.ink,700)}${text(20,178,'Вероятность 40% · B2B',11,C.muted)}${text(20,224,'Клиент',10,C.muted,700)}${text(20,247,'ООО «Ресурс»',14,C.ink,700)}${text(20,269,'Иван Петров · Директор',11,C.muted)}${text(20,310,'Контакты',10,C.muted,700)}${text(20,336,'☎ +7 900 123-45-67',12,C.green)}${text(20,361,'✉ ivan@resurs.ru',12,C.green)}${text(20,401,'Ответственный',10,C.muted,700)}${text(20,426,'Александр Соколов',12,C.ink,700)}${text(20,470,'Следующее действие',10,C.muted,700)}${rect(16,484,342,70,'#F5E6D7',9,'#E6C5AB')}${text(30,509,'Звонок по условиям поставки',12,C.ink,700)}${text(30,534,'Сегодня, 15:00 · через 2 ч 14 мин',10,C.red,700)}${text(20,594,'Связанные объекты',10,C.muted,700)}${pill(20,608,96,'2 задачи')}${pill(124,608,92,'3 файла')}${pill(224,608,116,'1 предложение')}${text(20,684,'Пользовательские поля',10,C.muted,700)}${text(20,710,'Тип упаковки',11,C.muted)}${text(340,710,'ПЭТ',11,C.ink,700,'end')}${text(20,741,'Объём в месяц',11,C.muted)}${text(340,741,'12 000 шт',11,C.ink,700,'end')}${text(20,772,'Адрес доставки',11,C.muted)}${text(340,772,'Горский 1/1',11,C.ink,700,'end')}${text(187,807,'⚙ Настроить поля',11,C.green,700,'middle')}`; s+=`${rect(388,76,600,748,'#FCF8EF',12,C.line)}${text(408,108,'Активность',15,C.ink,700)}${pill(728,88,70,'Все')}${pill(806,88,82,'Сообщения','#F3EBDD',C.muted)}${pill(896,88,72,'Задачи','#F3EBDD',C.muted)}${rect(406,132,564,74,'#F7F1E5',10,C.line)}${text(424,159,'Написать сообщение, заметку или поставить задачу…',11,C.muted)}${text(424,190,'✉ ☎ ☑ 📎',16,C.gold)}${rect(426,236,520,88,'#EDF3EA',12,null)}${text(444,260,'Telegram · Иван Петров',10,C.green,700)}${text(444,284,'Интересует поставка по новому прайсу.',12,C.ink)}${text(444,306,'Сегодня, 12:17',9,C.muted)}${rect(490,344,456,76,'#F2E8D5',12,null)}${text(508,370,'Вы · Telegram',10,C.gold,700)}${text(508,394,'Отправил актуальные условия.',12,C.ink)}${text(426,452,'● Задача выполнена',11,C.green,700)}${text(448,478,'Подготовить предварительный расчёт',12,C.ink)}${text(448,498,'Сегодня, 11:40 · Александр Соколов',9,C.muted)}${text(426,542,'☎ Исходящий звонок · 04:18',11,C.ink,700)}${text(448,568,'Обсудили объём и сроки поставки',11,C.muted)}${text(426,622,'▤ Коммерческое предложение.pdf',11,C.ink,700)}${text(448,647,'2,4 МБ · отправлено клиенту',10,C.muted)}${text(426,704,'◉ Стадия изменена',11,C.gold,700)}${text(448,730,'Первичный контакт → Квалификация',11,C.muted)}${text(448,752,'Вчера, 17:12',9,C.muted)}`; s+=`${rect(1002,76,258,748,'#F8F3E7',12,C.line)}${text(1020,108,'Следующий шаг',13,C.ink,700)}${rect(1018,126,226,88,'#F5E6D7',9,'#E6C5AB')}${text(1032,151,'Связаться сегодня',11,C.red,700)}${text(1032,176,'Уточнить условия договора',11,C.ink)}${text(1032,198,'15:00',10,C.muted)}${text(1020,252,'KRONA AI',11,C.gold,700)}${text(1020,280,'Клиент настроен позитивно.',11,C.ink)}${text(1020,300,'Главный вопрос — срок',11,C.ink)}${text(1020,320,'первой поставки.',11,C.ink)}${rect(1018,344,226,38,C.green,9,null)}${text(1131,368,'Подготовить ответ',11,'#FFF',700,'middle')}${text(1020,426,'Документы',11,C.muted,700)}${text(1020,454,'Предложение · отправлено',10,C.ink)}${text(1020,480,'Договор · не создан',10,C.red)}${text(1020,524,'Оплата',11,C.muted,700)}${text(1020,552,'Счета отсутствуют',10,C.ink)}${text(1020,596,'Автоматизации этапа',11,C.muted,700)}${text(1020,624,'✓ Создать задачу через 1 день',10,C.green)}${text(1020,650,'✓ Напомнить при молчании',10,C.green)}`;return s; } function customer(){ let s=`${rect(0,0,1260,126,'#FCF8EF',14,C.line)}${text(56,70,'ИП',18,C.green,700,'middle')}${text(110,44,'Иван Петров',22,C.ink,700)}${text(110,70,'Директор · ООО «Ресурс»',12,C.muted)}${pill(110,84,82,'Клиент')}${pill(200,84,58,'VIP','#F5E4C2',C.gold)}${text(1220,52,'☎ Позвонить ✉ Написать ···',12,C.green,700,'end')}${text(1220,88,'Последняя активность сегодня, 12:41',10,C.muted,'400','end')}`; s+=`${rect(0,142,810,682,'#FCF8EF',12,C.line)}${text(18,177,'Хронология отношений',15,C.ink,700)}${pill(562,157,70,'Все')}${pill(640,157,70,'Сделки','#F3EBDD',C.muted)}${pill(718,157,72,'Диалоги','#F3EBDD',C.muted)}`; const ev=[['Сегодня, 12:41','Telegram','Подтвердил интерес к поставке упаковки'],['Сегодня, 11:40','Задача','Подготовлен предварительный расчёт'],['Вчера, 17:12','Сделка','Переведена на этап «Квалификация»'],['16 сентября','Email','Открыто коммерческое предложение'],['12 сентября','Звонок','Первичный разговор · 06:24']];ev.forEach((a,i)=>{let y=220+i*104;s+=`${text(66,y-4,a[1],11,i?C.gold:C.green,700)}${text(66,y+22,a[2],13,C.ink,700)}${text(66,y+46,a[0],10,C.muted)}`}); s+=`${rect(826,142,434,330,'#FCF8EF',12,C.line)}${text(846,177,'Показатели клиента',15,C.ink,700)}${text(846,224,'Сумма сделок',10,C.muted)}${text(1240,224,'1 420 000 ₽',17,C.ink,700,'end')}${text(846,267,'Оплачено',10,C.muted)}${text(1240,267,'860 000 ₽',14,C.green,700,'end')}${text(846,310,'Активные сделки',10,C.muted)}${text(1240,310,'3',14,C.ink,700,'end')}${text(846,353,'Средний цикл',10,C.muted)}${text(1240,353,'18 дней',14,C.ink,700,'end')}${text(846,396,'Последняя покупка',10,C.muted)}${text(1240,396,'12 августа',14,C.ink,700,'end')}${text(846,439,'Риск оттока',10,C.muted)}${pill(1136,420,104,'Низкий')}`; s+=`${rect(826,488,434,336,'#FCF8EF',12,C.line)}${text(846,523,'Связи',15,C.ink,700)}${text(846,558,'Компания',10,C.muted)}${text(846,582,'ООО «Ресурс»',12,C.green,700)}${text(846,620,'Контактные каналы',10,C.muted)}${text(846,646,'Telegram @ivan_petrov',11,C.ink)}${text(846,672,'WhatsApp +7 900 123-45-67',11,C.ink)}${text(846,698,'Email ivan@resurs.ru',11,C.ink)}${text(846,744,'Ответственный',10,C.muted)}${text(846,770,'Александр Соколов',12,C.ink,700)}${text(846,804,'+ Связать объект',11,C.green,700)}`;return s; } function analytics(){ let s=`${rect(0,0,1260,58,'#FCF8EF',12,C.line)}${text(20,35,'B2B продажи · Сентябрь 2026⌄',13,C.ink,700)}${text(1230,35,'Сравнить период · Экспорт',11,C.green,700,'end')}`; const k=[['Новые сделки','24','+18%'],['Выиграно','1,94 млн ₽','+12%'],['Конверсия','31%','+4,2 п.п.'],['Средний цикл','18 дней','−3 дня']];k.forEach((a,i)=>{let x=i*310;s+=`${text(x+10,104,a[0],10,C.muted)}${text(x+10,136,a[1],23,C.ink,700)}${text(x+10,158,a[2],10,C.green,700)}${i<3?``:''}`}); s+=`${rect(0,188,760,330,'#FCF8EF',12,C.line)}${text(20,222,'Динамика выручки и прогноза',14,C.ink,700)}${text(28,492,'1 сен',10,C.muted)}${text(710,492,'30 сен',10,C.muted,'400','end')}${text(590,224,'— факт – – прогноз',10,C.muted)}`; s+=`${rect(776,188,484,330,'#FCF8EF',12,C.line)}${text(796,222,'Причины потерь',14,C.ink,700)}`;[['Цена',38],['Срок поставки',24],['Конкурент',18],['Нет ответа',12]].forEach((a,i)=>{let y=266+i*56;s+=`${text(796,y,a[0],11,C.ink)}${text(1208,y,a[1]+'%',10,C.muted)}`}); s+=`${rect(0,534,1260,290,'#FCF8EF',12,C.line)}${text(20,568,'Эффективность этапов',14,C.ink,700)}`;[['Новый → Квалификация','72%','1,8 дня'],['Квалификация → Предложение','61%','3,4 дня'],['Предложение → Переговоры','48%','5,2 дня'],['Переговоры → Согласование','66%','4,1 дня'],['Согласование → Выиграна','74%','3,5 дня']].forEach((a,i)=>{let y=614+i*39;s+=`${text(24,y,a[0],11,C.ink)}${text(910,y,a[1],11,C.green,700)}${text(1218,y,a[2],11,C.muted,400,'end')}`});return s; } function automation(){ let s=`${rect(0,0,1260,64,'#FCF8EF',12,C.line)}${text(20,28,'Воронка B2B продаж',13,C.ink,700)}${text(20,50,'Роботы выполняются сверху вниз при входе сделки на этап',10,C.muted)}${text(1228,38,'Проверить журнал · ⚙',11,C.green,700,'end')}`; const cols=[['Новая сделка',['Создать задачу менеджеру','Проверить дубликаты','Отправить приветствие']],['Квалификация',['Через 1 день: напомнить','Если молчит 3 дня: задача','AI: оценить вероятность']],['Предложение',['Создать предложение','Отправить клиенту','Уведомить при открытии']],['Согласование',['Создать проект договора','Задача юристу','Контроль оплаты']]];cols.forEach((c,i)=>{let x=i*310;s+=`${rect(x,82,294,742,'#F9F4E8',12,C.line)}${text(x+16,112,c[0],13,C.ink,700)}${pill(x+235,94,42,String(c[1].length))}`;c[1].forEach((a,j)=>{let y=144+j*128;s+=`${rect(x+14,y,266,108,'#FFFDF6',10,C.line)}${text(x+30,y+30,a,11,C.ink,700)}${text(x+30,y+55,j===2?'Условие: всегда':'Сразу после входа',9,C.muted)}${pill(x+30,y+68,78,'Активен')}${text(x+250,y+88,'⋮',16,C.gold,700)}`});s+=`${rect(x+14,548,266,42,'#EDF3EA',9,'#C8D8CA')}${text(x+147,574,'+ Добавить действие',11,C.green,700,'middle')}${text(x+147,792,'Перетащите действие сюда',10,C.muted,400,'middle')}`});return s; } function settings(){ let s=`${rect(0,0,254,824,'#FCF8EF',12,C.line)}${text(20,38,'Настройки CRM',15,C.ink,700)}`;['Воронки и этапы','Поля карточек','Карточка канбана','Источники лидов','Права доступа','Дубликаты','Импорт и экспорт'].forEach((a,i)=>{let y=74+i*52;s+=`${rect(10,y-27,234,40,i===0?'#E6ECDD':'transparent',8,null)}${text(24,y,a,11,i===0?C.green:C.ink,i===0?700:400)}`}); s+=`${rect(270,0,990,824,'#FCF8EF',12,C.line)}${text(294,40,'Воронки и этапы',19,C.ink,700)}${text(294,64,'Настройте путь сделки, обязательные поля и автоматизации',11,C.muted)}${rect(294,88,944,54,'#F7F1E5',9,C.line)}${text(312,121,'B2B продажи⌄',12,C.ink,700)}${text(1216,121,'+ Новая воронка',11,C.green,700,'end')}`; const stages=['Первичный контакт','Квалификация','Предложение','Переговоры','Согласование','Выиграна','Проиграна'];stages.forEach((a,i)=>{let y=170+i*76;s+=`${rect(294,y,944,58,'#FFFDF6',9,C.line)}${text(338,y+25,a,12,C.ink,700)}${text(338,y+44,i===0?'Начальный этап':i>4?'Финальный этап':'Обязательных полей: '+(i+1),9,C.muted)}${text(1160,y+34,'Автоматизации '+(i+1)+' ⋮',10,C.green,700,'end')}`});s+=`${rect(294,716,944,82,'#EDF3EA',10,'#C8D8CA')}${text(316,748,'+ Добавить этап',12,C.green,700)}${text(316,775,'Этапы можно перетаскивать. Изменения применятся ко всем сделкам.',10,C.muted)}`;return s; } const screens=[ ['70-crm-v2-pipeline.svg','CRM · Воронка продаж','Сделки, задачи и прогноз в одном рабочем поле',pipeline(),'+ Новая сделка'], ['71-crm-v2-deal.svg','CRM · Сделка','Данные, коммуникации и следующее действие',deal(),'Сохранено'], ['72-crm-v2-customer.svg','CRM · Клиент 360°','Полная история отношений и связанные объекты',customer(),'+ Новая сделка'], ['73-crm-v2-analytics.svg','CRM · Аналитика','Конверсия, скорость прохождения этапов и прогноз',analytics(),'Скачать отчёт'], ['74-crm-v2-automation.svg','CRM · Автоматизация','Действия и условия для каждого этапа воронки',automation(),'+ Новый робот'], ['75-crm-v2-settings.svg','CRM · Настройки','Воронки, поля, представления и права доступа',settings(),'Сохранить изменения'] ]; for(const [file,title,sub,body,action] of screens)fs.writeFileSync(path.join(out,file),shell(title,sub,body,action),'utf8'); console.log(`generated ${screens.length} CRM V2 screens`);