diff --git a/frontend/dist/assets/AdminUsers-Cv-dZx8g.js b/frontend/dist/assets/AdminUsers-B8OP5hvL.js similarity index 66% rename from frontend/dist/assets/AdminUsers-Cv-dZx8g.js rename to frontend/dist/assets/AdminUsers-B8OP5hvL.js index 2d6f8a5..1210bc9 100644 --- a/frontend/dist/assets/AdminUsers-Cv-dZx8g.js +++ b/frontend/dist/assets/AdminUsers-B8OP5hvL.js @@ -1,11 +1,11 @@ -import{k as w,_ as h,l as U,c as r,a as e,m,u as o,j as l,t as n,i as u,w as p,v,E as b,e as f,F as V,q as M,s as k,r as y,o as i,A as C}from"./index-C0_i8cDF.js";import{U as z}from"./users-qxBh6IGP.js";/** +import{c as k,_ as h,n as b,a as r,b as e,l as m,u as o,m as l,t as n,i as u,w as p,v,E as U,g as f,F as V,s as M,x as w,r as y,o as i,B as C}from"./index-DOaJiTJw.js";import{U as z}from"./users-SQMCzZpr.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 L=w("info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]);/** + */const B=k("info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]);/** * @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 N=w("user-plus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]),A={class:"card guide"},B={class:"card",style:{"margin-bottom":"16px"}},I={style:{"margin-top":"0"}},j={class:"row"},q={class:"row",style:{"margin-top":"10px"}},D=["disabled"],E={key:0,class:"error"},F={key:0,class:"card empty-state"},S={style:{flex:"1"}},T={class:"badge"},H={__name:"AdminUsers",setup(P){const c=y([]),d=y(""),t=y({username:"",name:"",password:"",role:"user"});async function g(){c.value=(await k.adminListUsers()).users}async function _(){d.value="";try{await k.adminCreateUser({...t.value}),t.value={username:"",name:"",password:"",role:"user"},await g()}catch(x){d.value=x.message}}return U(g),(x,s)=>(i(),r("div",null,[e("h2",null,[m(o(z),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),l(" "+n(o(u).t("users")),1)]),e("div",A,[e("strong",null,[m(o(L),{size:17,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),s[4]||(s[4]=l(" วิธีเพิ่มผู้ใช้งาน",-1))]),s[5]||(s[5]=e("ol",{style:{margin:"8px 0 0","padding-left":"20px","line-height":"1.8"}},[e("li",null,[l("กรอก "),e("strong",null,"ชื่อผู้ใช้ (สำหรับเข้าสู่ระบบ)"),l(", ชื่อ, และรหัสผ่านเริ่มต้น")]),e("li",null,[l("เลือกสิทธิ์: "),e("strong",null,"user"),l(" = ผู้เข้าฝึกขาย, "),e("strong",null,"admin"),l(" = จัดการระบบ")]),e("li",null,[l("กด "),e("strong",null,"สร้าง"),l(" — นำชื่อผู้ใช้ + รหัสผ่านไปแจ้งให้ผู้ใช้นั้นเข้าสู่ระบบได้เลย")])],-1))]),e("div",B,[e("h4",I,[m(o(N),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),l(" + "+n(o(u).t("create"))+" "+n(o(u).t("users").toLowerCase()),1)]),e("div",j,[p(e("input",{"onUpdate:modelValue":s[0]||(s[0]=a=>t.value.username=a),placeholder:"ชื่อผู้ใช้ (เข้าสู่ระบบ)",style:{flex:"1"}},null,512),[[v,t.value.username]]),p(e("input",{"onUpdate:modelValue":s[1]||(s[1]=a=>t.value.name=a),placeholder:"ชื่อจริง",style:{flex:"1"}},null,512),[[v,t.value.name]]),p(e("input",{"onUpdate:modelValue":s[2]||(s[2]=a=>t.value.password=a),type:"password",placeholder:"รหัสผ่านเริ่มต้น",style:{flex:"1"}},null,512),[[v,t.value.password]])]),e("div",q,[p(e("select",{"onUpdate:modelValue":s[3]||(s[3]=a=>t.value.role=a),style:{flex:"1"}},[...s[6]||(s[6]=[e("option",{value:"user"},"🙂 user — ผู้เข้าฝึก",-1),e("option",{value:"admin"},"🛠 admin — ผู้ดูแลระบบ",-1)])],512),[[b,t.value.role]]),e("button",{class:"primary",onClick:_,disabled:!t.value.username||!t.value.password},"+ "+n(o(u).t("create")),9,D)]),d.value?(i(),r("div",E,n(d.value),1)):f("",!0)]),c.value.length===0?(i(),r("div",F,[...s[7]||(s[7]=[e("strong",null,"ยังไม่มีผู้ใช้งาน",-1),e("span",null,"สร้างผู้ใช้งานคนแรกด้วยฟอร์มด้านบน",-1)])])):f("",!0),(i(!0),r(V,null,M(c.value,a=>(i(),r("div",{class:"card",key:a.id,style:{"margin-bottom":"8px",display:"flex","align-items":"center",gap:"12px"}},[e("strong",S,n(a.name)+" ("+n(a.username)+")",1),e("span",T,n(a.role),1),e("span",{class:C(["badge",a.active?"won":"lost"])},n(a.active?"active":"inactive"),3)]))),128))]))}},K=h(H,[["__scopeId","data-v-924406be"]]);export{K as default}; + */const L=k("user-plus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]),N={class:"card guide"},I={class:"card",style:{"margin-bottom":"16px"}},A={style:{"margin-top":"0"}},D={class:"row"},E={class:"row",style:{"margin-top":"10px"}},F=["disabled"],S={key:0,class:"error"},T={key:0,class:"card empty-state"},j={style:{flex:"1"}},q={class:"badge"},H={__name:"AdminUsers",setup(P){const c=y([]),d=y(""),t=y({username:"",name:"",password:"",role:"user"});async function g(){c.value=(await w.adminListUsers()).users}async function _(){d.value="";try{await w.adminCreateUser({...t.value}),t.value={username:"",name:"",password:"",role:"user"},await g()}catch(x){d.value=x.message}}return b(g),(x,s)=>(i(),r("div",null,[e("h2",null,[m(o(z),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),l(" "+n(o(u).t("users")),1)]),e("div",N,[e("strong",null,[m(o(B),{size:17,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),s[4]||(s[4]=l(" วิธีเพิ่มผู้ใช้งาน",-1))]),s[5]||(s[5]=e("ol",{style:{margin:"8px 0 0","padding-left":"20px","line-height":"1.8"}},[e("li",null,[l("กรอก "),e("strong",null,"ชื่อผู้ใช้ (สำหรับเข้าสู่ระบบ)"),l(", ชื่อ, และรหัสผ่านเริ่มต้น")]),e("li",null,[l("เลือกสิทธิ์: "),e("strong",null,"user"),l(" = ผู้เข้าฝึกขาย, "),e("strong",null,"admin"),l(" = จัดการระบบ")]),e("li",null,[l("กด "),e("strong",null,"สร้าง"),l(" — นำชื่อผู้ใช้ + รหัสผ่านไปแจ้งให้ผู้ใช้นั้นเข้าสู่ระบบได้เลย")])],-1))]),e("div",I,[e("h4",A,[m(o(L),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),l(" + "+n(o(u).t("create"))+" "+n(o(u).t("users").toLowerCase()),1)]),e("div",D,[p(e("input",{"onUpdate:modelValue":s[0]||(s[0]=a=>t.value.username=a),placeholder:"ชื่อผู้ใช้ (เข้าสู่ระบบ)",style:{flex:"1"}},null,512),[[v,t.value.username]]),p(e("input",{"onUpdate:modelValue":s[1]||(s[1]=a=>t.value.name=a),placeholder:"ชื่อจริง",style:{flex:"1"}},null,512),[[v,t.value.name]]),p(e("input",{"onUpdate:modelValue":s[2]||(s[2]=a=>t.value.password=a),type:"password",placeholder:"รหัสผ่านเริ่มต้น",style:{flex:"1"}},null,512),[[v,t.value.password]])]),e("div",E,[p(e("select",{"onUpdate:modelValue":s[3]||(s[3]=a=>t.value.role=a),style:{flex:"1"}},[...s[6]||(s[6]=[e("option",{value:"user"},"🙂 user — ผู้เข้าฝึก",-1),e("option",{value:"admin"},"🛠 admin — ผู้ดูแลระบบ",-1)])],512),[[U,t.value.role]]),e("button",{class:"primary",onClick:_,disabled:!t.value.username||!t.value.password},"+ "+n(o(u).t("create")),9,F)]),d.value?(i(),r("div",S,n(d.value),1)):f("",!0)]),c.value.length===0?(i(),r("div",T,[...s[7]||(s[7]=[e("strong",null,"ยังไม่มีผู้ใช้งาน",-1),e("span",null,"สร้างผู้ใช้งานคนแรกด้วยฟอร์มด้านบน",-1)])])):f("",!0),(i(!0),r(V,null,M(c.value,a=>(i(),r("div",{class:"card",key:a.id,style:{"margin-bottom":"8px",display:"flex","align-items":"center",gap:"12px"}},[e("strong",j,n(a.name)+" ("+n(a.username)+")",1),e("span",q,n(a.role),1),e("span",{class:C(["badge",a.active?"won":"lost"])},n(a.active?"active":"inactive"),3)]))),128))]))}},K=h(H,[["__scopeId","data-v-924406be"]]);export{K as default}; diff --git a/frontend/dist/assets/Analytics-z04-C_VZ.js b/frontend/dist/assets/Analytics-Bkjt0mFt.js similarity index 95% rename from frontend/dist/assets/Analytics-z04-C_VZ.js rename to frontend/dist/assets/Analytics-Bkjt0mFt.js index ddf804a..0fb9998 100644 --- a/frontend/dist/assets/Analytics-z04-C_VZ.js +++ b/frontend/dist/assets/Analytics-Bkjt0mFt.js @@ -1,4 +1,4 @@ -import{k as x,_ as L,l as M,c as p,a as s,m as i,u as a,j as c,t as e,i as n,n as w,w as f,v as b,p as U,e as N,F as R,q as j,s as A,x as B,r as m,f as E,o as y}from"./index-C0_i8cDF.js";import{U as P}from"./users-qxBh6IGP.js";import{P as S}from"./plus-BiLb0OIF.js";/** +import{c as x,_ as L,n as M,a as p,b as s,l as i,u as a,m as c,t as e,i as n,p as w,w as f,v as b,q as U,g as N,F as R,s as j,x as A,y as B,r as m,h as E,o as y}from"./index-DOaJiTJw.js";import{U as P}from"./users-SQMCzZpr.js";import{P as S}from"./plus-CODydpxS.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/Chat-DvLKhxgu.js b/frontend/dist/assets/Chat-DszzTVNw.js similarity index 89% rename from frontend/dist/assets/Chat-DvLKhxgu.js rename to frontend/dist/assets/Chat-DszzTVNw.js index 9df0949..66960fd 100644 --- a/frontend/dist/assets/Chat-DvLKhxgu.js +++ b/frontend/dist/assets/Chat-DszzTVNw.js @@ -1,6 +1,6 @@ -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-C0_i8cDF.js";import{T as Y}from"./target-DoOGVGr0.js";import{A as Q}from"./arrow-left-neyuEczm.js";/** +import{c as P,_ as R,n as G,x as S,a as o,l as k,p as D,u as a,b as s,t,i as n,F as T,s as L,m as g,B as w,g as h,w as K,v as $,d as H,k as J,r as d,A as O,C as U,y as Y,o as l}from"./index-DOaJiTJw.js";import{T as q}from"./target-QJk_fUDu.js";import{A as Q}from"./arrow-left-BUCak2lw.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}; + */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 B=J(),y=B.params.gid,x=B.params.pid,c=d(null),u=d("pick"),v=d([]),_=d(""),f=d(!1),i=d(null),N=d(null),b=d("social"),V=O(()=>{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(){U(()=>{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 z(){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=Y("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(q),{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:H(z,["enter"]),disabled:f.value,placeholder:a(n).t("send")},null,40,pe),[[$,_.value]]),s("button",{class:"primary",onClick:z,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}; diff --git a/frontend/dist/assets/GroupBuilder-DYRYwsrA.js b/frontend/dist/assets/GroupBuilder-CNxYYLnR.js similarity index 96% rename from frontend/dist/assets/GroupBuilder-DYRYwsrA.js rename to frontend/dist/assets/GroupBuilder-CNxYYLnR.js index fe7a46f..f1f4538 100644 --- a/frontend/dist/assets/GroupBuilder-DYRYwsrA.js +++ b/frontend/dist/assets/GroupBuilder-CNxYYLnR.js @@ -1,4 +1,4 @@ -import{k as g,_ as M,c as f,m as d,n as V,a as e,u as l,j as r,t as s,i as o,w as u,v as y,E as k,e as C,x as z,r as v,s as B,g as A,o as x}from"./index-C0_i8cDF.js";import{A as P}from"./arrow-left-neyuEczm.js";/** +import{c as g,_ as M,a as f,l as d,p as V,b as e,u as l,m as r,t as s,i as o,w as u,v as y,E as k,g as C,y as z,r as v,x as B,j as A,o as x}from"./index-DOaJiTJw.js";import{A as P}from"./arrow-left-BUCak2lw.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/GroupEdit-DsLJeZZx.js b/frontend/dist/assets/GroupEdit-Bq-uo5sC.js similarity index 86% rename from frontend/dist/assets/GroupEdit-DsLJeZZx.js rename to frontend/dist/assets/GroupEdit-Bq-uo5sC.js index 12dcfd9..ad7204c 100644 --- a/frontend/dist/assets/GroupEdit-DsLJeZZx.js +++ b/frontend/dist/assets/GroupEdit-Bq-uo5sC.js @@ -1,9 +1,9 @@ -import{k as I,_ as F,G as M,o as m,c as f,a as e,t as i,w as o,v as u,E as N,e as _,H as O,r as k,l as q,m as A,n as D,u as c,j as y,i as B,B as J,F as P,q as S,I as H,h as R,s as j,x as K,A as T}from"./index-C0_i8cDF.js";import{U as Q}from"./users-qxBh6IGP.js";import{S as W}from"./sparkles-D66jVNJm.js";/** +import{c as I,_ as F,G as M,o as m,a as f,b as e,t as i,w as o,v as u,E as N,g as _,H as O,r as k,n as D,l as z,p as J,u as c,m as y,i as B,f as q,F as P,s as S,I as H,k as R,x as A,y as K,B as T}from"./index-DOaJiTJw.js";import{U as Q}from"./users-SQMCzZpr.js";import{S as W}from"./sparkles-CwNig9QR.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 X=I("pencil",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]),Y={class:"persona-form"},Z={class:"muted"},h={class:"sec"},ee={class:"row"},le={class:"f"},te={class:"f"},ne={class:"f"},se={class:"row"},oe={class:"f"},ie={class:"f"},ae={class:"f"},ue={class:"sec"},re={class:"row"},de={class:"f"},me={class:"f"},ve={class:"f"},fe={class:"sec"},ge={class:"sec"},ye={class:"row"},be={class:"f"},ke={class:"f"},ce={key:0,class:"muted"},xe={class:"row actions"},we=["disabled"],Ve={__name:"PersonaForm",props:{persona:{type:Object,required:!0}},emits:["save","cancel"],setup(V,{emit:E}){const x=V,p=E,n=O({name:"",difficulty:1,tier:"B",profession:"",age_group:"",location:"",income:"",budget:"",lifestyle:"",background:"",personality:"",communication_style:"",goal:"",decision_timeline:"",opener:"",channel:"line",initiation_mode:"customer",special:""}),d=k(""),b=k(""),v=k(""),w=k(!1);function U(t){return Array.isArray(t)?t.join(` `):String(t||"")}function $(t){return t.split(` -`).map(l=>l.trim()).filter(Boolean)}M(()=>x.persona,t=>{Object.assign(n,{name:(t==null?void 0:t.name)||"",difficulty:(t==null?void 0:t.difficulty)??1,tier:(t==null?void 0:t.tier)||"B",profession:(t==null?void 0:t.profession)||"",age_group:(t==null?void 0:t.age_group)||"",location:(t==null?void 0:t.location)||"",income:(t==null?void 0:t.income)||"",budget:(t==null?void 0:t.budget)||"",lifestyle:(t==null?void 0:t.lifestyle)||"",background:(t==null?void 0:t.background)||"",personality:(t==null?void 0:t.personality)||"",communication_style:(t==null?void 0:t.communication_style)||"",goal:(t==null?void 0:t.goal)||"",decision_timeline:(t==null?void 0:t.decision_timeline)||"",opener:(t==null?void 0:t.opener)||"",channel:(t==null?void 0:t.channel)||"line",initiation_mode:(t==null?void 0:t.initiation_mode)||"customer",special:(t==null?void 0:t.special)||""}),d.value=U(t==null?void 0:t.pains),b.value=U(t==null?void 0:t.objections),v.value=U(t==null?void 0:t.negotiation_levers)},{immediate:!0});function z(){p("save",{...n,pains:$(d.value),objections:$(b.value),negotiation_levers:$(v.value)})}return(t,l)=>(m(),f("div",Y,[e("h3",null,i(V.persona.name||"New persona"),1),e("p",Z,i(V.persona.profession)+" · "+i(V.persona.personality),1),e("div",h,[l[28]||(l[28]=e("h4",null,"👤 ข้อมูลพื้นฐาน",-1)),e("div",ee,[e("div",le,[l[21]||(l[21]=e("label",null,"ชื่อ",-1)),o(e("input",{"onUpdate:modelValue":l[0]||(l[0]=s=>n.name=s)},null,512),[[u,n.name]])]),e("div",te,[l[22]||(l[22]=e("label",null,"ระดับความยาก (1-5)",-1)),o(e("input",{"onUpdate:modelValue":l[1]||(l[1]=s=>n.difficulty=s),type:"number",min:"1",max:"5"},null,512),[[u,n.difficulty,void 0,{number:!0}]])]),e("div",ne,[l[24]||(l[24]=e("label",null,"ระดับลูกค้า",-1)),o(e("select",{"onUpdate:modelValue":l[2]||(l[2]=s=>n.tier=s)},[...l[23]||(l[23]=[e("option",{value:"A"},"A — พร้อมตัดสินใจซื้อ",-1),e("option",{value:"B"},"B — ยังไม่แน่ใจ",-1),e("option",{value:"C"},"C — ไม่สนใจแต่มีปัญหา",-1)])],512),[[N,n.tier]])])]),e("div",se,[e("div",oe,[l[25]||(l[25]=e("label",null,"อาชีพ",-1)),o(e("input",{"onUpdate:modelValue":l[3]||(l[3]=s=>n.profession=s)},null,512),[[u,n.profession]])]),e("div",ie,[l[26]||(l[26]=e("label",null,"ช่วงอายุ",-1)),o(e("input",{"onUpdate:modelValue":l[4]||(l[4]=s=>n.age_group=s)},null,512),[[u,n.age_group]])]),e("div",ae,[l[27]||(l[27]=e("label",null,"พื้นที่",-1)),o(e("input",{"onUpdate:modelValue":l[5]||(l[5]=s=>n.location=s)},null,512),[[u,n.location]])])])]),e("div",ue,[l[32]||(l[32]=e("h4",null,"💼 ข้อมูลลูกค้า",-1)),e("div",re,[e("div",de,[l[29]||(l[29]=e("label",null,"รายได้/สถานะการเงิน",-1)),o(e("input",{"onUpdate:modelValue":l[6]||(l[6]=s=>n.income=s)},null,512),[[u,n.income]])]),e("div",me,[l[30]||(l[30]=e("label",null,"งบประมาณ",-1)),o(e("input",{"onUpdate:modelValue":l[7]||(l[7]=s=>n.budget=s)},null,512),[[u,n.budget]])]),e("div",ve,[l[31]||(l[31]=e("label",null,"ไลฟ์สไตล์",-1)),o(e("input",{"onUpdate:modelValue":l[8]||(l[8]=s=>n.lifestyle=s)},null,512),[[u,n.lifestyle]])])]),l[33]||(l[33]=e("label",null,"ภูมิหลัง",-1)),o(e("textarea",{"onUpdate:modelValue":l[9]||(l[9]=s=>n.background=s)},null,512),[[u,n.background]]),l[34]||(l[34]=e("label",null,"บุคลิก / วิธีพูดคุย",-1)),o(e("textarea",{"onUpdate:modelValue":l[10]||(l[10]=s=>n.personality=s)},null,512),[[u,n.personality]]),l[35]||(l[35]=e("label",null,"สไตล์การสื่อสาร",-1)),o(e("textarea",{"onUpdate:modelValue":l[11]||(l[11]=s=>n.communication_style=s)},null,512),[[u,n.communication_style]])]),e("div",fe,[l[36]||(l[36]=e("h4",null,"🎯 การขาย",-1)),l[37]||(l[37]=e("label",null,"เป้าหมาย",-1)),o(e("textarea",{"onUpdate:modelValue":l[12]||(l[12]=s=>n.goal=s)},null,512),[[u,n.goal]]),l[38]||(l[38]=e("label",null,"กรอบเวลาในการตัดสินใจ",-1)),o(e("input",{"onUpdate:modelValue":l[13]||(l[13]=s=>n.decision_timeline=s)},null,512),[[u,n.decision_timeline]]),l[39]||(l[39]=e("label",null,"Pain (ปัญหา) แบบ 1 ต่อบรรทัด",-1)),o(e("textarea",{"onUpdate:modelValue":l[14]||(l[14]=s=>d.value=s),placeholder:`เช่น ต้นทุนสูงเกินไป -ระบบล้าสมัย`},null,512),[[u,d.value]]),l[40]||(l[40]=e("label",null,"ข้อโต้แย้ง (Objections) 1 ต่อบรรทัด",-1)),o(e("textarea",{"onUpdate:modelValue":l[15]||(l[15]=s=>b.value=s)},null,512),[[u,b.value]]),l[41]||(l[41]=e("label",null,"สิ่งที่ใช้ต่อรอง (เช่น ส่วนลด, ฟรีติดตั้ง)",-1)),o(e("textarea",{"onUpdate:modelValue":l[16]||(l[16]=s=>v.value=s)},null,512),[[u,v.value]]),l[42]||(l[42]=e("label",null,"ช่องทางสำหรับลูกค้าเปิดบทสนทนา (opener)",-1)),o(e("textarea",{"onUpdate:modelValue":l[17]||(l[17]=s=>n.opener=s)},null,512),[[u,n.opener]])]),e("div",ge,[l[47]||(l[47]=e("h4",null,"📡 ช่องทาง & โหมด",-1)),e("div",ye,[e("div",be,[l[44]||(l[44]=e("label",null,"ช่องทาง",-1)),o(e("select",{"onUpdate:modelValue":l[18]||(l[18]=s=>n.channel=s)},[...l[43]||(l[43]=[e("option",{value:"line"},"LINE",-1),e("option",{value:"facebook"},"Facebook",-1)])],512),[[N,n.channel]])]),e("div",ke,[l[46]||(l[46]=e("label",null,"ใครเริ่มคุยก่อน",-1)),o(e("select",{"onUpdate:modelValue":l[19]||(l[19]=s=>n.initiation_mode=s)},[...l[45]||(l[45]=[e("option",{value:"customer"},"ลูกค้าทักก่อน",-1),e("option",{value:"seller"},"เราต้องเริ่มขาย (เชิงรุก)",-1)])],512),[[N,n.initiation_mode]])])]),n.special?(m(),f("label",ce,"พิเศษ: "+i(n.special),1)):_("",!0)]),e("div",xe,[e("button",{class:"primary",onClick:z,disabled:w.value},i(w.value?"กำลังบันทึก…":"💾 บันทึกบุคคลต้นแบบ"),9,we),e("button",{onClick:l[20]||(l[20]=s=>t.$emit("cancel"))},"ปิด")])]))}},pe=F(Ve,[["__scopeId","data-v-738758fc"]]),Ue={class:"row",style:{"align-items":"center","margin-bottom":"8px"}},$e={style:{margin:"0"}},Ce={class:"row",style:{"margin-left":"auto",gap:"10px"}},Be=["disabled"],_e={key:0,class:"spinner"},Ae={key:0,class:"muted"},je={key:1,class:"error",style:{margin:"12px 0"}},ze={key:2,class:"card empty-state"},Le={class:"grid"},Ne={class:"row",style:{"justify-content":"space-between","align-items":"center"}},Pe={class:"diff"},Se={class:"muted"},Ee={class:"muted"},Te=["onClick"],Fe={class:"modal"},Ge={__name:"GroupEdit",setup(V){const x=R().params.gid,p=k(null),n=k([]),d=k(!1),b=k(""),v=k(null);async function w(){const a=await j.getGroup(x);p.value=a.group,n.value=(await j.listPersonas(x)).personas}function U(a){return n.value.filter(r=>r.tier===a)}function $(a){return B.t(a==="A"?"tierA":a==="B"?"tierB":"tierC")}function z(a){return{A:"tier-a",B:"tier-b",C:"tier-c"}[a]||""}async function t(){d.value=!0,b.value="";try{const a=await j.analyzeGroup(x);n.value=a.personas,await w()}catch(a){b.value=a.message}finally{d.value=!1}}function l(a){v.value=JSON.parse(JSON.stringify(a))}async function s(a){d.value=!0;try{await j.updatePersona(x,v.value.id,a),v.value=null,await w()}catch(r){b.value=r.message}finally{d.value=!1}}return q(w),(a,r)=>{const G=K("router-link");return m(),f("div",null,[A(G,{to:"/training",class:"btn-back"},{default:D(()=>[y("← "+i(c(B).t("training")),1)]),_:1}),e("div",Ue,[e("h2",$e,[A(c(Q),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),y(" "+i(c(B).t("managePersonas")),1)]),e("div",Ce,[e("button",{onClick:t,disabled:d.value,class:"primary"},[d.value?(m(),f("span",_e)):(m(),J(c(W),{key:1,size:18,"stroke-width":1.8})),y(" "+i(d.value?"กำลังสร้าง…":c(B).t("analyze")),1)],8,Be)])]),p.value?(m(),f("p",Ae,[r[2]||(r[2]=y("สินค้า: ",-1)),e("strong",null,i(p.value.title),1)])):_("",!0),b.value?(m(),f("div",je,i(b.value),1)):_("",!0),r[4]||(r[4]=e("div",{class:"card guide"},[e("strong",null,"วิธีใช้หน้านี้"),e("ol",{style:{margin:"8px 0 0","padding-left":"20px","line-height":"1.8"}},[e("li",null,[y("กดปุ่ม "),e("strong",null,"✨ สร้าง/วิเคราะห์บุคคลต้นแบบ"),y(" เพื่อให้ระบบสร้างลูกค้าจำลอง 15 คน (ระดับ A/B/C)")]),e("li",null,[y("แต่ละการ์ดคือลูกค้าจำลอง 1 คน — กด "),e("strong",null,"✏️ แก้ไข"),y(" เพื่อปรับรายละเอียดให้ตรงใจ")]),e("li",null,[y("เมื่อพร้อมให้ผู้ใช้ฝึก กด "),e("strong",null,"เปิดใช้งาน"),y(" (ยังทำในขั้นถัดไป)")])])],-1)),n.value.length===0&&!d.value?(m(),f("div",ze,[...r[3]||(r[3]=[e("strong",null,"ยังไม่มีบุคคลต้นแบบ",-1),e("span",null,'กด "✨ สร้าง/วิเคราะห์บุคคลต้นแบบ" เพื่อให้ระบบสร้างลูกค้าจำลองให้',-1)])])):_("",!0),(m(),f(P,null,S(["A","B","C"],C=>e("div",{key:C,style:{"margin-bottom":"20px"}},[e("h4",null,i($(C)),1),e("div",Le,[(m(!0),f(P,null,S(U(C),g=>(m(),f("div",{key:g.id,class:"card pcard"},[e("div",Ne,[e("strong",null,i(g.name),1),e("span",{class:T(["badge",z(g.tier)])},i(g.tier),3)]),e("div",Pe,[(m(),f(P,null,S(5,L=>e("span",{key:L,class:T(["star",{on:L<=(g.difficulty||1)}])},"★",2)),64))]),e("div",Se,i(g.profession)+" · "+i(g.age_group)+" · "+i(g.location),1),e("div",Ee,i(g.channel)+" · "+i(g.initiation_mode==="seller"?"เริ่มขายเอง":"ลูกค้าทักก่อน"),1),e("button",{class:"edit-btn",onClick:L=>l(g)},[A(c(X),{size:15,"stroke-width":1.8}),y(" "+i(c(B).t("edit")),1)],8,Te)]))),128))])])),64)),v.value?(m(),f("div",{key:3,class:"modal-backdrop",onClick:r[1]||(r[1]=H(C=>v.value=null,["self"]))},[e("div",Fe,[A(pe,{persona:v.value,onSave:s,onCancel:r[0]||(r[0]=C=>v.value=null)},null,8,["persona"])])])):_("",!0)])}}},qe=F(Ge,[["__scopeId","data-v-c682ddb6"]]);export{qe as default}; +`).map(l=>l.trim()).filter(Boolean)}M(()=>x.persona,t=>{Object.assign(n,{name:(t==null?void 0:t.name)||"",difficulty:(t==null?void 0:t.difficulty)??1,tier:(t==null?void 0:t.tier)||"B",profession:(t==null?void 0:t.profession)||"",age_group:(t==null?void 0:t.age_group)||"",location:(t==null?void 0:t.location)||"",income:(t==null?void 0:t.income)||"",budget:(t==null?void 0:t.budget)||"",lifestyle:(t==null?void 0:t.lifestyle)||"",background:(t==null?void 0:t.background)||"",personality:(t==null?void 0:t.personality)||"",communication_style:(t==null?void 0:t.communication_style)||"",goal:(t==null?void 0:t.goal)||"",decision_timeline:(t==null?void 0:t.decision_timeline)||"",opener:(t==null?void 0:t.opener)||"",channel:(t==null?void 0:t.channel)||"line",initiation_mode:(t==null?void 0:t.initiation_mode)||"customer",special:(t==null?void 0:t.special)||""}),d.value=U(t==null?void 0:t.pains),b.value=U(t==null?void 0:t.objections),v.value=U(t==null?void 0:t.negotiation_levers)},{immediate:!0});function j(){p("save",{...n,pains:$(d.value),objections:$(b.value),negotiation_levers:$(v.value)})}return(t,l)=>(m(),f("div",Y,[e("h3",null,i(V.persona.name||"New persona"),1),e("p",Z,i(V.persona.profession)+" · "+i(V.persona.personality),1),e("div",h,[l[28]||(l[28]=e("h4",null,"👤 ข้อมูลพื้นฐาน",-1)),e("div",ee,[e("div",le,[l[21]||(l[21]=e("label",null,"ชื่อ",-1)),o(e("input",{"onUpdate:modelValue":l[0]||(l[0]=s=>n.name=s)},null,512),[[u,n.name]])]),e("div",te,[l[22]||(l[22]=e("label",null,"ระดับความยาก (1-5)",-1)),o(e("input",{"onUpdate:modelValue":l[1]||(l[1]=s=>n.difficulty=s),type:"number",min:"1",max:"5"},null,512),[[u,n.difficulty,void 0,{number:!0}]])]),e("div",ne,[l[24]||(l[24]=e("label",null,"ระดับลูกค้า",-1)),o(e("select",{"onUpdate:modelValue":l[2]||(l[2]=s=>n.tier=s)},[...l[23]||(l[23]=[e("option",{value:"A"},"A — พร้อมตัดสินใจซื้อ",-1),e("option",{value:"B"},"B — ยังไม่แน่ใจ",-1),e("option",{value:"C"},"C — ไม่สนใจแต่มีปัญหา",-1)])],512),[[N,n.tier]])])]),e("div",se,[e("div",oe,[l[25]||(l[25]=e("label",null,"อาชีพ",-1)),o(e("input",{"onUpdate:modelValue":l[3]||(l[3]=s=>n.profession=s)},null,512),[[u,n.profession]])]),e("div",ie,[l[26]||(l[26]=e("label",null,"ช่วงอายุ",-1)),o(e("input",{"onUpdate:modelValue":l[4]||(l[4]=s=>n.age_group=s)},null,512),[[u,n.age_group]])]),e("div",ae,[l[27]||(l[27]=e("label",null,"พื้นที่",-1)),o(e("input",{"onUpdate:modelValue":l[5]||(l[5]=s=>n.location=s)},null,512),[[u,n.location]])])])]),e("div",ue,[l[32]||(l[32]=e("h4",null,"💼 ข้อมูลลูกค้า",-1)),e("div",re,[e("div",de,[l[29]||(l[29]=e("label",null,"รายได้/สถานะการเงิน",-1)),o(e("input",{"onUpdate:modelValue":l[6]||(l[6]=s=>n.income=s)},null,512),[[u,n.income]])]),e("div",me,[l[30]||(l[30]=e("label",null,"งบประมาณ",-1)),o(e("input",{"onUpdate:modelValue":l[7]||(l[7]=s=>n.budget=s)},null,512),[[u,n.budget]])]),e("div",ve,[l[31]||(l[31]=e("label",null,"ไลฟ์สไตล์",-1)),o(e("input",{"onUpdate:modelValue":l[8]||(l[8]=s=>n.lifestyle=s)},null,512),[[u,n.lifestyle]])])]),l[33]||(l[33]=e("label",null,"ภูมิหลัง",-1)),o(e("textarea",{"onUpdate:modelValue":l[9]||(l[9]=s=>n.background=s)},null,512),[[u,n.background]]),l[34]||(l[34]=e("label",null,"บุคลิก / วิธีพูดคุย",-1)),o(e("textarea",{"onUpdate:modelValue":l[10]||(l[10]=s=>n.personality=s)},null,512),[[u,n.personality]]),l[35]||(l[35]=e("label",null,"สไตล์การสื่อสาร",-1)),o(e("textarea",{"onUpdate:modelValue":l[11]||(l[11]=s=>n.communication_style=s)},null,512),[[u,n.communication_style]])]),e("div",fe,[l[36]||(l[36]=e("h4",null,"🎯 การขาย",-1)),l[37]||(l[37]=e("label",null,"เป้าหมาย",-1)),o(e("textarea",{"onUpdate:modelValue":l[12]||(l[12]=s=>n.goal=s)},null,512),[[u,n.goal]]),l[38]||(l[38]=e("label",null,"กรอบเวลาในการตัดสินใจ",-1)),o(e("input",{"onUpdate:modelValue":l[13]||(l[13]=s=>n.decision_timeline=s)},null,512),[[u,n.decision_timeline]]),l[39]||(l[39]=e("label",null,"Pain (ปัญหา) แบบ 1 ต่อบรรทัด",-1)),o(e("textarea",{"onUpdate:modelValue":l[14]||(l[14]=s=>d.value=s),placeholder:`เช่น ต้นทุนสูงเกินไป +ระบบล้าสมัย`},null,512),[[u,d.value]]),l[40]||(l[40]=e("label",null,"ข้อโต้แย้ง (Objections) 1 ต่อบรรทัด",-1)),o(e("textarea",{"onUpdate:modelValue":l[15]||(l[15]=s=>b.value=s)},null,512),[[u,b.value]]),l[41]||(l[41]=e("label",null,"สิ่งที่ใช้ต่อรอง (เช่น ส่วนลด, ฟรีติดตั้ง)",-1)),o(e("textarea",{"onUpdate:modelValue":l[16]||(l[16]=s=>v.value=s)},null,512),[[u,v.value]]),l[42]||(l[42]=e("label",null,"ช่องทางสำหรับลูกค้าเปิดบทสนทนา (opener)",-1)),o(e("textarea",{"onUpdate:modelValue":l[17]||(l[17]=s=>n.opener=s)},null,512),[[u,n.opener]])]),e("div",ge,[l[47]||(l[47]=e("h4",null,"📡 ช่องทาง & โหมด",-1)),e("div",ye,[e("div",be,[l[44]||(l[44]=e("label",null,"ช่องทาง",-1)),o(e("select",{"onUpdate:modelValue":l[18]||(l[18]=s=>n.channel=s)},[...l[43]||(l[43]=[e("option",{value:"line"},"LINE",-1),e("option",{value:"facebook"},"Facebook",-1)])],512),[[N,n.channel]])]),e("div",ke,[l[46]||(l[46]=e("label",null,"ใครเริ่มคุยก่อน",-1)),o(e("select",{"onUpdate:modelValue":l[19]||(l[19]=s=>n.initiation_mode=s)},[...l[45]||(l[45]=[e("option",{value:"customer"},"ลูกค้าทักก่อน",-1),e("option",{value:"seller"},"เราต้องเริ่มขาย (เชิงรุก)",-1)])],512),[[N,n.initiation_mode]])])]),n.special?(m(),f("label",ce,"พิเศษ: "+i(n.special),1)):_("",!0)]),e("div",xe,[e("button",{class:"primary",onClick:j,disabled:w.value},i(w.value?"กำลังบันทึก…":"💾 บันทึกบุคคลต้นแบบ"),9,we),e("button",{onClick:l[20]||(l[20]=s=>t.$emit("cancel"))},"ปิด")])]))}},pe=F(Ve,[["__scopeId","data-v-738758fc"]]),Ue={class:"row",style:{"align-items":"center","margin-bottom":"8px"}},$e={style:{margin:"0"}},Ce={class:"row",style:{"margin-left":"auto",gap:"10px"}},Be=["disabled"],_e={key:0,class:"spinner"},ze={key:0,class:"muted"},Ae={key:1,class:"error",style:{margin:"12px 0"}},je={key:2,class:"card empty-state"},Le={class:"grid"},Ne={class:"row",style:{"justify-content":"space-between","align-items":"center"}},Pe={class:"diff"},Se={class:"muted"},Ee={class:"muted"},Te=["onClick"],Fe={class:"modal"},Ge={__name:"GroupEdit",setup(V){const x=R().params.gid,p=k(null),n=k([]),d=k(!1),b=k(""),v=k(null);async function w(){const a=await A.getGroup(x);p.value=a.group,n.value=(await A.listPersonas(x)).personas}function U(a){return n.value.filter(r=>r.tier===a)}function $(a){return B.t(a==="A"?"tierA":a==="B"?"tierB":"tierC")}function j(a){return{A:"tier-a",B:"tier-b",C:"tier-c"}[a]||""}async function t(){d.value=!0,b.value="";try{const a=await A.analyzeGroup(x);n.value=a.personas,await w()}catch(a){b.value=a.message}finally{d.value=!1}}function l(a){v.value=JSON.parse(JSON.stringify(a))}async function s(a){d.value=!0;try{await A.updatePersona(x,v.value.id,a),v.value=null,await w()}catch(r){b.value=r.message}finally{d.value=!1}}return D(w),(a,r)=>{const G=K("router-link");return m(),f("div",null,[z(G,{to:"/training",class:"btn-back"},{default:J(()=>[y("← "+i(c(B).t("training")),1)]),_:1}),e("div",Ue,[e("h2",$e,[z(c(Q),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),y(" "+i(c(B).t("managePersonas")),1)]),e("div",Ce,[e("button",{onClick:t,disabled:d.value,class:"primary"},[d.value?(m(),f("span",_e)):(m(),q(c(W),{key:1,size:18,"stroke-width":1.8})),y(" "+i(d.value?"กำลังสร้าง…":c(B).t("analyze")),1)],8,Be)])]),p.value?(m(),f("p",ze,[r[2]||(r[2]=y("สินค้า: ",-1)),e("strong",null,i(p.value.title),1)])):_("",!0),b.value?(m(),f("div",Ae,i(b.value),1)):_("",!0),r[4]||(r[4]=e("div",{class:"card guide"},[e("strong",null,"วิธีใช้หน้านี้"),e("ol",{style:{margin:"8px 0 0","padding-left":"20px","line-height":"1.8"}},[e("li",null,[y("กดปุ่ม "),e("strong",null,"✨ สร้าง/วิเคราะห์บุคคลต้นแบบ"),y(" เพื่อให้ระบบสร้างลูกค้าจำลอง 15 คน (ระดับ A/B/C)")]),e("li",null,[y("แต่ละการ์ดคือลูกค้าจำลอง 1 คน — กด "),e("strong",null,"✏️ แก้ไข"),y(" เพื่อปรับรายละเอียดให้ตรงใจ")]),e("li",null,[y("เมื่อพร้อมให้ผู้ใช้ฝึก กด "),e("strong",null,"เปิดใช้งาน"),y(" (ยังทำในขั้นถัดไป)")])])],-1)),n.value.length===0&&!d.value?(m(),f("div",je,[...r[3]||(r[3]=[e("strong",null,"ยังไม่มีบุคคลต้นแบบ",-1),e("span",null,'กด "✨ สร้าง/วิเคราะห์บุคคลต้นแบบ" เพื่อให้ระบบสร้างลูกค้าจำลองให้',-1)])])):_("",!0),(m(),f(P,null,S(["A","B","C"],C=>e("div",{key:C,style:{"margin-bottom":"20px"}},[e("h4",null,i($(C)),1),e("div",Le,[(m(!0),f(P,null,S(U(C),g=>(m(),f("div",{key:g.id,class:"card pcard"},[e("div",Ne,[e("strong",null,i(g.name),1),e("span",{class:T(["badge",j(g.tier)])},i(g.tier),3)]),e("div",Pe,[(m(),f(P,null,S(5,L=>e("span",{key:L,class:T(["star",{on:L<=(g.difficulty||1)}])},"★",2)),64))]),e("div",Se,i(g.profession)+" · "+i(g.age_group)+" · "+i(g.location),1),e("div",Ee,i(g.channel)+" · "+i(g.initiation_mode==="seller"?"เริ่มขายเอง":"ลูกค้าทักก่อน"),1),e("button",{class:"edit-btn",onClick:L=>l(g)},[z(c(X),{size:15,"stroke-width":1.8}),y(" "+i(c(B).t("edit")),1)],8,Te)]))),128))])])),64)),v.value?(m(),f("div",{key:3,class:"modal-backdrop",onClick:r[1]||(r[1]=H(C=>v.value=null,["self"]))},[e("div",Fe,[z(pe,{persona:v.value,onSave:s,onCancel:r[0]||(r[0]=C=>v.value=null)},null,8,["persona"])])])):_("",!0)])}}},De=F(Ge,[["__scopeId","data-v-c682ddb6"]]);export{De as default}; diff --git a/frontend/dist/assets/Guide-D6Cvcccc.js b/frontend/dist/assets/Guide-GzVXirX-.js similarity index 93% rename from frontend/dist/assets/Guide-D6Cvcccc.js rename to frontend/dist/assets/Guide-GzVXirX-.js index b62237d..c44e321 100644 --- a/frontend/dist/assets/Guide-D6Cvcccc.js +++ b/frontend/dist/assets/Guide-GzVXirX-.js @@ -1,6 +1,6 @@ -import{k as e,c as o,a as l,m as n,u as i,j as s,t as r,i as a,D as u,o as d}from"./index-C0_i8cDF.js";import{B as g}from"./book-open-E7lWrK45.js";import{L as p}from"./layout-dashboard-C4nLoaIz.js";import{T as m}from"./target-DoOGVGr0.js";import{S as y}from"./sparkles-D66jVNJm.js";/** +import{c as e,a as o,b as l,l as n,u as i,m as s,t as r,i as a,D as u,o as d}from"./index-DOaJiTJw.js";import{B as g}from"./book-open-Ckxqlz0w.js";import{L as p}from"./layout-dashboard-CmUmS5d8.js";import{T as m}from"./target-QJk_fUDu.js";import{S as y}from"./sparkles-CwNig9QR.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 h=e("wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]]),k={class:"card"},v={style:{"margin-top":"0"}},x={class:"card"},f={style:{"margin-top":"0"}},c={class:"card"},w={style:{"margin-top":"0"}},z={class:"card"},_={style:{"margin-top":"0"}},b={__name:"Guide",setup(B){return(S,t)=>(d(),o("div",null,[l("h2",null,[n(i(g),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),s(" "+r(i(a).t("guideTitle")),1)]),t[8]||(t[8]=l("p",{class:"muted"},"คู่มือสั้นๆ สำหรับพนักงานใหม่ — เข้าใจระบบได้ใน 5 นาที",-1)),l("div",k,[l("h3",v,[n(i(p),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[0]||(t[0]=s(" 1. หน้า 3 แท็บ (menu ด้านบน)",-1))]),t[1]||(t[1]=l("ul",{style:{"line-height":"1.9"}},[l("li",null,[l("strong",null,"ภาพรวมผู้ดูแล"),s(" — เฉพาะ admin ดูสถิติผลการฝึกของทีม + กรองตามช่วงเวลา")]),l("li",null,[l("strong",null,"ภาพรวมผลการฝึก"),s(" — ของตัวคุณเอง: ชนะ/แพ้/ยังไม่ได้ฝึก")]),l("li",null,[l("strong",null,"การฝึก"),s(" — เลือกสินค้า → เลือกลูกค้า (บุคคลต้นแบบ) → เริ่มแชท")]),l("li",null,[l("strong",null,"การตั้งค่า (⚙︎)"),s(" — แก้ชื่อ/อีเมล, เปลี่ยนรหัสผ่าน, เปลี่ยนภาษา")])],-1))]),l("div",x,[l("h3",f,[n(i(m),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[2]||(t[2]=s(" 2. วิธีฝึก (start a session)",-1))]),t[3]||(t[3]=l("ol",{style:{"line-height":"1.9","padding-left":"20px"}},[l("li",null,[s("เข้าแท็บ "),l("strong",null,"การฝึก"),s(" → เลือกสินค้าที่อยากฝึก")]),l("li",null,"เลือกลูกค้า (บุคคลต้นแบบ) — ระดับ A ง่ายสุด / C ยากสุด (ดูดาวความยาก)"),l("li",null,[s("เลือก "),l("strong",null,"สถานการณ์"),s(": โซเชียล (ลูกค้าทักก่อน) / พบหน้า-โทร (คุณทักก่อน) / กลับมาติดต่อ")]),l("li",null,"แชทกับลูกค้า — ฝึกปิดการขาย ลูกค้าจะตัดสินใจเองว่าซื้อหรือไม่ซื้อ"),l("li",null,"หลังจบ ดูผล + ข้อเสนอแนะ + ข้อมูลลูกค้าที่ถูกซ่อนไว้")],-1))]),l("div",c,[l("h3",w,[n(i(y),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[4]||(t[4]=s(" 3. เคล็ดลับ",-1))]),t[5]||(t[5]=l("ul",{style:{"line-height":"1.9"}},[l("li",null,[s('ลูกค้าแต่ละคน หรือ "บุคคลต้นแบบ" ฝึกได้ '),l("strong",null,"คนละครั้ง"),s(" (one-shot) — ฝึกจนจบแล้วลองคนอื่น")]),l("li",null,"ถ้าออกกลางคัน กลับมาได้ คุยต่อจากเดิม (ยังไม่นับว่าจบ)"),l("li",null,"ปิดการขาย = แก้ปัญหาจริงของลูกค้า + รับมือข้อโต้แย้ง + ปิดราคา")],-1))]),l("div",z,[l("h3",_,[n(i(h),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[6]||(t[6]=s(" 4. สำหรับ Admin",-1))]),t[7]||(t[7]=u('',1))])]))}};export{b as default}; + */const h=e("wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]]),k={class:"card"},v={style:{"margin-top":"0"}},x={class:"card"},f={style:{"margin-top":"0"}},c={class:"card"},w={style:{"margin-top":"0"}},z={class:"card"},_={style:{"margin-top":"0"}},L={__name:"Guide",setup(B){return(S,t)=>(d(),o("div",null,[l("h2",null,[n(i(g),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),s(" "+r(i(a).t("guideTitle")),1)]),t[8]||(t[8]=l("p",{class:"muted"},"คู่มือสั้นๆ สำหรับพนักงานใหม่ — เข้าใจระบบได้ใน 5 นาที",-1)),l("div",k,[l("h3",v,[n(i(p),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[0]||(t[0]=s(" 1. หน้า 3 แท็บ (menu ด้านบน)",-1))]),t[1]||(t[1]=l("ul",{style:{"line-height":"1.9"}},[l("li",null,[l("strong",null,"ภาพรวมผู้ดูแล"),s(" — เฉพาะ admin ดูสถิติผลการฝึกของทีม + กรองตามช่วงเวลา")]),l("li",null,[l("strong",null,"ภาพรวมผลการฝึก"),s(" — ของตัวคุณเอง: ชนะ/แพ้/ยังไม่ได้ฝึก")]),l("li",null,[l("strong",null,"การฝึก"),s(" — เลือกสินค้า → เลือกลูกค้า (บุคคลต้นแบบ) → เริ่มแชท")]),l("li",null,[l("strong",null,"การตั้งค่า (⚙︎)"),s(" — แก้ชื่อ/อีเมล, เปลี่ยนรหัสผ่าน, เปลี่ยนภาษา")])],-1))]),l("div",x,[l("h3",f,[n(i(m),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[2]||(t[2]=s(" 2. วิธีฝึก (start a session)",-1))]),t[3]||(t[3]=l("ol",{style:{"line-height":"1.9","padding-left":"20px"}},[l("li",null,[s("เข้าแท็บ "),l("strong",null,"การฝึก"),s(" → เลือกสินค้าที่อยากฝึก")]),l("li",null,"เลือกลูกค้า (บุคคลต้นแบบ) — ระดับ A ง่ายสุด / C ยากสุด (ดูดาวความยาก)"),l("li",null,[s("เลือก "),l("strong",null,"สถานการณ์"),s(": โซเชียล (ลูกค้าทักก่อน) / พบหน้า-โทร (คุณทักก่อน) / กลับมาติดต่อ")]),l("li",null,"แชทกับลูกค้า — ฝึกปิดการขาย ลูกค้าจะตัดสินใจเองว่าซื้อหรือไม่ซื้อ"),l("li",null,"หลังจบ ดูผล + ข้อเสนอแนะ + ข้อมูลลูกค้าที่ถูกซ่อนไว้")],-1))]),l("div",c,[l("h3",w,[n(i(y),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[4]||(t[4]=s(" 3. เคล็ดลับ",-1))]),t[5]||(t[5]=l("ul",{style:{"line-height":"1.9"}},[l("li",null,[s('ลูกค้าแต่ละคน หรือ "บุคคลต้นแบบ" ฝึกได้ '),l("strong",null,"คนละครั้ง"),s(" (one-shot) — ฝึกจนจบแล้วลองคนอื่น")]),l("li",null,"ถ้าออกกลางคัน กลับมาได้ คุยต่อจากเดิม (ยังไม่นับว่าจบ)"),l("li",null,"ปิดการขาย = แก้ปัญหาจริงของลูกค้า + รับมือข้อโต้แย้ง + ปิดราคา")],-1))]),l("div",z,[l("h3",_,[n(i(h),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),t[6]||(t[6]=s(" 4. สำหรับ Admin",-1))]),t[7]||(t[7]=u('',1))])]))}};export{L as default}; diff --git a/frontend/dist/assets/Login-D3svPLnW.css b/frontend/dist/assets/Login-D3svPLnW.css deleted file mode 100644 index 16bdd37..0000000 --- a/frontend/dist/assets/Login-D3svPLnW.css +++ /dev/null @@ -1 +0,0 @@ -.login-wrap[data-v-f7904d9f]{display:flex;justify-content:center;padding-top:10vh}.login-card[data-v-f7904d9f]{width:360px}h1[data-v-f7904d9f]{margin-top:0}.pw-wrap[data-v-f7904d9f]{position:relative}.pw-toggle[data-v-f7904d9f]{position:absolute;right:4px;top:50%;transform:translateY(-50%);background:transparent;border:none;padding:6px;min-height:36px;cursor:pointer} diff --git a/frontend/dist/assets/Login-DxHA8GYa.js b/frontend/dist/assets/Login-DxHA8GYa.js new file mode 100644 index 0000000..767fdfd --- /dev/null +++ b/frontend/dist/assets/Login-DxHA8GYa.js @@ -0,0 +1,11 @@ +import{c as k,_ as x,a as y,b as e,t as l,u as a,i as n,w as h,v as M,d as w,e as B,f as _,g as E,r,h as f,j as S,k as V,o as s}from"./index-DOaJiTJw.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 z=k("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);/** + * @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 C=k("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]),D={class:"login-wrap"},K={class:"card login-card"},L={class:"pw-wrap"},j=["type"],I=["aria-label"],N={key:0,class:"error",role:"alert"},R=["disabled"],U={key:0,class:"spinner"},q={key:1},H={__name:"Login",setup(O){const g=V(),m=S(),u=r(""),i=r(""),o=r(!1),d=r(""),c=r(!1);async function v(){d.value="",c.value=!0;try{await f.login(u.value.trim(),i.value),f.mustSetup?m.push({path:"/setup"}):m.push(g.query.redirect||"/")}catch{d.value=n.t("loginError")}finally{c.value=!1}}return(b,t)=>(s(),y("div",D,[e("div",K,[e("h1",null,l(a(n).t("app")),1),t[3]||(t[3]=e("p",{class:"muted",style:{"margin-top":"-8px"}},"Sales training simulator",-1)),e("label",null,l(a(n).t("username")),1),h(e("input",{"onUpdate:modelValue":t[0]||(t[0]=p=>u.value=p),type:"text",autocomplete:"username",placeholder:"username",class:"wide",onKeyup:w(v,["enter"])},null,544),[[M,u.value]]),e("label",null,l(a(n).t("password")),1),e("div",L,[h(e("input",{"onUpdate:modelValue":t[1]||(t[1]=p=>i.value=p),type:o.value?"text":"password",autocomplete:"current-password",placeholder:"••••••••",class:"wide",onKeyup:w(v,["enter"])},null,40,j),[[B,i.value]]),e("button",{type:"button",class:"pw-toggle",onClick:t[2]||(t[2]=p=>o.value=!o.value),"aria-label":o.value?"Hide password":"Show password"},[o.value?(s(),_(a(z),{key:0,size:20,"stroke-width":1.8})):(s(),_(a(C),{key:1,size:20,"stroke-width":1.8}))],8,I)]),d.value?(s(),y("div",N,l(d.value),1)):E("",!0),e("button",{class:"primary",style:{width:"100%","margin-top":"18px"},disabled:c.value||!u.value||!i.value,onClick:v},[c.value?(s(),y("span",U)):(s(),y("span",q,l(a(n).t("login")),1))],8,R)])]))}},T=x(H,[["__scopeId","data-v-491f49d6"]]);export{T as default}; diff --git a/frontend/dist/assets/Login-j4sHK_z1.css b/frontend/dist/assets/Login-j4sHK_z1.css new file mode 100644 index 0000000..89f27d5 --- /dev/null +++ b/frontend/dist/assets/Login-j4sHK_z1.css @@ -0,0 +1 @@ +.login-wrap[data-v-491f49d6]{display:flex;justify-content:center;padding-top:8vh;padding-left:16px;padding-right:16px}.login-card[data-v-491f49d6]{width:460px;max-width:100%;padding:28px 30px}h1[data-v-491f49d6]{margin-top:0;font-size:24px}.wide[data-v-491f49d6]{width:100%;min-height:46px;font-size:15px;padding:12px 14px}.pw-wrap[data-v-491f49d6]{position:relative}.pw-wrap input[data-v-491f49d6]{padding-right:48px}.pw-toggle[data-v-491f49d6]{position:absolute;right:4px;top:50%;transform:translateY(-50%);background:transparent;border:none;padding:8px;min-height:40px;cursor:pointer;color:var(--muted)}.pw-toggle[data-v-491f49d6]:hover{color:var(--ink)} diff --git a/frontend/dist/assets/Login-vrbZzr6f.js b/frontend/dist/assets/Login-vrbZzr6f.js deleted file mode 100644 index 9c1e492..0000000 --- a/frontend/dist/assets/Login-vrbZzr6f.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as b,c as d,a as e,t as s,u as c,i as o,w as y,v as x,b as w,d as k,e as S,r as l,f,g as V,h as B,o as v}from"./index-C0_i8cDF.js";const C={class:"login-wrap"},D={class:"card login-card"},K={class:"pw-wrap"},E=["type"],L=["aria-label"],M={key:0,class:"error",role:"alert"},N=["disabled"],R={key:0,class:"spinner"},U={key:1},q={__name:"Login",setup(H){const g=B(),_=V(),n=l(""),u=l(""),a=l(!1),r=l(""),i=l(!1);async function m(){r.value="",i.value=!0;try{await f.login(n.value.trim(),u.value),f.mustSetup?_.push({path:"/setup"}):_.push(g.query.redirect||"/")}catch{r.value=o.t("loginError")}finally{i.value=!1}}return(h,t)=>(v(),d("div",C,[e("div",D,[e("h1",null,"🎯 "+s(c(o).t("app")),1),t[3]||(t[3]=e("p",{class:"muted",style:{"margin-top":"-8px"}},"Sales training simulator",-1)),e("label",null,s(c(o).t("username")),1),y(e("input",{"onUpdate:modelValue":t[0]||(t[0]=p=>n.value=p),type:"text",autocomplete:"username",onKeyup:w(m,["enter"])},null,544),[[x,n.value]]),e("label",null,s(c(o).t("password")),1),e("div",K,[y(e("input",{"onUpdate:modelValue":t[1]||(t[1]=p=>u.value=p),type:a.value?"text":"password",autocomplete:"current-password",onKeyup:w(m,["enter"])},null,40,E),[[k,u.value]]),e("button",{type:"button",class:"pw-toggle",onClick:t[2]||(t[2]=p=>a.value=!a.value),"aria-label":a.value?"Hide password":"Show password"},s(a.value?"🙈":"👁"),9,L)]),r.value?(v(),d("div",M,s(r.value),1)):S("",!0),e("button",{class:"primary",style:{width:"100%","margin-top":"16px"},disabled:i.value||!n.value||!u.value,onClick:m},[i.value?(v(),d("span",R)):(v(),d("span",U,s(c(o).t("login")),1))],8,N)])]))}},P=b(q,[["__scopeId","data-v-f7904d9f"]]);export{P as default}; diff --git a/frontend/dist/assets/MyBoard-UPzqfwhQ.js b/frontend/dist/assets/MyBoard-CTHsz6OL.js similarity index 60% rename from frontend/dist/assets/MyBoard-UPzqfwhQ.js rename to frontend/dist/assets/MyBoard-CTHsz6OL.js index ff68d42..2b50eb2 100644 --- a/frontend/dist/assets/MyBoard-UPzqfwhQ.js +++ b/frontend/dist/assets/MyBoard-CTHsz6OL.js @@ -1 +1 @@ -import{_ as f,l as x,s as v,c as r,a as t,m as b,u as e,j as k,t as s,i as a,e as _,w as B,y as N,F as D,q as S,r as p,z as c,o as i,A as T}from"./index-C0_i8cDF.js";import{L as V}from"./layout-dashboard-C4nLoaIz.js";const z={style:{margin:"0"}},L={key:0,class:"row stat-row"},M={class:"card stat"},j={class:"card stat won"},C={class:"card stat lost"},F={class:"card stat"},q={key:1,class:"card"},A={key:2,class:"card empty-state"},E={class:"card",style:{"margin-top":"20px"}},G={style:{"margin-top":"0"}},I={__name:"MyBoard",setup(H){const o=p([]),u=p([]),m=p(!0),y=c(()=>o.value.length),g=c(()=>o.value.filter(n=>n.my_outcome==="won").length),h=c(()=>o.value.filter(n=>n.my_outcome==="lost").length),w=c(()=>o.value.filter(n=>n.my_outcome==="not_tried").length);return x(async()=>{try{o.value=(await v.myBoard()).board||[],u.value=(await v.mySessions()).sessions||[]}finally{m.value=!1}}),(n,l)=>(i(),r("div",null,[t("div",null,[t("h2",z,[b(e(V),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),k(" "+s(e(a).t("myDashboard")),1)]),l[0]||(l[0]=t("div",{class:"muted",style:{"margin-top":"4px","margin-bottom":"16px"}},"สรุปผลการฝึกของตัวคุณเอง — ดูว่าปิดการขายได้กี่ครั้ง ยังฝึกกับใครบ้าง",-1))]),m.value?_("",!0):(i(),r("div",L,[t("div",M,[t("span",null,s(e(a).t("total")),1),t("strong",null,s(y.value),1)]),t("div",j,[t("span",null,s(e(a).t("won")),1),t("strong",null,s(g.value),1)]),t("div",C,[t("span",null,s(e(a).t("lost")),1),t("strong",null,s(h.value),1)]),t("div",F,[t("span",null,s(e(a).t("notTried")),1),t("strong",null,s(w.value),1)])])),m.value?(i(),r("div",q,[...l[1]||(l[1]=[t("div",{class:"skeleton",style:{height:"50px"}},null,-1)])])):o.value.length===0?(i(),r("div",A,[...l[2]||(l[2]=[t("strong",null,"No practice yet",-1),t("span",null,"Go to Training and try closing a sale with a persona.",-1)])])):_("",!0),B(t("div",E,[t("h3",G,s(e(a).t("mySessions")),1),(i(!0),r(D,null,S(u.value,d=>(i(),r("div",{key:d.id,style:{display:"flex","justify-content":"space-between",padding:"8px 0","border-bottom":"1px solid var(--border)"}},[t("span",null,s(d.persona_name),1),t("span",{class:T(["badge",d.outcome])},s(d.outcome==="won"?e(a).t("won"):e(a).t("lost")),3)]))),128))],512),[[N,u.value.length]])]))}},O=f(I,[["__scopeId","data-v-6767b6b8"]]);export{O as default}; +import{_ as f,n as x,x as v,a as r,b as t,l as b,u as e,m as k,t as s,i as a,g as _,w as B,z as N,F as D,s as S,r as p,A as c,o as i,B as T}from"./index-DOaJiTJw.js";import{L as V}from"./layout-dashboard-CmUmS5d8.js";const z={style:{margin:"0"}},L={key:0,class:"row stat-row"},M={class:"card stat"},C={class:"card stat won"},F={class:"card stat lost"},j={class:"card stat"},A={key:1,class:"card"},E={key:2,class:"card empty-state"},G={class:"card",style:{"margin-top":"20px"}},I={style:{"margin-top":"0"}},q={__name:"MyBoard",setup(H){const o=p([]),u=p([]),m=p(!0),y=c(()=>o.value.length),g=c(()=>o.value.filter(n=>n.my_outcome==="won").length),h=c(()=>o.value.filter(n=>n.my_outcome==="lost").length),w=c(()=>o.value.filter(n=>n.my_outcome==="not_tried").length);return x(async()=>{try{o.value=(await v.myBoard()).board||[],u.value=(await v.mySessions()).sessions||[]}finally{m.value=!1}}),(n,l)=>(i(),r("div",null,[t("div",null,[t("h2",z,[b(e(V),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),k(" "+s(e(a).t("myDashboard")),1)]),l[0]||(l[0]=t("div",{class:"muted",style:{"margin-top":"4px","margin-bottom":"16px"}},"สรุปผลการฝึกของตัวคุณเอง — ดูว่าปิดการขายได้กี่ครั้ง ยังฝึกกับใครบ้าง",-1))]),m.value?_("",!0):(i(),r("div",L,[t("div",M,[t("span",null,s(e(a).t("total")),1),t("strong",null,s(y.value),1)]),t("div",C,[t("span",null,s(e(a).t("won")),1),t("strong",null,s(g.value),1)]),t("div",F,[t("span",null,s(e(a).t("lost")),1),t("strong",null,s(h.value),1)]),t("div",j,[t("span",null,s(e(a).t("notTried")),1),t("strong",null,s(w.value),1)])])),m.value?(i(),r("div",A,[...l[1]||(l[1]=[t("div",{class:"skeleton",style:{height:"50px"}},null,-1)])])):o.value.length===0?(i(),r("div",E,[...l[2]||(l[2]=[t("strong",null,"No practice yet",-1),t("span",null,"Go to Training and try closing a sale with a persona.",-1)])])):_("",!0),B(t("div",G,[t("h3",I,s(e(a).t("mySessions")),1),(i(!0),r(D,null,S(u.value,d=>(i(),r("div",{key:d.id,style:{display:"flex","justify-content":"space-between",padding:"8px 0","border-bottom":"1px solid var(--border)"}},[t("span",null,s(d.persona_name),1),t("span",{class:T(["badge",d.outcome])},s(d.outcome==="won"?e(a).t("won"):e(a).t("lost")),3)]))),128))],512),[[N,u.value.length]])]))}},O=f(q,[["__scopeId","data-v-6767b6b8"]]);export{O as default}; diff --git a/frontend/dist/assets/Personas-Dl-F3CRY.js b/frontend/dist/assets/Personas-CGSsKXxA.js similarity index 72% rename from frontend/dist/assets/Personas-Dl-F3CRY.js rename to frontend/dist/assets/Personas-CGSsKXxA.js index 7afacc8..c6a9bb2 100644 --- a/frontend/dist/assets/Personas-Dl-F3CRY.js +++ b/frontend/dist/assets/Personas-CGSsKXxA.js @@ -1 +1 @@ -import{_ as T,l as $,c as r,m as d,n as m,a as t,t as s,u as e,i as n,f as g,j as _,e as w,F as y,q as p,h as L,s as N,x as V,r as b,o as a,S as I,A as h,B as A}from"./index-C0_i8cDF.js";import{T as S}from"./target-DoOGVGr0.js";import{A as j}from"./arrow-left-neyuEczm.js";const F={class:"row",style:{"align-items":"center"}},q={style:{margin:"0"}},D={class:"muted",style:{"margin-left":"auto"}},E={key:0,class:"card guide"},M={key:1,class:"row",style:{margin:"12px 0",gap:"10px"}},R={class:"primary"},G={class:"grid"},H={class:"row",style:{"justify-content":"space-between"}},J={class:"diff"},K={class:"muted"},O={class:"muted"},Q={class:"muted"},U={class:"muted",style:{"margin-top":"6px"}},W={class:"primary",style:{width:"100%"}},X={class:"primary",style:{width:"100%"}},Y={key:1,class:"muted",style:{"margin-top":"auto","font-size":"12px"}},Z={__name:"Personas",setup(tt){const c=L().params.gid,k=b([]),B=b(!0);async function C(){try{k.value=(await N.listPersonas(c)).personas}finally{B.value=!1}}function z(l){return k.value.filter(i=>i.tier===l)}function P(l){return n.t(l==="A"?"tierA":l==="B"?"tierB":"tierC")}function v(l){return l==="won"?n.t("won"):l==="lost"?n.t("lost"):n.t("notTried")}return $(C),(l,i)=>{const u=V("router-link");return a(),r("div",null,[d(u,{to:"/training",class:"btn-back"},{default:m(()=>[d(e(j),{size:16,"stroke-width":2}),_(" "+s(e(n).t("training")),1)]),_:1}),t("div",F,[t("h2",q,s(e(n).t("personas")),1),t("span",D,s(e(n).t("selectPersona")),1)]),e(g).isAdmin?w("",!0):(a(),r("div",E,[t("strong",null,[d(e(S),{size:17,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),i[0]||(i[0]=_(" วิธีฝึก",-1))]),i[1]||(i[1]=t("ol",{style:{margin:"8px 0 0","padding-left":"20px","line-height":"1.8"}},[t("li",null,"เลือกลูกค้าจำลอง (บุคคลต้นแบบ) คนหนึ่งที่อยากฝึกด้วย"),t("li",null,"ระดับ A ง่ายสุด → ระดับ C ยากสุด (ดูจากดาว ★ ความยาก)"),t("li",null,"กดปุ่มสำหรับฝึกแชทกับลูกค้าคนนั้น (ฝึกได้คนละครั้งเท่านั้น)")],-1))])),e(g).isAdmin?(a(),r("div",M,[d(u,{to:`/admin/groups/${e(c)}/edit`},{default:m(()=>[t("button",R,[d(e(I),{size:18,"stroke-width":1.8}),_(" "+s(e(n).t("managePersonas")),1)])]),_:1},8,["to"]),i[2]||(i[2]=t("span",{class:"muted"},"Admin: จัดการรายละเอียดบุคคลต้นแบบได้ที่นี่",-1))])):w("",!0),(a(),r(y,null,p(["A","B","C"],f=>t("div",{key:f,style:{margin:"20px 0"}},[t("h4",null,s(P(f)),1),t("div",G,[(a(!0),r(y,null,p(z(f),o=>(a(),r("div",{key:o.id,class:"card pcard lift"},[t("div",H,[t("strong",null,s(o.name),1),t("span",{class:h(["badge",o.my_outcome])},s(v(o.my_outcome)),3)]),t("div",J,[(a(),r(y,null,p(5,x=>t("span",{key:x,class:h(["star",{on:x<=(o.difficulty||1)}])},"★",2)),64)),t("span",K,s(e(n).t("difficulty"))+" "+s(o.difficulty||1)+"/5",1)]),t("div",O,[_(s(o.profession)+" · "+s(o.age_group)+" · "+s(o.location),1),i[3]||(i[3]=t("br",null,null,-1)),t("span",{class:h(["badge",o.channel])},s(o.channel),3),t("span",Q," · "+s(o.initiation_mode==="seller"?e(n).t("sellerInitiated"):e(n).t("customerInitiated")),1)]),t("div",U,s(o.product_context),1),e(g).isAdmin?(a(),A(u,{key:0,to:`/groups/${e(c)}/chat/${o.id}`,style:{"margin-top":"auto"}},{default:m(()=>[t("button",W,s(e(n).t("chat")),1)]),_:1},8,["to"])):(a(),r(y,{key:1},[o.my_outcome==="not_tried"?(a(),A(u,{key:0,to:`/groups/${e(c)}/chat/${o.id}`,style:{"margin-top":"auto"}},{default:m(()=>[t("button",X,s(e(n).t("chat")),1)]),_:1},8,["to"])):(a(),r("div",Y,"✓ "+s(e(n).t("trained"))+" ("+s(v(o.my_outcome))+")",1))],64))]))),128))])])),64))])}}},at=T(Z,[["__scopeId","data-v-46d50c99"]]);export{at as default}; +import{_ as T,n as $,a as r,l as d,p as m,b as t,t as s,u as e,i as n,h as f,m as _,g as w,F as y,s as p,k as L,x as N,y as V,r as b,o as a,S as I,B as h,f as A}from"./index-DOaJiTJw.js";import{T as S}from"./target-QJk_fUDu.js";import{A as F}from"./arrow-left-BUCak2lw.js";const j={class:"row",style:{"align-items":"center"}},D={style:{margin:"0"}},E={class:"muted",style:{"margin-left":"auto"}},M={key:0,class:"card guide"},R={key:1,class:"row",style:{margin:"12px 0",gap:"10px"}},q={class:"primary"},G={class:"grid"},H={class:"row",style:{"justify-content":"space-between"}},J={class:"diff"},K={class:"muted"},O={class:"muted"},Q={class:"muted"},U={class:"muted",style:{"margin-top":"6px"}},W={class:"primary",style:{width:"100%"}},X={class:"primary",style:{width:"100%"}},Y={key:1,class:"muted",style:{"margin-top":"auto","font-size":"12px"}},Z={__name:"Personas",setup(tt){const c=L().params.gid,k=b([]),B=b(!0);async function C(){try{k.value=(await N.listPersonas(c)).personas}finally{B.value=!1}}function z(l){return k.value.filter(i=>i.tier===l)}function P(l){return n.t(l==="A"?"tierA":l==="B"?"tierB":"tierC")}function v(l){return l==="won"?n.t("won"):l==="lost"?n.t("lost"):n.t("notTried")}return $(C),(l,i)=>{const u=V("router-link");return a(),r("div",null,[d(u,{to:"/training",class:"btn-back"},{default:m(()=>[d(e(F),{size:16,"stroke-width":2}),_(" "+s(e(n).t("training")),1)]),_:1}),t("div",j,[t("h2",D,s(e(n).t("personas")),1),t("span",E,s(e(n).t("selectPersona")),1)]),e(f).isAdmin?w("",!0):(a(),r("div",M,[t("strong",null,[d(e(S),{size:17,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),i[0]||(i[0]=_(" วิธีฝึก",-1))]),i[1]||(i[1]=t("ol",{style:{margin:"8px 0 0","padding-left":"20px","line-height":"1.8"}},[t("li",null,"เลือกลูกค้าจำลอง (บุคคลต้นแบบ) คนหนึ่งที่อยากฝึกด้วย"),t("li",null,"ระดับ A ง่ายสุด → ระดับ C ยากสุด (ดูจากดาว ★ ความยาก)"),t("li",null,"กดปุ่มสำหรับฝึกแชทกับลูกค้าคนนั้น (ฝึกได้คนละครั้งเท่านั้น)")],-1))])),e(f).isAdmin?(a(),r("div",R,[d(u,{to:`/admin/groups/${e(c)}/edit`},{default:m(()=>[t("button",q,[d(e(I),{size:18,"stroke-width":1.8}),_(" "+s(e(n).t("managePersonas")),1)])]),_:1},8,["to"]),i[2]||(i[2]=t("span",{class:"muted"},"Admin: จัดการรายละเอียดบุคคลต้นแบบได้ที่นี่",-1))])):w("",!0),(a(),r(y,null,p(["A","B","C"],g=>t("div",{key:g,style:{margin:"20px 0"}},[t("h4",null,s(P(g)),1),t("div",G,[(a(!0),r(y,null,p(z(g),o=>(a(),r("div",{key:o.id,class:"card pcard lift"},[t("div",H,[t("strong",null,s(o.name),1),t("span",{class:h(["badge",o.my_outcome])},s(v(o.my_outcome)),3)]),t("div",J,[(a(),r(y,null,p(5,x=>t("span",{key:x,class:h(["star",{on:x<=(o.difficulty||1)}])},"★",2)),64)),t("span",K,s(e(n).t("difficulty"))+" "+s(o.difficulty||1)+"/5",1)]),t("div",O,[_(s(o.profession)+" · "+s(o.age_group)+" · "+s(o.location),1),i[3]||(i[3]=t("br",null,null,-1)),t("span",{class:h(["badge",o.channel])},s(o.channel),3),t("span",Q," · "+s(o.initiation_mode==="seller"?e(n).t("sellerInitiated"):e(n).t("customerInitiated")),1)]),t("div",U,s(o.product_context),1),e(f).isAdmin?(a(),A(u,{key:0,to:`/groups/${e(c)}/chat/${o.id}`,style:{"margin-top":"auto"}},{default:m(()=>[t("button",W,s(e(n).t("chat")),1)]),_:1},8,["to"])):(a(),r(y,{key:1},[o.my_outcome==="not_tried"?(a(),A(u,{key:0,to:`/groups/${e(c)}/chat/${o.id}`,style:{"margin-top":"auto"}},{default:m(()=>[t("button",X,s(e(n).t("chat")),1)]),_:1},8,["to"])):(a(),r("div",Y,"✓ "+s(e(n).t("trained"))+" ("+s(v(o.my_outcome))+")",1))],64))]))),128))])])),64))])}}},at=T(Z,[["__scopeId","data-v-46d50c99"]]);export{at as default}; diff --git a/frontend/dist/assets/Settings-BvwfMyfH.js b/frontend/dist/assets/Settings-BvwfMyfH.js deleted file mode 100644 index fbfd187..0000000 --- a/frontend/dist/assets/Settings-BvwfMyfH.js +++ /dev/null @@ -1,16 +0,0 @@ -import{k as z,_ as T,r as c,f as i,c as h,a as e,m as k,u as a,S as $,j as v,t as o,i as s,w as x,v as b,e as V,A as S,s as U,o as w}from"./index-C0_i8cDF.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 j=z("globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);/** - * @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 D=z("lock",[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]]);/** - * @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 E=z("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]),I={class:"card"},A={style:{"margin-top":"0"}},G={class:"muted"},H=["value"],O={class:"row",style:{gap:"10px","margin-top":"16px"}},q=["disabled"],F={key:0,class:"spinner"},J={class:"card",style:{"margin-top":"16px"}},K={style:{"margin-top":"0"}},Q={class:"row",style:{gap:"10px","margin-top":"16px"}},R=["disabled"],W={key:0,class:"spinner"},X={class:"card",style:{"margin-top":"16px"}},Y={style:{"margin-top":"0"}},Z={class:"row"},ee={key:0,class:"error",role:"alert"},ae={key:1,class:"ok",role:"status"},se={__name:"Settings",setup(te){var C,M;const y=c(((C=i.user)==null?void 0:C.name)||""),p=c(((M=i.user)==null?void 0:M.email)||""),u=c(""),_=c(""),r=c(""),m=c(""),g=c(!1),f=c(!1);async function B(){var d,t;r.value="",m.value="",g.value=!0;try{const n={};if(y.value&&y.value!==((d=i.user)==null?void 0:d.name)&&(n.name=y.value),p.value&&p.value!==((t=i.user)==null?void 0:t.email)&&(n.email=p.value),Object.keys(n).length){const l=await U.updateProfile(n);i.user=l.user,m.value=s.t("saved")}}catch(n){r.value=n.message}finally{g.value=!1}}async function N(){var d,t,n;if(r.value="",m.value="",u.value.length<4){r.value=s.t("passwordTooShort");return}if(u.value!==_.value){r.value=s.t("passwordMismatch");return}f.value=!0;try{const l=((d=i.user)==null?void 0:d.username)||((t=i.user)==null?void 0:t.id)||"",L=await U.setup({username:l,email:p.value||((n=i.user)==null?void 0:n.email),password:u.value});i.user=L.user,u.value="",_.value="",m.value=s.t("saved")}catch(l){r.value=l.message}finally{f.value=!1}}function P(d){s.set(d)}return(d,t)=>{var n;return w(),h("div",null,[e("h2",null,[k(a($),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),v(" "+o(a(s).t("settings")),1)]),e("div",I,[e("h3",A,[k(a(E),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("profile")),1)]),e("label",null,[v(o(a(s).t("username"))+" ",1),e("span",G,"("+o(a(s).t("readonly"))+")",1)]),e("input",{value:((n=a(i).user)==null?void 0:n.username)||"",disabled:""},null,8,H),e("label",null,o(a(s).t("name")),1),x(e("input",{"onUpdate:modelValue":t[0]||(t[0]=l=>y.value=l),type:"text"},null,512),[[b,y.value]]),e("label",null,o(a(s).t("email")),1),x(e("input",{"onUpdate:modelValue":t[1]||(t[1]=l=>p.value=l),type:"email"},null,512),[[b,p.value]]),e("div",O,[e("button",{class:"primary",disabled:g.value,onClick:B},[g.value?(w(),h("span",F)):V("",!0),v(o(a(s).t("saveProfile")),1)],8,q)])]),e("div",J,[e("h3",K,[k(a(D),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("changePassword")),1)]),e("label",null,o(a(s).t("newPassword")),1),x(e("input",{"onUpdate:modelValue":t[2]||(t[2]=l=>u.value=l),type:"password",autocomplete:"new-password"},null,512),[[b,u.value]]),e("label",null,o(a(s).t("confirmPassword")),1),x(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>_.value=l),type:"password",autocomplete:"new-password"},null,512),[[b,_.value]]),e("div",Q,[e("button",{class:"primary",disabled:f.value||!u.value||u.value!==_.value,onClick:N},[f.value?(w(),h("span",W)):V("",!0),v(o(a(s).t("save")),1)],8,R)])]),e("div",X,[e("h3",Y,[k(a(j),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("language")),1)]),e("div",Z,[e("button",{class:S({active:a(s).locale==="th"}),onClick:t[4]||(t[4]=l=>P("th"))},"ไทย",2),e("button",{class:S({active:a(s).locale==="en"}),onClick:t[5]||(t[5]=l=>P("en"))},"English",2)])]),r.value?(w(),h("div",ee,o(r.value),1)):V("",!0),m.value?(w(),h("div",ae,"✅ "+o(m.value),1)):V("",!0)])}}},oe=T(se,[["__scopeId","data-v-4a5a3af4"]]);export{oe as default}; diff --git a/frontend/dist/assets/Settings-CVA3uaSz.js b/frontend/dist/assets/Settings-CVA3uaSz.js new file mode 100644 index 0000000..f138647 --- /dev/null +++ b/frontend/dist/assets/Settings-CVA3uaSz.js @@ -0,0 +1,11 @@ +import{c as M,_ as T,r as c,h as u,a as h,b as e,l as k,u as a,S as $,m as v,t as o,i as s,w as b,v as x,g as V,B as S,x as B,o as g}from"./index-DOaJiTJw.js";import{L as D}from"./lock-WqnzR3ED.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 E=M("globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);/** + * @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 I=M("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]),j={class:"card"},G={style:{"margin-top":"0"}},H={class:"muted"},O=["value"],q={class:"row",style:{gap:"10px","margin-top":"16px"}},A=["disabled"],F={key:0,class:"spinner"},J={class:"card",style:{"margin-top":"16px"}},K={style:{"margin-top":"0"}},Q={class:"row",style:{gap:"10px","margin-top":"16px"}},R=["disabled"],W={key:0,class:"spinner"},X={class:"card",style:{"margin-top":"16px"}},Y={style:{"margin-top":"0"}},Z={class:"row"},ee={key:0,class:"error",role:"alert"},ae={key:1,class:"ok",role:"status"},se={__name:"Settings",setup(te){var z,C;const y=c(((z=u.user)==null?void 0:z.name)||""),p=c(((C=u.user)==null?void 0:C.email)||""),i=c(""),_=c(""),r=c(""),m=c(""),f=c(!1),w=c(!1);async function U(){var d,t;r.value="",m.value="",f.value=!0;try{const n={};if(y.value&&y.value!==((d=u.user)==null?void 0:d.name)&&(n.name=y.value),p.value&&p.value!==((t=u.user)==null?void 0:t.email)&&(n.email=p.value),Object.keys(n).length){const l=await B.updateProfile(n);u.user=l.user,m.value=s.t("saved")}}catch(n){r.value=n.message}finally{f.value=!1}}async function L(){var d,t,n;if(r.value="",m.value="",i.value.length<4){r.value=s.t("passwordTooShort");return}if(i.value!==_.value){r.value=s.t("passwordMismatch");return}w.value=!0;try{const l=((d=u.user)==null?void 0:d.username)||((t=u.user)==null?void 0:t.id)||"",N=await B.setup({username:l,email:p.value||((n=u.user)==null?void 0:n.email),password:i.value});u.user=N.user,i.value="",_.value="",m.value=s.t("saved")}catch(l){r.value=l.message}finally{w.value=!1}}function P(d){s.set(d)}return(d,t)=>{var n;return g(),h("div",null,[e("h2",null,[k(a($),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),v(" "+o(a(s).t("settings")),1)]),e("div",j,[e("h3",G,[k(a(I),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("profile")),1)]),e("label",null,[v(o(a(s).t("username"))+" ",1),e("span",H,"("+o(a(s).t("readonly"))+")",1)]),e("input",{value:((n=a(u).user)==null?void 0:n.username)||"",disabled:""},null,8,O),e("label",null,o(a(s).t("name")),1),b(e("input",{"onUpdate:modelValue":t[0]||(t[0]=l=>y.value=l),type:"text"},null,512),[[x,y.value]]),e("label",null,o(a(s).t("email")),1),b(e("input",{"onUpdate:modelValue":t[1]||(t[1]=l=>p.value=l),type:"email"},null,512),[[x,p.value]]),e("div",q,[e("button",{class:"primary",disabled:f.value,onClick:U},[f.value?(g(),h("span",F)):V("",!0),v(o(a(s).t("saveProfile")),1)],8,A)])]),e("div",J,[e("h3",K,[k(a(D),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("changePassword")),1)]),e("label",null,o(a(s).t("newPassword")),1),b(e("input",{"onUpdate:modelValue":t[2]||(t[2]=l=>i.value=l),type:"password",autocomplete:"new-password"},null,512),[[x,i.value]]),e("label",null,o(a(s).t("confirmPassword")),1),b(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>_.value=l),type:"password",autocomplete:"new-password"},null,512),[[x,_.value]]),e("div",Q,[e("button",{class:"primary",disabled:w.value||!i.value||i.value!==_.value,onClick:L},[w.value?(g(),h("span",W)):V("",!0),v(o(a(s).t("save")),1)],8,R)])]),e("div",X,[e("h3",Y,[k(a(E),{size:18,"stroke-width":1.8,style:{"vertical-align":"-3px"}}),v(" "+o(a(s).t("language")),1)]),e("div",Z,[e("button",{class:S({active:a(s).locale==="th"}),onClick:t[4]||(t[4]=l=>P("th"))},"ไทย",2),e("button",{class:S({active:a(s).locale==="en"}),onClick:t[5]||(t[5]=l=>P("en"))},"English",2)])]),r.value?(g(),h("div",ee,o(r.value),1)):V("",!0),m.value?(g(),h("div",ae,"✅ "+o(m.value),1)):V("",!0)])}}},ne=T(se,[["__scopeId","data-v-4a5a3af4"]]);export{ne as default}; diff --git a/frontend/dist/assets/Setup-BdS_6JlN.css b/frontend/dist/assets/Setup-BdS_6JlN.css deleted file mode 100644 index 501dcfb..0000000 --- a/frontend/dist/assets/Setup-BdS_6JlN.css +++ /dev/null @@ -1 +0,0 @@ -.setup-wrap[data-v-f190e120]{display:flex;justify-content:center;padding-top:8vh}.setup-card[data-v-f190e120]{width:380px}h1[data-v-f190e120]{margin-top:0} diff --git a/frontend/dist/assets/Setup-C_0Y0xY8.js b/frontend/dist/assets/Setup-C_0Y0xY8.js new file mode 100644 index 0000000..928dda8 --- /dev/null +++ b/frontend/dist/assets/Setup-C_0Y0xY8.js @@ -0,0 +1 @@ +import{_ as V,a as v,b as e,l as S,u as s,m as g,t,i as a,h as w,w as _,v as y,d as f,g as K,r,j as N,o as m}from"./index-DOaJiTJw.js";import{L as T}from"./lock-WqnzR3ED.js";const B={class:"setup-wrap"},U={class:"card setup-card"},C={class:"muted"},D={key:0,class:"error",role:"alert"},L=["disabled"],M={key:0,class:"spinner"},P={key:1},j={__name:"Setup",setup(z){const x=N(),i=r(""),l=r(""),p=r(""),o=r(""),d=r(!1);async function c(){if(o.value="",l.value.length<4){o.value=a.t("passwordTooShort");return}if(l.value!==p.value){o.value=a.t("passwordMismatch");return}d.value=!0;try{await w.finishSetup(i.value.trim(),l.value),x.push("/")}catch(h){o.value=h.message}finally{d.value=!1}}return(h,u)=>{var b,k;return m(),v("div",B,[e("div",U,[e("h1",null,[S(s(T),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),g(" "+t(s(a).t("setupTitle")),1)]),e("p",C,[g(t(s(a).t("setupSubtitle"))+" ",1),e("strong",null,t(((b=s(w).user)==null?void 0:b.name)||((k=s(w).user)==null?void 0:k.username)),1)]),e("label",null,t(s(a).t("email")),1),_(e("input",{"onUpdate:modelValue":u[0]||(u[0]=n=>i.value=n),type:"email",autocomplete:"email",class:"wide",onKeyup:f(c,["enter"])},null,544),[[y,i.value]]),e("label",null,t(s(a).t("newPassword")),1),_(e("input",{"onUpdate:modelValue":u[1]||(u[1]=n=>l.value=n),type:"password",autocomplete:"new-password",class:"wide",onKeyup:f(c,["enter"])},null,544),[[y,l.value]]),e("label",null,t(s(a).t("confirmPassword")),1),_(e("input",{"onUpdate:modelValue":u[2]||(u[2]=n=>p.value=n),type:"password",autocomplete:"new-password",class:"wide",onKeyup:f(c,["enter"])},null,544),[[y,p.value]]),o.value?(m(),v("div",D,t(o.value),1)):K("",!0),e("button",{class:"primary",style:{width:"100%","margin-top":"16px"},disabled:d.value||!i.value||!l.value||l.value!==p.value,onClick:c},[d.value?(m(),v("span",M)):(m(),v("span",P,t(s(a).t("save")),1))],8,L)])])}}},R=V(j,[["__scopeId","data-v-477fc775"]]);export{R as default}; diff --git a/frontend/dist/assets/Setup-Cy1qc0PW.css b/frontend/dist/assets/Setup-Cy1qc0PW.css new file mode 100644 index 0000000..b02c6cd --- /dev/null +++ b/frontend/dist/assets/Setup-Cy1qc0PW.css @@ -0,0 +1 @@ +.setup-wrap[data-v-477fc775]{display:flex;justify-content:center;padding-top:8vh;padding-left:16px;padding-right:16px}.setup-card[data-v-477fc775]{width:460px;max-width:100%;padding:28px 30px}h1[data-v-477fc775]{margin-top:0;font-size:24px}.wide[data-v-477fc775]{width:100%;min-height:46px;font-size:15px;padding:12px 14px} diff --git a/frontend/dist/assets/Setup-D1N6f_I9.js b/frontend/dist/assets/Setup-D1N6f_I9.js deleted file mode 100644 index 691e416..0000000 --- a/frontend/dist/assets/Setup-D1N6f_I9.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as x,c as v,a as e,t,u as s,i as a,j as S,f as _,w,v as f,b as y,e as V,r,g as K,o as m}from"./index-C0_i8cDF.js";const T={class:"setup-wrap"},B={class:"card setup-card"},N={class:"muted"},U={key:0,class:"error",role:"alert"},C=["disabled"],D={key:0,class:"spinner"},M={key:1},P={__name:"Setup",setup(j){const k=K(),i=r(""),l=r(""),p=r(""),o=r(""),d=r(!1);async function c(){if(o.value="",l.value.length<4){o.value=a.t("passwordTooShort");return}if(l.value!==p.value){o.value=a.t("passwordMismatch");return}d.value=!0;try{await _.finishSetup(i.value.trim(),l.value),k.push("/")}catch(h){o.value=h.message}finally{d.value=!1}}return(h,u)=>{var b,g;return m(),v("div",T,[e("div",B,[e("h1",null,"🔐 "+t(s(a).t("setupTitle")),1),e("p",N,[S(t(s(a).t("setupSubtitle"))+" ",1),e("strong",null,t(((b=s(_).user)==null?void 0:b.name)||((g=s(_).user)==null?void 0:g.username)),1)]),e("label",null,t(s(a).t("email")),1),w(e("input",{"onUpdate:modelValue":u[0]||(u[0]=n=>i.value=n),type:"email",autocomplete:"email",onKeyup:y(c,["enter"])},null,544),[[f,i.value]]),e("label",null,t(s(a).t("newPassword")),1),w(e("input",{"onUpdate:modelValue":u[1]||(u[1]=n=>l.value=n),type:"password",autocomplete:"new-password",onKeyup:y(c,["enter"])},null,544),[[f,l.value]]),e("label",null,t(s(a).t("confirmPassword")),1),w(e("input",{"onUpdate:modelValue":u[2]||(u[2]=n=>p.value=n),type:"password",autocomplete:"new-password",onKeyup:y(c,["enter"])},null,544),[[f,p.value]]),o.value?(m(),v("div",U,t(o.value),1)):V("",!0),e("button",{class:"primary",style:{width:"100%","margin-top":"16px"},disabled:d.value||!i.value||!l.value||l.value!==p.value,onClick:c},[d.value?(m(),v("span",D)):(m(),v("span",M,t(s(a).t("save")),1))],8,C)])])}}},I=x(P,[["__scopeId","data-v-f190e120"]]);export{I as default}; diff --git a/frontend/dist/assets/Training-CsBkF1Lz.js b/frontend/dist/assets/Training-CsBkF1Lz.js deleted file mode 100644 index a0a3293..0000000 --- a/frontend/dist/assets/Training-CsBkF1Lz.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as w,l as b,s as A,f as d,c as l,a as t,m as c,u as s,j as _,t as e,i as n,n as m,B as h,e as f,F as B,q as C,r as g,x as N,o as i,A as k}from"./index-C0_i8cDF.js";import{T as P}from"./target-DoOGVGr0.js";import{B as T}from"./book-open-E7lWrK45.js";import{P as z}from"./plus-BiLb0OIF.js";const V={class:"row",style:{"align-items":"center","margin-bottom":"16px"}},j={style:{margin:"0"}},F={class:"row",style:{"margin-left":"auto",gap:"10px"}},L={class:"soft"},S={class:"primary"},$={class:"muted"},q={key:0,class:"card",style:{"min-height":"80px"}},D={key:1,class:"card empty-state"},E={key:0},G={key:1},I={class:"grid"},M={class:"card lift train-card"},O={class:"row",style:{"justify-content":"space-between"}},H={class:"muted",style:{margin:"6px 0 12px"}},J={class:"row",style:{gap:"8px"}},K={class:"muted"},Q={class:"primary",style:{width:"100%","margin-top":"12px"}},R={__name:"Training",setup(U){const u=g([]),y=g(!0);function v(a){return a.sales_kit&&a.sales_kit.productName||a.input&&a.input.product||""}function x(a){return a.personas||a.persona_count||0}return b(async()=>{try{const a=(await A.listGroups()).groups||[];u.value=d.isAdmin?a:a.filter(r=>r.status==="ready")}finally{y.value=!1}}),(a,r)=>{const p=N("router-link");return i(),l("div",null,[t("div",V,[t("h2",j,[c(s(P),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),_(" "+e(s(n).t("training")),1)]),t("div",F,[c(p,{to:"/guide"},{default:m(()=>[t("button",L,[c(s(T),{size:18,"stroke-width":1.8}),r[0]||(r[0]=_(" คู่มือ",-1))])]),_:1}),s(d).isAdmin?(i(),h(p,{key:0,to:"/admin/new-group"},{default:m(()=>[t("button",S,[c(s(z),{size:18,"stroke-width":2}),_(" "+e(s(n).t("addProduct")),1)])]),_:1})):f("",!0)])]),t("p",$,e(s(n).t("trainingSubtitle")),1),y.value?(i(),l("div",q,[...r[1]||(r[1]=[t("div",{class:"skeleton",style:{height:"50px"}},null,-1)])])):u.value.length===0?(i(),l("div",D,[t("strong",null,e(s(n).t("noTraining")),1),s(d).isAdmin?(i(),l("span",E,'Click "'+e(s(n).t("addProduct"))+'" to create a persona group.',1)):(i(),l("span",G,"Ask an admin to create a persona group first."))])):f("",!0),t("div",I,[(i(!0),l(B,null,C(u.value,o=>(i(),h(p,{key:o.id,to:s(d).isAdmin?`/admin/groups/${o.id}/edit`:`/groups/${o.id}/personas`,style:{"text-decoration":"none"}},{default:m(()=>[t("div",M,[t("div",O,[t("strong",null,e(o.title),1),t("span",{class:k(["badge",o.status==="ready"?"ready":"draft"])},e(o.status),3)]),t("div",H,e(v(o)),1),t("div",J,[t("span",{class:k(["badge",o.channel||"line"])},e(o.channel||"line"),3),t("span",K,e(x(o))+" "+e(s(n).t("personas").toLowerCase()),1)]),t("button",Q,e(s(d).isAdmin?o.status==="ready"?s(n).t("managePersonas"):s(n).t("analyze"):s(n).t("selectPersona")),1)])]),_:2},1032,["to"]))),128))])])}}},tt=w(R,[["__scopeId","data-v-e39df241"]]);export{tt as default}; diff --git a/frontend/dist/assets/Training-EZ9n5Yut.js b/frontend/dist/assets/Training-EZ9n5Yut.js new file mode 100644 index 0000000..f151f79 --- /dev/null +++ b/frontend/dist/assets/Training-EZ9n5Yut.js @@ -0,0 +1 @@ +import{_ as w,n as b,x as B,h as d,a as l,b as t,l as c,u as s,m as _,t as e,i as n,p as m,f as h,g as f,F as C,s as A,r as g,y as N,o as i,B as k}from"./index-DOaJiTJw.js";import{T as P}from"./target-QJk_fUDu.js";import{B as T}from"./book-open-Ckxqlz0w.js";import{P as z}from"./plus-CODydpxS.js";const V={class:"row",style:{"align-items":"center","margin-bottom":"16px"}},F={style:{margin:"0"}},L={class:"row",style:{"margin-left":"auto",gap:"10px"}},S={class:"soft"},$={class:"primary"},j={class:"muted"},D={key:0,class:"card",style:{"min-height":"80px"}},E={key:1,class:"card empty-state"},G={key:0},I={key:1},M={class:"grid"},O={class:"card lift train-card"},q={class:"row",style:{"justify-content":"space-between"}},H={class:"muted",style:{margin:"6px 0 12px"}},J={class:"row",style:{gap:"8px"}},K={class:"muted"},Q={class:"primary",style:{width:"100%","margin-top":"12px"}},R={__name:"Training",setup(U){const u=g([]),y=g(!0);function v(a){return a.sales_kit&&a.sales_kit.productName||a.input&&a.input.product||""}function x(a){return a.personas||a.persona_count||0}return b(async()=>{try{const a=(await B.listGroups()).groups||[];u.value=d.isAdmin?a:a.filter(r=>r.status==="ready")}finally{y.value=!1}}),(a,r)=>{const p=N("router-link");return i(),l("div",null,[t("div",V,[t("h2",F,[c(s(P),{size:22,"stroke-width":1.8,style:{"vertical-align":"-4px"}}),_(" "+e(s(n).t("training")),1)]),t("div",L,[c(p,{to:"/guide"},{default:m(()=>[t("button",S,[c(s(T),{size:18,"stroke-width":1.8}),r[0]||(r[0]=_(" คู่มือ",-1))])]),_:1}),s(d).isAdmin?(i(),h(p,{key:0,to:"/admin/new-group"},{default:m(()=>[t("button",$,[c(s(z),{size:18,"stroke-width":2}),_(" "+e(s(n).t("addProduct")),1)])]),_:1})):f("",!0)])]),t("p",j,e(s(n).t("trainingSubtitle")),1),y.value?(i(),l("div",D,[...r[1]||(r[1]=[t("div",{class:"skeleton",style:{height:"50px"}},null,-1)])])):u.value.length===0?(i(),l("div",E,[t("strong",null,e(s(n).t("noTraining")),1),s(d).isAdmin?(i(),l("span",G,'Click "'+e(s(n).t("addProduct"))+'" to create a persona group.',1)):(i(),l("span",I,"Ask an admin to create a persona group first."))])):f("",!0),t("div",M,[(i(!0),l(C,null,A(u.value,o=>(i(),h(p,{key:o.id,to:s(d).isAdmin?`/admin/groups/${o.id}/edit`:`/groups/${o.id}/personas`,style:{"text-decoration":"none"}},{default:m(()=>[t("div",O,[t("div",q,[t("strong",null,e(o.title),1),t("span",{class:k(["badge",o.status==="ready"?"ready":"draft"])},e(o.status),3)]),t("div",H,e(v(o)),1),t("div",J,[t("span",{class:k(["badge",o.channel||"line"])},e(o.channel||"line"),3),t("span",K,e(x(o))+" "+e(s(n).t("personas").toLowerCase()),1)]),t("button",Q,e(s(d).isAdmin?o.status==="ready"?s(n).t("managePersonas"):s(n).t("analyze"):s(n).t("selectPersona")),1)])]),_:2},1032,["to"]))),128))])])}}},tt=w(R,[["__scopeId","data-v-e39df241"]]);export{tt as default}; diff --git a/frontend/dist/assets/arrow-left-neyuEczm.js b/frontend/dist/assets/arrow-left-BUCak2lw.js similarity index 86% rename from frontend/dist/assets/arrow-left-neyuEczm.js rename to frontend/dist/assets/arrow-left-BUCak2lw.js index 84c5863..531d7f9 100644 --- a/frontend/dist/assets/arrow-left-neyuEczm.js +++ b/frontend/dist/assets/arrow-left-BUCak2lw.js @@ -1,4 +1,4 @@ -import{k as e}from"./index-C0_i8cDF.js";/** +import{c as e}from"./index-DOaJiTJw.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/book-open-E7lWrK45.js b/frontend/dist/assets/book-open-Ckxqlz0w.js similarity index 90% rename from frontend/dist/assets/book-open-E7lWrK45.js rename to frontend/dist/assets/book-open-Ckxqlz0w.js index dbb4b51..18292a6 100644 --- a/frontend/dist/assets/book-open-E7lWrK45.js +++ b/frontend/dist/assets/book-open-Ckxqlz0w.js @@ -1,4 +1,4 @@ -import{k as a}from"./index-C0_i8cDF.js";/** +import{c as a}from"./index-DOaJiTJw.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/index-C0_i8cDF.js b/frontend/dist/assets/index-DOaJiTJw.js similarity index 97% rename from frontend/dist/assets/index-C0_i8cDF.js rename to frontend/dist/assets/index-DOaJiTJw.js index 2a9d95f..a39322b 100644 --- a/frontend/dist/assets/index-C0_i8cDF.js +++ b/frontend/dist/assets/index-DOaJiTJw.js @@ -1,4 +1,4 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Login-vrbZzr6f.js","assets/Login-D3svPLnW.css","assets/Setup-D1N6f_I9.js","assets/Setup-BdS_6JlN.css","assets/Analytics-z04-C_VZ.js","assets/users-qxBh6IGP.js","assets/plus-BiLb0OIF.js","assets/Analytics-CQgwlaXy.css","assets/MyBoard-UPzqfwhQ.js","assets/layout-dashboard-C4nLoaIz.js","assets/MyBoard-B7ypQ1JT.css","assets/Training-CsBkF1Lz.js","assets/target-DoOGVGr0.js","assets/book-open-E7lWrK45.js","assets/Training-BYBkfggr.css","assets/Personas-Dl-F3CRY.js","assets/arrow-left-neyuEczm.js","assets/Personas-CskAUbZv.css","assets/Chat-DvLKhxgu.js","assets/Chat-Dhsij-Zk.css","assets/Settings-BvwfMyfH.js","assets/Settings-BCN2EZQ5.css","assets/Guide-D6Cvcccc.js","assets/sparkles-D66jVNJm.js","assets/GroupBuilder-DYRYwsrA.js","assets/GroupBuilder-CpbMByEC.css","assets/GroupEdit-DsLJeZZx.js","assets/GroupEdit-D9lmggXK.css","assets/AdminUsers-Cv-dZx8g.js","assets/AdminUsers-B0sl0uHS.css"])))=>i.map(i=>d[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Login-DxHA8GYa.js","assets/Login-j4sHK_z1.css","assets/Setup-C_0Y0xY8.js","assets/lock-WqnzR3ED.js","assets/Setup-Cy1qc0PW.css","assets/Analytics-Bkjt0mFt.js","assets/users-SQMCzZpr.js","assets/plus-CODydpxS.js","assets/Analytics-CQgwlaXy.css","assets/MyBoard-CTHsz6OL.js","assets/layout-dashboard-CmUmS5d8.js","assets/MyBoard-B7ypQ1JT.css","assets/Training-EZ9n5Yut.js","assets/target-QJk_fUDu.js","assets/book-open-Ckxqlz0w.js","assets/Training-BYBkfggr.css","assets/Personas-CGSsKXxA.js","assets/arrow-left-BUCak2lw.js","assets/Personas-CskAUbZv.css","assets/Chat-DszzTVNw.js","assets/Chat-Dhsij-Zk.css","assets/Settings-CVA3uaSz.js","assets/Settings-BCN2EZQ5.css","assets/Guide-GzVXirX-.js","assets/sparkles-CwNig9QR.js","assets/GroupBuilder-CNxYYLnR.js","assets/GroupBuilder-CpbMByEC.css","assets/GroupEdit-Bq-uo5sC.js","assets/GroupEdit-D9lmggXK.css","assets/AdminUsers-B8OP5hvL.js","assets/AdminUsers-B0sl0uHS.css"])))=>i.map(i=>d[i]); (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&s(o)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function s(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();/** * @vue/shared v3.5.41 * (c) 2018-present Yuxi (Evan) You and Vue contributors @@ -79,4 +79,4 @@ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Login-vrbZzr6f. * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. - */const Eu=No("settings",[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]),Bs="st_token";function Mo(){return localStorage.getItem(Bs)}function ws(e){e?localStorage.setItem(Bs,e):localStorage.removeItem(Bs)}async function ee(e,t,n,s=!1){const r={},i=Mo();i&&(r.Authorization=`Bearer ${i}`);let o=n;!s&&n!==void 0&&n!==null&&(r["Content-Type"]="application/json",o=JSON.stringify(n));const l=await fetch(t,{method:e,headers:r,body:o});let c=null;try{c=await l.json()}catch{}if(!l.ok){const f=c&&(c.error||c.message)||`HTTP ${l.status}`;throw new Error(f)}return c}const Ss={login:(e,t)=>ee("POST","/api/auth/login",{username:e,password:t}),me:()=>ee("GET","/api/auth/me"),setup:e=>ee("POST","/api/auth/setup",e),updateProfile:e=>ee("PATCH","/api/auth/profile",e),adminCreateUser:e=>ee("POST","/api/admin/users",e),adminListUsers:()=>ee("GET","/api/admin/users"),adminUpdateUser:(e,t)=>ee("PUT",`/api/admin/users/${e}`,t),createGroup:e=>ee("POST","/api/groups",e,!0),listGroups:()=>ee("GET","/api/groups"),getGroup:e=>ee("GET",`/api/groups/${e}`),analyzeGroup:e=>ee("POST",`/api/groups/${e}/analyze`),listPersonas:e=>ee("GET",`/api/groups/${e}/personas`),getPersona:(e,t)=>ee("GET",`/api/groups/${e}/personas/${t}`),updatePersona:(e,t,n)=>ee("PUT",`/api/groups/${e}/personas/${t}`,n),chatStart:(e,t,n,s)=>ee("POST",`/api/chat/${e}/personas/${t}/chat/start`,{scenario:n,locale:s}),chatResume:(e,t)=>ee("GET",`/api/chat/${e}/personas/${t}/chat/resume`),chatSend:(e,t,n)=>ee("POST",`/api/chat/${e}/personas/${t}/chat/send`,{text:n}),chatFinish:(e,t)=>ee("POST",`/api/chat/${e}/personas/${t}/chat/finish`),mySessions:()=>ee("GET","/api/chat/sessions"),myBoard:()=>ee("GET","/api/me/board"),weakAreas:()=>ee("GET","/api/me/weak-areas"),myPersonas:()=>ee("GET","/api/me/personas"),generatePersona:e=>ee("POST","/api/me/personas/generate",e),analytics:(e={})=>{const t=new URLSearchParams;e.from&&t.set("from",e.from),e.to&&t.set("to",e.to);const n=t.toString();return ee("GET",`/api/analytics${n?`?${n}`:""}`)}},Ce=Jt({user:null,token:Mo(),mustSetup:!1,get role(){return this.user?this.user.role:null},get isAdmin(){return this.role==="admin"||this.role==="super_admin"},async load(){var e;if(!this.token)return null;try{const t=await Ss.me();return this.user=t.user,this.mustSetup=!!((e=t.user)!=null&&e.must_setup),this.user}catch{return this.user=null,this.mustSetup=!1,ws(null),null}},async login(e,t){const n=await Ss.login(e,t);return this.token=n.token,ws(n.token),this.user=n.user,this.mustSetup=!!n.must_setup,n.user},async finishSetup(e,t){const n=await Ss.setup({username:this.user.username||this.user.id,email:e,password:t});return this.user=n.user,this.mustSetup=!1,n.user},logout(){this.user=null,this.token=null,this.mustSetup=!1,ws(null)}}),As={en:{app:"Sales Trainer",login:"Login",logout:"Logout",username:"Username",email:"Email",password:"Password",newPassword:"New password",confirmPassword:"Confirm password",save:"Save",passwordTooShort:"Password must be at least 4 characters",passwordMismatch:"Passwords do not match",setupTitle:"Set up your account",setupSubtitle:"First login for ",loginError:"Invalid credentials",dashboard:"Dashboard",training:"Training",myDashboard:"My dashboard",adminOverview:"Admin overview",guideTitle:"How to use / คู่มือใช้งาน",settings:"Settings",account:"Account",profile:"Profile",readonly:"read-only",name:"Display name",saveProfile:"Save profile",changePassword:"Change password",optional:"optional",saved:"Saved",total:"Total",dateRange:"Date range",apply:"Apply",clear:"Clear",hardestPersonas:"Hardest personas",closeRate:"Close rate",managePersonas:"Manage personas",difficulty:"Difficulty",trained:"Trained",addProduct:"Add product",trainingSubtitle:"Pick a product group, then choose a persona to practice closing the sale.",noTraining:"No training groups available",groups:"Persona Groups",myTraining:"My Training",adminTools:"Admin Tools",users:"Users",analytics:"Analytics",groupBuilder:"Group Builder",create:"Create",analyze:"Analyze",manual:"Manual",edit:"Edit",product:"Product",segment:"Initial customer segment (optional)",description:"Additional description / scenario (optional)",channel:"Channel",facebook:"Facebook",line:"LINE",language:"Language",thai:"Thai",english:"English",personas:"Personas",tierA:"Tier A — Ready to buy",tierB:"Tier B — Unsure",tierC:"Tier C — Not interested but has pain",selectPersona:"Select a persona to practice",chooseScenario:"Choose a scenario",chatGuideTitle:"How to practice",chatGuideText:'You are playing the salesperson. Chat with this customer and try to close the sale. Ask about their needs, solve their pain, and handle their objections. When you are done, press "Finish & get result" to see your score and coaching.',chat:"Chat",start:"Start",send:"Send",finish:"Finish & get result",debrief:"Result & Coaching",won:"Won",lost:"Lost",notTried:"Not tried",score:"Score",pain:"Pain",why:"Reason",reveal:"Revealed persona details",generatePersona:"Generate my persona",weakAreas:"My weak areas",mySessions:"My sessions",openSaleTask:"The customer did NOT message first. You must open the sale.",sellerInitiated:"You must open the sale (outbound)",customerInitiated:"The customer will message you first"},th:{app:"ระบบฝึกทักษะการขาย",login:"เข้าสู่ระบบ",logout:"ออกจากระบบ",username:"ชื่อผู้ใช้",email:"อีเมล",password:"รหัสผ่าน",newPassword:"รหัสผ่านใหม่",confirmPassword:"ยืนยันรหัสผ่าน",save:"บันทึก",passwordTooShort:"รหัสผ่านต้องมีความยาวอย่างน้อย 4 ตัวอักษร",passwordMismatch:"รหัสผ่านที่ยืนยันไม่ตรงกัน",setupTitle:"ตั้งค่าบัญชีของคุณ",setupSubtitle:"เข้าสู่ระบบครั้งแรกสำหรับ ",loginError:"ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง กรุณาลองอีกครั้ง",dashboard:"หน้าหลัก",training:"การฝึก",myDashboard:"ภาพรวมผลการฝึก",adminOverview:"ภาพรวมผู้ดูแล",settings:"การตั้งค่า",account:"บัญชี",profile:"ข้อมูลส่วนตัว",readonly:"อ่านอย่างเดียว",name:"ชื่อที่แสดง",saveProfile:"บันทึกข้อมูล",changePassword:"เปลี่ยนรหัสผ่าน",optional:"ไม่บังคับ",saved:"บันทึกเรียบร้อย",total:"ทั้งหมด",dateRange:"ช่วงเวลา",apply:"กรอง",clear:"ล้าง",hardestPersonas:"บุคคลต้นแบบที่ขายยากที่สุด",closeRate:"อัตราปิดการขาย",managePersonas:"จัดการบุคคลต้นแบบ",difficulty:"ระดับความยาก",trained:"ฝึกแล้ว",addProduct:"เพิ่มสินค้า",trainingSubtitle:"เลือกกลุ่มสินค้า แล้วเลือกบุคคลต้นแบบเพื่อฝึกปิดการขาย",noTraining:"ยังไม่มีกลุ่มฝึก",groups:"กลุ่มบุคคลต้นแบบลูกค้า (Persona)",myTraining:"ประวัติการฝึก",adminTools:"เครื่องมือผู้ดูแลระบบ",users:"ผู้ใช้งาน",analytics:"สถิติ",groupBuilder:"สร้างกลุ่มบุคคลต้นแบบ",create:"สร้าง",analyze:"วิเคราะห์",manual:"ระบุเอง",edit:"แก้ไข",product:"สินค้า/บริการ",segment:"กลุ่มลูกค้าเป้าหมายเบื้องต้น (ไม่บังคับ)",description:"คำอธิบายหรือรายละเอียดเพิ่มเติม (ไม่บังคับ)",channel:"ช่องทางติดต่อ",facebook:"Facebook",line:"LINE",language:"ภาษา",thai:"ไทย",english:"อังกฤษ",personas:"บุคคลต้นแบบ",tierA:"ระดับ A — พร้อมตัดสินใจซื้อ",tierB:"ระดับ B — ยังไม่แน่ใจ",tierC:"ระดับ C — ไม่สนใจแต่มีปัญหา",selectPersona:"เลือกบุคคลต้นแบบเพื่อฝึก",chooseScenario:"เลือกสถานการณ์",chatGuideTitle:"วิธีฝึก",chatGuideText:'คุณรับบทเป็นพนักงานขาย พูดคุยกับลูกค้าคนนี้เพื่อพยายามปิดการขายให้ได้ สอบถามความต้องการ แก้ไขปัญหาของลูกค้า และรับมือกับข้อโต้แย้ง เมื่อพอใจแล้วกด "สรุปผล" เพื่อดูคะแนนและข้อเสนอแนะ',chat:"แชท",start:"เริ่มต้น",send:"ส่ง",finish:"สรุปผล",debrief:"ผลลัพธ์และข้อเสนอแนะ",won:"ปิดการขายได้",lost:"ปิดการขายไม่ได้",notTried:"ยังไม่ได้ฝึก",score:"คะแนน",pain:"ปัญหาของลูกค้า",why:"เหตุผล",reveal:"รายละเอียดบุคคลต้นแบบที่ถูกซ่อนไว้",generatePersona:"สร้างบุคคลต้นแบบเพิ่มเติม",weakAreas:"จุดอ่อนที่ควรฝึกเพิ่มเติม",mySessions:"ประวัติการฝึกของฉัน",openSaleTask:"ลูกค้ายังไม่ได้ทักเข้ามา คุณต้องเป็นฝ่ายเริ่มบทสนทนาการขายเอง",sellerInitiated:"คุณต้องเริ่มการขายในเชิงรุก",customerInitiated:"ลูกค้าจะติดต่อเข้ามาก่อน"}},Ke=Jt({locale:localStorage.getItem("locale")||"th",t(e){return As[this.locale]&&As[this.locale][e]||As.en[e]||e},set(e){this.locale=e,localStorage.setItem("locale",e)}}),wu=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Su={class:"app"},Au={key:0,class:"topnav"},Ru={class:"tabs"},xu={class:"nav-right"},Tu={class:"txt"},Cu={class:"main"},Pu={__name:"App",setup(e){const t=pu();function n(){Ke.set(Ke.locale==="th"?"en":"th")}function s(){Ce.logout(),t.push("/login")}return Wi(()=>{Ce.token&&!Ce.user&&Ce.load()}),(r,i)=>{const o=_r("router-link"),l=_r("router-view");return on(),Tr("div",Su,[ae(Ce).user?(on(),Tr("nav",Au,[ie(o,{to:"/",class:"brand"},{default:Vt(()=>[Ft(Rt(ae(Ke).t("app")),1)]),_:1}),mt("div",Ru,[ae(Ce).isAdmin?(on(),Ds(o,{key:0,to:"/",class:jt(["tab",{active:r.$route.path==="/"}])},{default:Vt(()=>[Ft(Rt(ae(Ke).t("adminOverview")),1)]),_:1},8,["class"])):Cr("",!0),ie(o,{to:"/my/board",class:jt(["tab",{active:r.$route.path==="/my/board"}])},{default:Vt(()=>[Ft(Rt(ae(Ke).t("myDashboard")),1)]),_:1},8,["class"]),ie(o,{to:"/training",class:jt(["tab",{active:r.$route.path==="/training"}])},{default:Vt(()=>[Ft(Rt(ae(Ke).t("training")),1)]),_:1},8,["class"])]),mt("div",xu,[mt("button",{onClick:n,class:"lang"},Rt(ae(Ke).locale==="th"?"EN":"TH"),1),ie(o,{to:"/settings",class:"icon-btn",title:ae(Ke).t("settings")},{default:Vt(()=>[ie(ae(Eu),{size:20,"stroke-width":1.8})]),_:1},8,["title"]),mt("button",{onClick:s,class:"logout-btn"},[ie(ae(bu),{size:18,"stroke-width":1.8}),i[0]||(i[0]=Ft()),mt("span",Tu,Rt(ae(Ke).t("logout")),1)])])])):Cr("",!0),mt("main",Cu,[(on(),Ds(l,{key:ae(Ke).locale}))])])}}},Ou=wu(Pu,[["__scopeId","data-v-f29a3a4f"]]),Iu="modulepreload",Nu=function(e){return"/"+e},ai={},Se=function(t,n,s){let r=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));r=Promise.allSettled(n.map(c=>{if(c=Nu(c),c in ai)return;ai[c]=!0;const f=c.endsWith(".css"),u=f?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${u}`))return;const h=document.createElement("link");if(h.rel=f?"stylesheet":Iu,f||(h.as="script"),h.crossOrigin="",h.href=c,l&&h.setAttribute("nonce",l),document.head.appendChild(h),f)return new Promise((g,m)=>{h.addEventListener("load",g),h.addEventListener("error",()=>m(new Error(`Unable to preload CSS for ${c}`)))})}))}function i(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return r.then(o=>{for(const l of o||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},Mu=[{path:"/login",component:()=>Se(()=>import("./Login-vrbZzr6f.js"),__vite__mapDeps([0,1])),meta:{public:!0}},{path:"/setup",component:()=>Se(()=>import("./Setup-D1N6f_I9.js"),__vite__mapDeps([2,3]))},{path:"/",component:()=>Se(()=>import("./Analytics-z04-C_VZ.js"),__vite__mapDeps([4,5,6,7])),meta:{admin:!0}},{path:"/my/board",component:()=>Se(()=>import("./MyBoard-UPzqfwhQ.js"),__vite__mapDeps([8,9,10]))},{path:"/training",component:()=>Se(()=>import("./Training-CsBkF1Lz.js"),__vite__mapDeps([11,12,13,6,14]))},{path:"/groups/:gid/personas",component:()=>Se(()=>import("./Personas-Dl-F3CRY.js"),__vite__mapDeps([15,12,16,17]))},{path:"/groups/:gid/chat/:pid",component:()=>Se(()=>import("./Chat-DvLKhxgu.js"),__vite__mapDeps([18,12,16,19]))},{path:"/settings",component:()=>Se(()=>import("./Settings-BvwfMyfH.js"),__vite__mapDeps([20,21]))},{path:"/guide",component:()=>Se(()=>import("./Guide-D6Cvcccc.js"),__vite__mapDeps([22,13,9,12,23]))},{path:"/admin/new-group",component:()=>Se(()=>import("./GroupBuilder-DYRYwsrA.js"),__vite__mapDeps([24,16,25])),meta:{admin:!0}},{path:"/admin/groups/:gid/edit",component:()=>Se(()=>import("./GroupEdit-DsLJeZZx.js"),__vite__mapDeps([26,5,23,27])),meta:{admin:!0}},{path:"/admin/users",component:()=>Se(()=>import("./AdminUsers-Cv-dZx8g.js"),__vite__mapDeps([28,5,29])),meta:{admin:!0}},{path:"/admin/analytics",component:()=>Se(()=>import("./Analytics-z04-C_VZ.js"),__vite__mapDeps([4,5,6,7])),meta:{admin:!0}}],Do=hu({history:$a(),routes:Mu});Do.beforeEach(async e=>e.meta.public?!0:(Ce.user||await Ce.load(),Ce.user?Ce.mustSetup&&e.path!=="/setup"?{path:"/setup"}:e.path==="/"&&!Ce.isAdmin?{path:"/my/board"}:e.meta.admin&&!Ce.isAdmin?{path:"/my/board"}:!0:{path:"/login",query:{redirect:e.fullPath}}));ia(Ou).use(Do).mount("#app");export{jt as A,Ds as B,Zs as C,Vu as D,Xc as E,tt as F,Mn as G,Jt as H,Uu as I,Eu as S,wu as _,mt as a,Bu as b,Tr as c,Hu as d,Cr as e,Ce as f,pu as g,ju as h,Ke as i,Ft as j,No as k,Wi as l,ie as m,Vt as n,on as o,Ks as p,Lu as q,dl as r,Ss as s,Rt as t,ae as u,jr as v,Du as w,_r as x,Fu as y,Oe as z}; + */const Eu=No("settings",[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]),Bs="st_token";function Mo(){return localStorage.getItem(Bs)}function ws(e){e?localStorage.setItem(Bs,e):localStorage.removeItem(Bs)}async function ee(e,t,n,s=!1){const r={},i=Mo();i&&(r.Authorization=`Bearer ${i}`);let o=n;!s&&n!==void 0&&n!==null&&(r["Content-Type"]="application/json",o=JSON.stringify(n));const l=await fetch(t,{method:e,headers:r,body:o});let c=null;try{c=await l.json()}catch{}if(!l.ok){const f=c&&(c.error||c.message)||`HTTP ${l.status}`;throw new Error(f)}return c}const Ss={login:(e,t)=>ee("POST","/api/auth/login",{username:e,password:t}),me:()=>ee("GET","/api/auth/me"),setup:e=>ee("POST","/api/auth/setup",e),updateProfile:e=>ee("PATCH","/api/auth/profile",e),adminCreateUser:e=>ee("POST","/api/admin/users",e),adminListUsers:()=>ee("GET","/api/admin/users"),adminUpdateUser:(e,t)=>ee("PUT",`/api/admin/users/${e}`,t),createGroup:e=>ee("POST","/api/groups",e,!0),listGroups:()=>ee("GET","/api/groups"),getGroup:e=>ee("GET",`/api/groups/${e}`),analyzeGroup:e=>ee("POST",`/api/groups/${e}/analyze`),listPersonas:e=>ee("GET",`/api/groups/${e}/personas`),getPersona:(e,t)=>ee("GET",`/api/groups/${e}/personas/${t}`),updatePersona:(e,t,n)=>ee("PUT",`/api/groups/${e}/personas/${t}`,n),chatStart:(e,t,n,s)=>ee("POST",`/api/chat/${e}/personas/${t}/chat/start`,{scenario:n,locale:s}),chatResume:(e,t)=>ee("GET",`/api/chat/${e}/personas/${t}/chat/resume`),chatSend:(e,t,n)=>ee("POST",`/api/chat/${e}/personas/${t}/chat/send`,{text:n}),chatFinish:(e,t)=>ee("POST",`/api/chat/${e}/personas/${t}/chat/finish`),mySessions:()=>ee("GET","/api/chat/sessions"),myBoard:()=>ee("GET","/api/me/board"),weakAreas:()=>ee("GET","/api/me/weak-areas"),myPersonas:()=>ee("GET","/api/me/personas"),generatePersona:e=>ee("POST","/api/me/personas/generate",e),analytics:(e={})=>{const t=new URLSearchParams;e.from&&t.set("from",e.from),e.to&&t.set("to",e.to);const n=t.toString();return ee("GET",`/api/analytics${n?`?${n}`:""}`)}},Ce=Jt({user:null,token:Mo(),mustSetup:!1,get role(){return this.user?this.user.role:null},get isAdmin(){return this.role==="admin"||this.role==="super_admin"},async load(){var e;if(!this.token)return null;try{const t=await Ss.me();return this.user=t.user,this.mustSetup=!!((e=t.user)!=null&&e.must_setup),this.user}catch{return this.user=null,this.mustSetup=!1,ws(null),null}},async login(e,t){const n=await Ss.login(e,t);return this.token=n.token,ws(n.token),this.user=n.user,this.mustSetup=!!n.must_setup,n.user},async finishSetup(e,t){const n=await Ss.setup({username:this.user.username||this.user.id,email:e,password:t});return this.user=n.user,this.mustSetup=!1,n.user},logout(){this.user=null,this.token=null,this.mustSetup=!1,ws(null)}}),As={en:{app:"Sales Trainer",login:"Login",logout:"Logout",username:"Username",email:"Email",password:"Password",newPassword:"New password",confirmPassword:"Confirm password",save:"Save",passwordTooShort:"Password must be at least 4 characters",passwordMismatch:"Passwords do not match",setupTitle:"Set up your account",setupSubtitle:"First login for ",loginError:"Invalid credentials",dashboard:"Dashboard",training:"Training",myDashboard:"My dashboard",adminOverview:"Admin overview",guideTitle:"How to use / คู่มือใช้งาน",settings:"Settings",account:"Account",profile:"Profile",readonly:"read-only",name:"Display name",saveProfile:"Save profile",changePassword:"Change password",optional:"optional",saved:"Saved",total:"Total",dateRange:"Date range",apply:"Apply",clear:"Clear",hardestPersonas:"Hardest personas",closeRate:"Close rate",managePersonas:"Manage personas",difficulty:"Difficulty",trained:"Trained",addProduct:"Add product",trainingSubtitle:"Pick a product group, then choose a persona to practice closing the sale.",noTraining:"No training groups available",groups:"Persona Groups",myTraining:"My Training",adminTools:"Admin Tools",users:"Users",analytics:"Analytics",groupBuilder:"Group Builder",create:"Create",analyze:"Analyze",manual:"Manual",edit:"Edit",product:"Product",segment:"Initial customer segment (optional)",description:"Additional description / scenario (optional)",channel:"Channel",facebook:"Facebook",line:"LINE",language:"Language",thai:"Thai",english:"English",personas:"Personas",tierA:"Tier A — Ready to buy",tierB:"Tier B — Unsure",tierC:"Tier C — Not interested but has pain",selectPersona:"Select a persona to practice",chooseScenario:"Choose a scenario",chatGuideTitle:"How to practice",chatGuideText:'You are playing the salesperson. Chat with this customer and try to close the sale. Ask about their needs, solve their pain, and handle their objections. When you are done, press "Finish & get result" to see your score and coaching.',chat:"Chat",start:"Start",send:"Send",finish:"Finish & get result",debrief:"Result & Coaching",won:"Won",lost:"Lost",notTried:"Not tried",score:"Score",pain:"Pain",why:"Reason",reveal:"Revealed persona details",generatePersona:"Generate my persona",weakAreas:"My weak areas",mySessions:"My sessions",openSaleTask:"The customer did NOT message first. You must open the sale.",sellerInitiated:"You must open the sale (outbound)",customerInitiated:"The customer will message you first"},th:{app:"ระบบฝึกทักษะการขาย",login:"เข้าสู่ระบบ",logout:"ออกจากระบบ",username:"ชื่อผู้ใช้",email:"อีเมล",password:"รหัสผ่าน",newPassword:"รหัสผ่านใหม่",confirmPassword:"ยืนยันรหัสผ่าน",save:"บันทึก",passwordTooShort:"รหัสผ่านต้องมีความยาวอย่างน้อย 4 ตัวอักษร",passwordMismatch:"รหัสผ่านที่ยืนยันไม่ตรงกัน",setupTitle:"ตั้งค่าบัญชีของคุณ",setupSubtitle:"เข้าสู่ระบบครั้งแรกสำหรับ ",loginError:"ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง กรุณาลองอีกครั้ง",dashboard:"หน้าหลัก",training:"การฝึก",myDashboard:"ภาพรวมผลการฝึก",adminOverview:"ภาพรวมผู้ดูแล",settings:"การตั้งค่า",account:"บัญชี",profile:"ข้อมูลส่วนตัว",readonly:"อ่านอย่างเดียว",name:"ชื่อที่แสดง",saveProfile:"บันทึกข้อมูล",changePassword:"เปลี่ยนรหัสผ่าน",optional:"ไม่บังคับ",saved:"บันทึกเรียบร้อย",total:"ทั้งหมด",dateRange:"ช่วงเวลา",apply:"กรอง",clear:"ล้าง",hardestPersonas:"บุคคลต้นแบบที่ขายยากที่สุด",closeRate:"อัตราปิดการขาย",managePersonas:"จัดการบุคคลต้นแบบ",difficulty:"ระดับความยาก",trained:"ฝึกแล้ว",addProduct:"เพิ่มสินค้า",trainingSubtitle:"เลือกกลุ่มสินค้า แล้วเลือกบุคคลต้นแบบเพื่อฝึกปิดการขาย",noTraining:"ยังไม่มีกลุ่มฝึก",groups:"กลุ่มบุคคลต้นแบบลูกค้า (Persona)",myTraining:"ประวัติการฝึก",adminTools:"เครื่องมือผู้ดูแลระบบ",users:"ผู้ใช้งาน",analytics:"สถิติ",groupBuilder:"สร้างกลุ่มบุคคลต้นแบบ",create:"สร้าง",analyze:"วิเคราะห์",manual:"ระบุเอง",edit:"แก้ไข",product:"สินค้า/บริการ",segment:"กลุ่มลูกค้าเป้าหมายเบื้องต้น (ไม่บังคับ)",description:"คำอธิบายหรือรายละเอียดเพิ่มเติม (ไม่บังคับ)",channel:"ช่องทางติดต่อ",facebook:"Facebook",line:"LINE",language:"ภาษา",thai:"ไทย",english:"อังกฤษ",personas:"บุคคลต้นแบบ",tierA:"ระดับ A — พร้อมตัดสินใจซื้อ",tierB:"ระดับ B — ยังไม่แน่ใจ",tierC:"ระดับ C — ไม่สนใจแต่มีปัญหา",selectPersona:"เลือกบุคคลต้นแบบเพื่อฝึก",chooseScenario:"เลือกสถานการณ์",chatGuideTitle:"วิธีฝึก",chatGuideText:'คุณรับบทเป็นพนักงานขาย พูดคุยกับลูกค้าคนนี้เพื่อพยายามปิดการขายให้ได้ สอบถามความต้องการ แก้ไขปัญหาของลูกค้า และรับมือกับข้อโต้แย้ง เมื่อพอใจแล้วกด "สรุปผล" เพื่อดูคะแนนและข้อเสนอแนะ',chat:"แชท",start:"เริ่มต้น",send:"ส่ง",finish:"สรุปผล",debrief:"ผลลัพธ์และข้อเสนอแนะ",won:"ปิดการขายได้",lost:"ปิดการขายไม่ได้",notTried:"ยังไม่ได้ฝึก",score:"คะแนน",pain:"ปัญหาของลูกค้า",why:"เหตุผล",reveal:"รายละเอียดบุคคลต้นแบบที่ถูกซ่อนไว้",generatePersona:"สร้างบุคคลต้นแบบเพิ่มเติม",weakAreas:"จุดอ่อนที่ควรฝึกเพิ่มเติม",mySessions:"ประวัติการฝึกของฉัน",openSaleTask:"ลูกค้ายังไม่ได้ทักเข้ามา คุณต้องเป็นฝ่ายเริ่มบทสนทนาการขายเอง",sellerInitiated:"คุณต้องเริ่มการขายในเชิงรุก",customerInitiated:"ลูกค้าจะติดต่อเข้ามาก่อน"}},Ke=Jt({locale:localStorage.getItem("locale")||"th",t(e){return As[this.locale]&&As[this.locale][e]||As.en[e]||e},set(e){this.locale=e,localStorage.setItem("locale",e)}}),wu=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Su={class:"app"},Au={key:0,class:"topnav"},Ru={class:"tabs"},xu={class:"nav-right"},Tu={class:"txt"},Cu={class:"main"},Pu={__name:"App",setup(e){const t=pu();function n(){Ke.set(Ke.locale==="th"?"en":"th")}function s(){Ce.logout(),t.push("/login")}return Wi(()=>{Ce.token&&!Ce.user&&Ce.load()}),(r,i)=>{const o=_r("router-link"),l=_r("router-view");return on(),Tr("div",Su,[ae(Ce).user?(on(),Tr("nav",Au,[ie(o,{to:"/",class:"brand"},{default:Vt(()=>[Ft(Rt(ae(Ke).t("app")),1)]),_:1}),mt("div",Ru,[ae(Ce).isAdmin?(on(),Ds(o,{key:0,to:"/",class:jt(["tab",{active:r.$route.path==="/"}])},{default:Vt(()=>[Ft(Rt(ae(Ke).t("adminOverview")),1)]),_:1},8,["class"])):Cr("",!0),ie(o,{to:"/my/board",class:jt(["tab",{active:r.$route.path==="/my/board"}])},{default:Vt(()=>[Ft(Rt(ae(Ke).t("myDashboard")),1)]),_:1},8,["class"]),ie(o,{to:"/training",class:jt(["tab",{active:r.$route.path==="/training"}])},{default:Vt(()=>[Ft(Rt(ae(Ke).t("training")),1)]),_:1},8,["class"])]),mt("div",xu,[mt("button",{onClick:n,class:"lang"},Rt(ae(Ke).locale==="th"?"EN":"TH"),1),ie(o,{to:"/settings",class:"icon-btn",title:ae(Ke).t("settings")},{default:Vt(()=>[ie(ae(Eu),{size:20,"stroke-width":1.8})]),_:1},8,["title"]),mt("button",{onClick:s,class:"logout-btn"},[ie(ae(bu),{size:18,"stroke-width":1.8}),i[0]||(i[0]=Ft()),mt("span",Tu,Rt(ae(Ke).t("logout")),1)])])])):Cr("",!0),mt("main",Cu,[(on(),Ds(l,{key:ae(Ke).locale}))])])}}},Ou=wu(Pu,[["__scopeId","data-v-f29a3a4f"]]),Iu="modulepreload",Nu=function(e){return"/"+e},ai={},Se=function(t,n,s){let r=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));r=Promise.allSettled(n.map(c=>{if(c=Nu(c),c in ai)return;ai[c]=!0;const f=c.endsWith(".css"),u=f?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${u}`))return;const h=document.createElement("link");if(h.rel=f?"stylesheet":Iu,f||(h.as="script"),h.crossOrigin="",h.href=c,l&&h.setAttribute("nonce",l),document.head.appendChild(h),f)return new Promise((g,m)=>{h.addEventListener("load",g),h.addEventListener("error",()=>m(new Error(`Unable to preload CSS for ${c}`)))})}))}function i(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return r.then(o=>{for(const l of o||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},Mu=[{path:"/login",component:()=>Se(()=>import("./Login-DxHA8GYa.js"),__vite__mapDeps([0,1])),meta:{public:!0}},{path:"/setup",component:()=>Se(()=>import("./Setup-C_0Y0xY8.js"),__vite__mapDeps([2,3,4]))},{path:"/",component:()=>Se(()=>import("./Analytics-Bkjt0mFt.js"),__vite__mapDeps([5,6,7,8])),meta:{admin:!0}},{path:"/my/board",component:()=>Se(()=>import("./MyBoard-CTHsz6OL.js"),__vite__mapDeps([9,10,11]))},{path:"/training",component:()=>Se(()=>import("./Training-EZ9n5Yut.js"),__vite__mapDeps([12,13,14,7,15]))},{path:"/groups/:gid/personas",component:()=>Se(()=>import("./Personas-CGSsKXxA.js"),__vite__mapDeps([16,13,17,18]))},{path:"/groups/:gid/chat/:pid",component:()=>Se(()=>import("./Chat-DszzTVNw.js"),__vite__mapDeps([19,13,17,20]))},{path:"/settings",component:()=>Se(()=>import("./Settings-CVA3uaSz.js"),__vite__mapDeps([21,3,22]))},{path:"/guide",component:()=>Se(()=>import("./Guide-GzVXirX-.js"),__vite__mapDeps([23,14,10,13,24]))},{path:"/admin/new-group",component:()=>Se(()=>import("./GroupBuilder-CNxYYLnR.js"),__vite__mapDeps([25,17,26])),meta:{admin:!0}},{path:"/admin/groups/:gid/edit",component:()=>Se(()=>import("./GroupEdit-Bq-uo5sC.js"),__vite__mapDeps([27,6,24,28])),meta:{admin:!0}},{path:"/admin/users",component:()=>Se(()=>import("./AdminUsers-B8OP5hvL.js"),__vite__mapDeps([29,6,30])),meta:{admin:!0}},{path:"/admin/analytics",component:()=>Se(()=>import("./Analytics-Bkjt0mFt.js"),__vite__mapDeps([5,6,7,8])),meta:{admin:!0}}],Do=hu({history:$a(),routes:Mu});Do.beforeEach(async e=>e.meta.public?!0:(Ce.user||await Ce.load(),Ce.user?Ce.mustSetup&&e.path!=="/setup"?{path:"/setup"}:e.path==="/"&&!Ce.isAdmin?{path:"/my/board"}:e.meta.admin&&!Ce.isAdmin?{path:"/my/board"}:!0:{path:"/login",query:{redirect:e.fullPath}}));ia(Ou).use(Do).mount("#app");export{Oe as A,jt as B,Zs as C,Vu as D,Xc as E,tt as F,Mn as G,Jt as H,Uu as I,Eu as S,wu as _,Tr as a,mt as b,No as c,Bu as d,Hu as e,Ds as f,Cr as g,Ce as h,Ke as i,pu as j,ju as k,ie as l,Ft as m,Wi as n,on as o,Vt as p,Ks as q,dl as r,Lu as s,Rt as t,ae as u,jr as v,Du as w,Ss as x,_r as y,Fu as z}; diff --git a/frontend/dist/assets/layout-dashboard-C4nLoaIz.js b/frontend/dist/assets/layout-dashboard-CmUmS5d8.js similarity index 91% rename from frontend/dist/assets/layout-dashboard-C4nLoaIz.js rename to frontend/dist/assets/layout-dashboard-CmUmS5d8.js index 889a89d..a2ae215 100644 --- a/frontend/dist/assets/layout-dashboard-C4nLoaIz.js +++ b/frontend/dist/assets/layout-dashboard-CmUmS5d8.js @@ -1,4 +1,4 @@ -import{k as t}from"./index-C0_i8cDF.js";/** +import{c as t}from"./index-DOaJiTJw.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/lock-WqnzR3ED.js b/frontend/dist/assets/lock-WqnzR3ED.js new file mode 100644 index 0000000..d34fd65 --- /dev/null +++ b/frontend/dist/assets/lock-WqnzR3ED.js @@ -0,0 +1,6 @@ +import{c as e}from"./index-DOaJiTJw.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 t=e("lock",[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]]);export{t as L}; diff --git a/frontend/dist/assets/plus-BiLb0OIF.js b/frontend/dist/assets/plus-CODydpxS.js similarity index 86% rename from frontend/dist/assets/plus-BiLb0OIF.js rename to frontend/dist/assets/plus-CODydpxS.js index efc6291..936bbcb 100644 --- a/frontend/dist/assets/plus-BiLb0OIF.js +++ b/frontend/dist/assets/plus-CODydpxS.js @@ -1,4 +1,4 @@ -import{k as e}from"./index-C0_i8cDF.js";/** +import{c as e}from"./index-DOaJiTJw.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/sparkles-D66jVNJm.js b/frontend/dist/assets/sparkles-CwNig9QR.js similarity index 93% rename from frontend/dist/assets/sparkles-D66jVNJm.js rename to frontend/dist/assets/sparkles-CwNig9QR.js index 91fbc03..93f1317 100644 --- a/frontend/dist/assets/sparkles-D66jVNJm.js +++ b/frontend/dist/assets/sparkles-CwNig9QR.js @@ -1,4 +1,4 @@ -import{k as a}from"./index-C0_i8cDF.js";/** +import{c as a}from"./index-DOaJiTJw.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/target-DoOGVGr0.js b/frontend/dist/assets/target-QJk_fUDu.js similarity index 88% rename from frontend/dist/assets/target-DoOGVGr0.js rename to frontend/dist/assets/target-QJk_fUDu.js index 89d3346..21d3b75 100644 --- a/frontend/dist/assets/target-DoOGVGr0.js +++ b/frontend/dist/assets/target-QJk_fUDu.js @@ -1,4 +1,4 @@ -import{k as c}from"./index-C0_i8cDF.js";/** +import{c}from"./index-DOaJiTJw.js";/** * @license lucide-vue-next v1.0.0 - ISC * * This source code is licensed under the ISC license. diff --git a/frontend/dist/assets/users-qxBh6IGP.js b/frontend/dist/assets/users-SQMCzZpr.js similarity index 75% rename from frontend/dist/assets/users-qxBh6IGP.js rename to frontend/dist/assets/users-SQMCzZpr.js index eaf03ed..e499df8 100644 --- a/frontend/dist/assets/users-qxBh6IGP.js +++ b/frontend/dist/assets/users-SQMCzZpr.js @@ -1,6 +1,6 @@ -import{k as e}from"./index-C0_i8cDF.js";/** +import{c as e}from"./index-DOaJiTJw.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 r=e("users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]]);export{r as U}; + */const c=e("users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]]);export{c as U}; diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 79d1ad1..4717b4b 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -4,7 +4,7 @@ Sales Trainer - + diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue index 79ce78f..09e748d 100644 --- a/frontend/src/views/Login.vue +++ b/frontend/src/views/Login.vue @@ -1,19 +1,23 @@