Backend:
- Channel/initiation now driven by a SCENARIO chosen at chat start, not baked into the
persona: social (customer opens), f2f_call (seller must open, proactive), recontact
(customer re-contacts after 1-3 months).
- /chat/start accepts {scenario}; session stores scenario + internal{turns,score}.
- persona_reply takes scenario + adapts tone; system-role transcript entries are fed to
the persona as hidden scene notes.
- JUDGE updated for realism: good response can WIN even in hard/tough-text scenarios;
long/no-close chats (turns >~12) lose; pushy/ignoring-need loses. Efficiency rewarded.
Frontend:
- Scenario picker before chat (choose Social / Face-to-face-call / Re-contact).
- Chat thread renders role=system as a centered time-lapse/scene note.
- Choose-scenario i18n (EN+TH).
Rebuilt dist.
7 lines
4.5 KiB
JavaScript
7 lines
4.5 KiB
JavaScript
import{k,_ as C,l as V,c as u,a as s,m as i,u as a,j as m,t,i as l,n as h,w as f,v as w,p as z,e as M,F as N,q as L,s as P,x as U,r as v,o as _}from"./index-tI5UDFg-.js";import{U as j}from"./users-qicnhyDs.js";import{P as A}from"./plus-DCrJlDOb.js";/**
|
||
* @license lucide-vue-next v1.0.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const B=k("chart-column",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]]),S={class:"row",style:{"align-items":"center","margin-bottom":"16px"}},T={style:{margin:"0"}},D={class:"row",style:{"margin-left":"auto",gap:"10px"}},F={class:"users-btn"},I={class:"primary"},R={class:"card filter-bar"},W={class:"muted"},q=["disabled"],E=["disabled"],O={class:"row",style:{gap:"16px",margin:"16px 0"}},G={class:"card stat"},H={class:"card stat"},J={style:{color:"var(--green)"}},K={class:"card stat"},Q={style:{color:"var(--red)"}},X={class:"card stat"},Y={class:"card stat"},Z={class:"card"},$={class:"row",style:{"justify-content":"space-between","align-items":"center"}},ss={class:"bar"},ts={class:"muted",style:{"font-size":"12px","margin-top":"6px"}},es={style:{"margin-top":"20px"}},as={key:0,class:"card empty-state"},os={class:"grid"},ls={class:"row",style:{"justify-content":"space-between"}},ns={class:"muted"},is={class:"row",style:{"margin-top":"10px",gap:"8px"}},rs={class:"badge won"},ds={class:"badge lost"},cs={class:"badge not_tried"},us={class:"muted",style:{"margin-top":"8px"}},vs={__name:"Analytics",setup(_s){const o=v({overall:{total_sessions:0,wins:0,losses:0,close_rate:0,avg_score:0},trainee_count:0,hardest_personas:[]}),r=v(""),d=v(""),c=v(!1);async function p(){c.value=!0;try{o.value=await P.analytics({from:r.value,to:d.value})}finally{c.value=!1}}function b(){p()}function x(){r.value="",d.value="",p()}return V(p),(ps,e)=>{const g=U("router-link");return _(),u("div",null,[s("div",S,[s("div",null,[s("h2",T,[i(a(B),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),m(" "+t(a(l).t("adminOverview")),1)]),e[2]||(e[2]=s("div",{class:"muted",style:{"margin-top":"4px"}},"ภาพรวมผลการฝึกของทีมทั้งหมด — เลือกช่วงเวลาเพื่อดูสถิติ",-1))]),s("div",D,[i(g,{to:"/admin/users"},{default:h(()=>[s("button",F,[i(a(j),{size:18,"stroke-width":2}),m(" "+t(a(l).t("users")),1)])]),_:1}),i(g,{to:"/admin/new-group"},{default:h(()=>[s("button",I,[i(a(A),{size:18,"stroke-width":2}),m(" "+t(a(l).t("addProduct")),1)])]),_:1})])]),s("div",R,[s("span",W,"🗓 "+t(a(l).t("dateRange")),1),f(s("input",{type:"date","onUpdate:modelValue":e[0]||(e[0]=n=>r.value=n)},null,512),[[w,r.value]]),e[3]||(e[3]=s("span",null,"–",-1)),f(s("input",{type:"date","onUpdate:modelValue":e[1]||(e[1]=n=>d.value=n)},null,512),[[w,d.value]]),s("button",{class:"primary",onClick:b,disabled:c.value},"→ "+t(a(l).t("apply")),9,q),s("button",{onClick:x,disabled:c.value},t(a(l).t("clear")),9,E)]),s("div",O,[s("div",G,[e[4]||(e[4]=s("div",null,"Sessions",-1)),s("strong",null,t(o.value.overall.total_sessions),1)]),s("div",H,[e[5]||(e[5]=s("div",null,"Wins",-1)),s("strong",J,t(o.value.overall.wins),1)]),s("div",K,[e[6]||(e[6]=s("div",null,"Losses",-1)),s("strong",Q,t(o.value.overall.losses),1)]),s("div",X,[e[7]||(e[7]=s("div",null,"Avg score",-1)),s("strong",null,t(o.value.overall.avg_score),1)]),s("div",Y,[e[8]||(e[8]=s("div",null,"Trainees",-1)),s("strong",null,t(o.value.trainee_count),1)])]),s("div",Z,[s("div",$,[s("strong",null,t(a(l).t("closeRate")),1),s("strong",null,t(o.value.overall.close_rate)+"%",1)]),s("div",ss,[s("div",{class:"bar-fill",style:z({width:(o.value.overall.close_rate||0)+"%"})},null,4)]),s("div",ts,t(o.value.overall.wins)+" "+t(a(l).t("won").toLowerCase())+" / "+t(o.value.overall.total_sessions)+" sessions ",1)]),s("h3",es,t(a(l).t("hardestPersonas")),1),o.value.hardest_personas.length===0?(_(),u("div",as,[...e[9]||(e[9]=[s("strong",null,"No data",-1),s("span",null,"No sessions in this date range.",-1)])])):M("",!0),s("div",os,[(_(!0),u(N,null,L(o.value.hardest_personas,(n,y)=>(_(),u("div",{key:y,class:"card lift tier-card"},[s("div",ls,[s("strong",null,t(n.persona_name),1),s("span",ns,"#"+t(y+1),1)]),s("div",is,[s("span",rs,t(n.wins)+"W",1),s("span",ds,t(n.losses)+"L",1),s("span",cs,t(n.plays)+" plays",1)]),s("div",us,t(a(l).t("score"))+": "+t(n.avg_score),1)]))),128))])])}}},hs=C(vs,[["__scopeId","data-v-f2feb744"]]);export{hs as default};
|