Files
sales-trainer/frontend/dist/assets/Chat-C6Malw3d.js
Macky 15c60ae400 feat(i18n + export + guide): locale-aware scenarios/debrief; CSV export; how-to-use page
Backend:
- SCENARIOS localized (th/en): scenario preamble + persona tone adaptation follow the
  trainee's locale; start accepts {locale} and stores it on the session; send/auto-finish
  use it so debrief text (why/coaching/turning points) is in the active language.
- /api/analytics/export returns per-trainee finished-session CSV (admin).

Frontend:
- Scenario picker labels localize by i18n.locale.
- New /guide page (non-IT how-to), linked from Training.
- Analytics: date-filter bar uses line icon + 'Download CSV' button (fetch w/ auth).
Rebuilt dist.
2026-08-08 15:06:48 +07:00

7 lines
7.6 KiB
JavaScript

import{k as P,_ as R,l as G,s as S,c as o,m as k,n as D,u as a,a as s,t,i as n,F as T,q as L,j as g,A as w,e as h,w as K,v as $,b as q,h as H,r as d,z as J,C as O,x as U,o as l}from"./index-Dm2VwslH.js";import{T as Y}from"./target-CliUY7kC.js";import{A as Q}from"./arrow-left-Cm4VHcqz.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 W=P("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]),X={key:0,class:"card"},Z={style:{"margin-top":"0"}},ee=["onClick"],se={class:"row",style:{"align-items":"center"}},te={key:0,class:"badge line"},ae={key:1,class:"badge facebook"},oe={class:"muted",style:{"margin-top":"6px"}},le=["disabled"],ne={key:1},ie={class:"card guide"},re={style:{margin:"6px 0 0","line-height":"1.7"}},ce={class:"row",style:{"align-items":"center","margin-bottom":"12px"}},ue={style:{margin:"0"}},de={key:0,class:"muted"},ve={key:0,class:"bubble msg-customer muted"},me={key:0,class:"composer"},pe=["disabled","placeholder"],he=["disabled"],_e={key:1,class:"card debrief"},ge={key:0},ye={key:0,class:"reveal-grid"},fe={class:"rk"},be={class:"rv"},ke={class:"primary",style:{"margin-top":"12px"}},we={__name:"Chat",setup(xe){const z=H(),y=z.params.gid,x=z.params.pid,c=d(null),u=d("pick"),v=d([]),_=d(""),f=d(!1),i=d(null),N=d(null),b=d("social"),V=J(()=>{const e=n.locale==="en";return[{id:"social",emoji:"💬",init:"customer",label:e?"Social Media (chat)":"Social Media (แชท)",desc:e?"The customer messages you first — short, chat-style replies":"ลูกค้าทักมาหาคุณก่อน — โทนสั้น ทักๆ ตามสไตล์แชท"},{id:"f2f_call",emoji:"📞",init:"seller",label:e?"Face-to-face / Phone":"พบหน้า / โทรศัพท์",desc:e?"You must proactively open the conversation (seller starts)":"คุณต้องเป็นฝ่ายเปิดการสนทนาเชิงรุกกับลีด (ผู้ฝึกทักก่อน)"},{id:"recontact",emoji:"⏳",init:"customer",label:e?"Re-contact (1-3 months)":"ลูกค้ากลับมาติดต่อ (1-3 เดือน)",desc:e?"Customer contacted you before, now returns more ready to decide":"เคยได้รับข้อมูลไปแล้ว ตอนนี้กลับมาติดต่อ พร้อมตัดสินใจมากขึ้น"}]});function A(){O(()=>{C.value&&(C.value.scrollTop=C.value.scrollHeight)})}const C=d(null);async function F(){u.value="chat";const e=await S.chatStart(y,x,b.value,n.locale);N.value=e.session.id,v.value=e.session.messages||[],v.value.length&&A()}G(async()=>{c.value=(await S.getPersona(y,x)).persona;try{const e=await S.chatResume(y,x);N.value=e.session.id,v.value=e.session.messages||[],v.value.length&&!e.session.debrief?(u.value="chat",V.find(j=>j.id===e.scenario)&&(b.value=e.scenario)):e.session.debrief&&(i.value=e.session.debrief,v.value=e.session.messages||[],u.value="done"),v.value.length&&A()}catch{u.value="pick"}});async function B(){if(_.value.trim()){f.value=!0;try{const e=await S.chatSend(y,x,_.value.trim());v.value=e.messages,_.value="",e.finished&&(i.value=e.debrief||null,u.value="done"),A()}catch(e){alert(e.message)}finally{f.value=!1}}}const I={name:"ชื่อ",tier:"ระดับ",difficulty:"ความยาก",profession:"อาชีพ",age_group:"ช่วงอายุ",location:"พื้นที่",income:"รายได้",budget:"งบประมาณ",lifestyle:"ไลฟ์สไตล์",background:"ภูมิหลัง",personality:"บุคลิก",communication_style:"สไตล์การสื่อสาร",goal:"เป้าหมาย",decision_timeline:"กรอบตัดสินใจ",pains:"ปัญหา (Pain)",objections:"ข้อโต้แย้ง",negotiation_levers:"สิ่งที่ใช้ต่อรอง",opener:"บทเปิดบทสนทนา",channel:"ช่องทาง",initiation_mode:"ใครเริ่มก่อน",product_context:"บริบทสินค้า"};function M(e){return I[e]||e}function E(e){return Array.isArray(e)?e.join(", "):e&&typeof e=="object"?JSON.stringify(e):String(e??"—")}return(e,m)=>{const j=U("router-link");return l(),o("div",null,[k(j,{to:`/groups/${a(y)}/personas`,class:"btn-back"},{default:D(()=>[k(a(Q),{size:16,"stroke-width":2}),g(" "+t(a(n).t("personas")),1)]),_:1},8,["to"]),u.value==="pick"?(l(),o("div",X,[s("h3",Z,"🎬 "+t(a(n).t("chooseScenario")),1),m[1]||(m[1]=s("p",{class:"muted",style:{"margin-top":"0"}},"เลือกสถานการณ์ที่อยากฝึกการขาย — แต่ละแบบกำหนดว่าใครทักก่อน และโทนการสนทนา",-1)),(l(!0),o(T,null,L(V.value,r=>(l(),o("div",{key:r.id,class:w(["scenario",{sel:b.value===r.id}]),onClick:p=>b.value=r.id},[s("div",se,[s("strong",null,t(r.emoji)+" "+t(r.label),1),r.init==="customer"?(l(),o("span",te,"ลูกค้าทักก่อน")):(l(),o("span",ae,"คุณต้องทักก่อน (เชิงรุก)"))]),s("div",oe,t(r.desc),1)],10,ee))),128)),s("button",{class:"primary",style:{"margin-top":"16px",width:"100%"},disabled:!b.value,onClick:F}," ▶ "+t(a(n).t("start")),9,le)])):(l(),o("div",ne,[s("div",ie,[s("strong",null,[k(a(Y),{size:17,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),g(" "+t(a(n).t("chatGuideTitle")),1)]),s("p",re,t(a(n).t("chatGuideText")),1)]),s("div",ce,[s("h2",ue,t(c.value?c.value.name:"..."),1),s("span",{class:w(["badge",c.value&&c.value.channel])},t(c.value?c.value.channel:""),3),c.value?(l(),o("span",de,t(c.value.profession)+" · "+t(c.value.age_group),1)):h("",!0),u.value==="done"?(l(),o("span",{key:1,class:w(["badge",i.value&&i.value.outcome])},t(i.value&&i.value.outcome==="won"?a(n).t("won"):a(n).t("lost")),3)):h("",!0)]),s("div",{class:"thread",ref_key:"thread",ref:C},[(l(!0),o(T,null,L(v.value,(r,p)=>(l(),o("div",{key:p,class:w(["bubble",r.role==="seller"?"msg-seller":r.role==="system"?"msg-system":"msg-customer"])},t(r.text),3))),128)),f.value?(l(),o("div",ve,"...")):h("",!0)],512),u.value==="chat"?(l(),o("div",me,[K(s("input",{"onUpdate:modelValue":m[0]||(m[0]=r=>_.value=r),onKeyup:q(B,["enter"]),disabled:f.value,placeholder:a(n).t("send")},null,40,pe),[[$,_.value]]),s("button",{class:"primary",onClick:B,disabled:f.value||!_.value.trim()},t(a(n).t("send")),9,he)])):h("",!0),u.value==="done"&&i.value?(l(),o("div",_e,[s("h3",null,t(a(n).t("debrief")),1),s("p",null,[s("span",{class:w(["badge",i.value.outcome])},t(i.value.outcome==="won"?a(n).t("won"):a(n).t("lost")),3),g(" — "+t(a(n).t("score"))+": ",1),s("strong",null,t(i.value.score),1)]),s("p",null,[s("strong",null,t(a(n).t("pain"))+":",1),g(" "+t(i.value.pain||"—"),1)]),s("p",null,[s("strong",null,t(a(n).t("why"))+":",1),g(" "+t(i.value.why),1)]),i.value.coaching&&i.value.coaching.length?(l(),o("div",ge,[m[2]||(m[2]=s("strong",null,"Coaching:",-1)),s("ul",null,[(l(!0),o(T,null,L(i.value.coaching,(r,p)=>(l(),o("li",{key:p},t(r),1))),128))])])):h("",!0),s("details",null,[s("summary",null,[k(a(W),{size:15,"stroke-width":1.8,style:{"vertical-align":"-2px"}}),g(" "+t(a(n).t("reveal")),1)]),i.value.revealed_persona?(l(),o("div",ye,[(l(!0),o(T,null,L(i.value.revealed_persona,(r,p)=>(l(),o("div",{key:p,class:"rev"},[s("span",fe,t(M(p)),1),s("span",be,t(E(r)),1)]))),128))])):h("",!0)]),k(j,{to:"/"},{default:D(()=>[s("button",ke,t(a(n).t("dashboard")),1)]),_:1})])):h("",!0)]))])}}},Te=R(we,[["__scopeId","data-v-19840301"]]);export{Te as default};