mirror of
https://github.com/wasrusgen/wasrusgen1-crm.git
synced 2026-06-03 19:04:47 +00:00
ux(cabinet): объединить Этап 1+2 в «Разговор с Еленой» — клиент не теряет контекст (4 шага вместо 5)
This commit is contained in:
parent
492b1adae4
commit
6e0e85db86
@ -280,11 +280,10 @@ body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);displ
|
|||||||
<div class="si" id="si0" onclick="go(0)" style="margin-bottom:4px"><div class="si-num" style="background:rgba(255,255,255,.1);color:rgba(255,255,255,.7)">👤</div><div class="si-body"><div class="si-name">Профиль компании</div><div class="si-sub">О вашей деятельности</div></div></div>
|
<div class="si" id="si0" onclick="go(0)" style="margin-bottom:4px"><div class="si-num" style="background:rgba(255,255,255,.1);color:rgba(255,255,255,.7)">👤</div><div class="si-body"><div class="si-name">Профиль компании</div><div class="si-sub">О вашей деятельности</div></div></div>
|
||||||
<div style="height:1px;background:rgba(255,255,255,.06);margin:4px 18px 8px"></div>
|
<div style="height:1px;background:rgba(255,255,255,.06);margin:4px 18px 8px"></div>
|
||||||
<div class="sb-cap">Путь к результату</div>
|
<div class="sb-cap">Путь к результату</div>
|
||||||
<div class="si active" id="si1" onclick="go(1)"><div class="si-num">1</div><div class="si-body"><div class="si-lbl">Этап 1</div><div class="si-name">Знакомство</div><div class="si-sub">Интервью с Еленой</div></div></div>
|
<div class="si active" id="si1" onclick="go(1)"><div class="si-num">1</div><div class="si-body"><div class="si-lbl">Этап 1</div><div class="si-name">Разговор с Еленой</div><div class="si-sub">Знакомство и диагностика</div></div></div>
|
||||||
<div class="si" id="si2" onclick="go(2)"><div class="si-num">2</div><div class="si-body"><div class="si-lbl">Этап 2</div><div class="si-name">Диагностика</div><div class="si-sub">Углубление</div></div></div>
|
<div class="si" id="si3" onclick="go(3)"><div class="si-num">2</div><div class="si-body"><div class="si-lbl">Этап 2</div><div class="si-name">Документы</div><div class="si-sub">Материалы</div></div></div>
|
||||||
<div class="si" id="si3" onclick="go(3)"><div class="si-num">3</div><div class="si-body"><div class="si-lbl">Этап 3</div><div class="si-name">Документы</div><div class="si-sub">Материалы</div></div></div>
|
<div class="si" id="si4" onclick="go(4)"><div class="si-num">3</div><div class="si-body"><div class="si-lbl">Этап 3</div><div class="si-name">Анализ</div><div class="si-sub">Модель бизнеса</div></div></div>
|
||||||
<div class="si" id="si4" onclick="go(4)"><div class="si-num">4</div><div class="si-body"><div class="si-lbl">Этап 4</div><div class="si-name">Анализ</div><div class="si-sub">Модель бизнеса</div></div></div>
|
<div class="si" id="si5" onclick="go(5)"><div class="si-num">4</div><div class="si-body"><div class="si-lbl">Этап 4</div><div class="si-name">План</div><div class="si-sub">ТЗ на программу</div></div></div>
|
||||||
<div class="si" id="si5" onclick="go(5)"><div class="si-num">5</div><div class="si-body"><div class="si-lbl">Этап 5</div><div class="si-name">План</div><div class="si-sub">ТЗ на программу</div></div></div>
|
|
||||||
<div style="height:1px;background:rgba(255,255,255,.06);margin:8px 18px"></div>
|
<div style="height:1px;background:rgba(255,255,255,.06);margin:8px 18px"></div>
|
||||||
<div class="si" id="si6" onclick="go(6)"><div class="si-num" style="background:rgba(4,120,87,.25);color:#10B981">💬</div><div class="si-body"><div class="si-name">Консультант</div><div class="si-sub">Связаться с Русланом</div></div></div>
|
<div class="si" id="si6" onclick="go(6)"><div class="si-num" style="background:rgba(4,120,87,.25);color:#10B981">💬</div><div class="si-body"><div class="si-name">Консультант</div><div class="si-sub">Связаться с Русланом</div></div></div>
|
||||||
</div>
|
</div>
|
||||||
@ -305,9 +304,9 @@ body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);displ
|
|||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Этап 1 — Знакомство (живой чат) -->
|
<!-- Этап 1 — Разговор с Еленой (знакомство + диагностика) -->
|
||||||
<div class="sv active" id="sv1">
|
<div class="sv active" id="sv1">
|
||||||
<div class="hero"><div class="hero-ic">💬</div><div><div class="hero-tag">Этап 1 из 5 · В процессе</div><div class="hero-h">Знакомство</div><div class="hero-d">Расскажите Елене о вашем бизнесе — текстом или голосом</div></div></div>
|
<div class="hero"><div class="hero-ic">💬</div><div><div class="hero-tag">Этап 1 из 4 · В процессе</div><div class="hero-h">Разговор с Еленой</div><div class="hero-d">Расскажите о бизнесе — Елена знакомится и сразу углубляется в детали. Текстом или голосом.</div></div></div>
|
||||||
<div class="scroll"><div class="chat" id="chat"></div></div>
|
<div class="scroll"><div class="chat" id="chat"></div></div>
|
||||||
<div class="inbar">
|
<div class="inbar">
|
||||||
<textarea class="inp" id="inp" rows="1" placeholder="Напишите или скажите Елене..." onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendMsg()}"></textarea>
|
<textarea class="inp" id="inp" rows="1" placeholder="Напишите или скажите Елене..." onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendMsg()}"></textarea>
|
||||||
@ -316,20 +315,9 @@ body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);displ
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Этап 2 — Диагностика (живой чат, продолжение беседы) -->
|
|
||||||
<div class="sv" id="sv2">
|
|
||||||
<div class="hero"><div class="hero-ic">🔍</div><div><div class="hero-tag">Этап 2 из 5 · Диагностика</div><div class="hero-h">Углубляемся</div><div class="hero-d">Елена задаёт уточняющие вопросы — отвечайте. Это продолжение разговора с Этапа 1.</div></div></div>
|
|
||||||
<div class="scroll"><div class="chat" id="chat2"></div></div>
|
|
||||||
<div class="inbar">
|
|
||||||
<textarea class="inp" id="inp2" rows="1" placeholder="Ответьте Елене…" onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendMsg2()}"></textarea>
|
|
||||||
<button class="icon-btn mic" id="mic2" onclick="toggleMic('inp2','mic2')" title="Голосом"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg></button>
|
|
||||||
<button class="icon-btn send" id="send2" onclick="sendMsg2()"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Этап 3 — Документы -->
|
<!-- Этап 3 — Документы -->
|
||||||
<div class="sv" id="sv3">
|
<div class="sv" id="sv3">
|
||||||
<div class="hero"><div class="hero-ic">📁</div><div><div class="hero-tag">Этап 3 из 5</div><div class="hero-h">Документы</div><div class="hero-d">Загрузите материалы — Елена учтёт их в анализе</div></div></div>
|
<div class="hero"><div class="hero-ic">📁</div><div><div class="hero-tag">Этап 2 из 4</div><div class="hero-h">Документы</div><div class="hero-d">Загрузите материалы — Елена учтёт их в анализе</div></div></div>
|
||||||
<div class="scroll"><div class="pad">
|
<div class="scroll"><div class="pad">
|
||||||
<div class="drop" id="dropZone" onclick="document.getElementById('fileInp').click()">
|
<div class="drop" id="dropZone" onclick="document.getElementById('fileInp').click()">
|
||||||
<div class="drop-ic">📎</div>
|
<div class="drop-ic">📎</div>
|
||||||
@ -343,13 +331,13 @@ body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);displ
|
|||||||
|
|
||||||
<!-- Этап 4 — Анализ -->
|
<!-- Этап 4 — Анализ -->
|
||||||
<div class="sv" id="sv4">
|
<div class="sv" id="sv4">
|
||||||
<div class="hero"><div class="hero-ic">🧠</div><div><div class="hero-tag">Этап 4 из 5</div><div class="hero-h">Анализ бизнеса</div><div class="hero-d">Елена строит модель вашего бизнеса</div></div></div>
|
<div class="hero"><div class="hero-ic">🧠</div><div><div class="hero-tag">Этап 3 из 4</div><div class="hero-h">Анализ бизнеса</div><div class="hero-d">Елена строит модель вашего бизнеса</div></div></div>
|
||||||
<div class="scroll"><div class="pad" id="anPad"></div></div>
|
<div class="scroll"><div class="pad" id="anPad"></div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Этап 5 — План -->
|
<!-- Этап 5 — План -->
|
||||||
<div class="sv" id="sv5">
|
<div class="sv" id="sv5">
|
||||||
<div class="hero"><div class="hero-ic">🚀</div><div><div class="hero-tag">Этап 5 из 5</div><div class="hero-h">План — ТЗ на программу</div><div class="hero-d">Проект системы для вашего бизнеса</div></div></div>
|
<div class="hero"><div class="hero-ic">🚀</div><div><div class="hero-tag">Этап 4 из 4</div><div class="hero-h">План — ТЗ на программу</div><div class="hero-d">Проект системы для вашего бизнеса</div></div></div>
|
||||||
<div class="scroll"><div class="pad" id="specPad"></div></div>
|
<div class="scroll"><div class="pad" id="specPad"></div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -389,7 +377,7 @@ const urlToken=new URLSearchParams(location.search).get("t");
|
|||||||
if(urlToken)localStorage.setItem("cab_token",urlToken);
|
if(urlToken)localStorage.setItem("cab_token",urlToken);
|
||||||
let token=urlToken||localStorage.getItem("cab_token"), state=null, cur=1;
|
let token=urlToken||localStorage.getItem("cab_token"), state=null, cur=1;
|
||||||
const chat=document.getElementById("chat"), inp=document.getElementById("inp");
|
const chat=document.getElementById("chat"), inp=document.getElementById("inp");
|
||||||
const PCTS={1:20,2:40,3:60,4:80,5:100};
|
const PCTS={1:25,3:50,4:75,5:100}; // 4 шага для клиента (Этап 1 объединён)
|
||||||
function esc(s){return (s||"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}
|
function esc(s){return (s||"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}
|
||||||
function fmt(s){return esc(s).replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>")}
|
function fmt(s){return esc(s).replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>")}
|
||||||
|
|
||||||
@ -411,7 +399,6 @@ function go(n){
|
|||||||
document.getElementById('si'+n).classList.add('active');
|
document.getElementById('si'+n).classList.add('active');
|
||||||
if(PCTS[n]!=null){document.getElementById('pbPct').textContent=PCTS[n]+'%';document.getElementById('pbFill').style.width=PCTS[n]+'%';}
|
if(PCTS[n]!=null){document.getElementById('pbPct').textContent=PCTS[n]+'%';document.getElementById('pbFill').style.width=PCTS[n]+'%';}
|
||||||
if(n===1){renderChat1();requestAnimationFrame(scrollChatBottom);} // ре-рендер из общей беседы
|
if(n===1){renderChat1();requestAnimationFrame(scrollChatBottom);} // ре-рендер из общей беседы
|
||||||
if(n===2)renderChat2(); // продолжение того же диалога
|
|
||||||
if(n===6){renderOpChat();startOpPoll();}else{stopOpPoll();}
|
if(n===6){renderOpChat();startOpPoll();}else{stopOpPoll();}
|
||||||
if(n===3)renderDocs();
|
if(n===3)renderDocs();
|
||||||
if(n===4)renderAnalysis();
|
if(n===4)renderAnalysis();
|
||||||
@ -593,15 +580,6 @@ function renderAll(){
|
|||||||
checkPayment();
|
checkPayment();
|
||||||
}
|
}
|
||||||
function renderChat1(){const c=document.getElementById("chat");if(!c)return;c.innerHTML="";(state.messages||[]).forEach(m=>addMsg(m.role==="user"?"user":"elena",m.content));}
|
function renderChat1(){const c=document.getElementById("chat");if(!c)return;c.innerHTML="";(state.messages||[]).forEach(m=>addMsg(m.role==="user"?"user":"elena",m.content));}
|
||||||
/* ── Этап 2 — продолжение диалога (тот же state.messages) ── */
|
|
||||||
function addMsg2(role,text){const c=document.getElementById("chat2");if(!c)return;const m=document.createElement("div");m.className="msg "+(role==="user"?"user":"");m.innerHTML=`<div class="av ${role==='user'?'u':'e'}">${role==='user'?'Я':'Е'}</div><div class="bb ${role==='user'?'out':'in'}">${fmt(text)}</div>`;c.appendChild(m);const sc=c.parentElement;if(sc)sc.scrollTop=sc.scrollHeight;}
|
|
||||||
function renderChat2(){const c=document.getElementById("chat2");if(!c)return;c.innerHTML="";const m=state.messages||[];if(!m.length){c.innerHTML='<div style="text-align:center;color:#cbd5e1;font-size:13px;padding:24px 16px">Начните разговор на Этапе 1 — здесь Елена продолжит уточнять детали.</div>';return;}m.forEach(x=>addMsg2(x.role==="user"?"user":"elena",x.content));requestAnimationFrame(()=>{const sc=c.parentElement;if(sc)sc.scrollTop=sc.scrollHeight;});}
|
|
||||||
async function sendMsg2(){const i=document.getElementById("inp2");const t=i.value.trim();if(!t)return;if(recording)stopMic();i.value="";i.style.height="auto";addMsg2("user",t);state.messages.push({role:"user",content:t});
|
|
||||||
const btn=document.getElementById("send2");btn.disabled=true;
|
|
||||||
const tp=document.createElement("div");tp.className="msg";tp.id="typing2";tp.innerHTML='<div class="av e">Е</div><div class="typing"><span></span><span></span><span></span></div>';document.getElementById("chat2").appendChild(tp);const sc=document.getElementById("chat2").parentElement;if(sc)sc.scrollTop=sc.scrollHeight;
|
|
||||||
try{const r=await fetch(`${API}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token,message:t})});const d=await r.json();const x=document.getElementById("typing2");if(x)x.remove();addMsg2("elena",d.reply||("Ошибка: "+(d.error||"?")));state.messages.push({role:"assistant",content:d.reply||""});unlockStages();}catch(e){const x=document.getElementById("typing2");if(x)x.remove();addMsg2("elena","Ошибка связи: "+e.message);}
|
|
||||||
btn.disabled=false;
|
|
||||||
}
|
|
||||||
function money(n){return (n||0).toLocaleString("ru-RU")+" ₽"}
|
function money(n){return (n||0).toLocaleString("ru-RU")+" ₽"}
|
||||||
function checkPayment(){
|
function checkPayment(){
|
||||||
const crm=state.crm||{};const deal=crm.deal_amount||0;
|
const crm=state.crm||{};const deal=crm.deal_amount||0;
|
||||||
@ -668,7 +646,7 @@ async function payVia(method){
|
|||||||
function unlockStages(){
|
function unlockStages(){
|
||||||
// Этап 4 доступен если есть достаточно сообщений
|
// Этап 4 доступен если есть достаточно сообщений
|
||||||
const enough=state.messages.length>=3;
|
const enough=state.messages.length>=3;
|
||||||
[2,3,4,5].forEach(n=>{const si=document.getElementById('si'+n);if(enough||n<=3)si.classList.remove('locked');});
|
[3,4,5].forEach(n=>{const si=document.getElementById('si'+n);if(si&&(enough||n===3))si.classList.remove('locked');});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendMsg(){
|
async function sendMsg(){
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user