- GroupEdit: replace raw JSON persona dump with a labeled, sectioned PersonaForm
(ข้อมูลพื้นฐาน / ข้อมูลลูกค้า / การขาย / ช่องทาง) shown in a modal; admin edits by field.
- New reusable components/PersonaForm.vue.
- GroupBuilder + Personas: add friendly step-by-step guidance cards ('วิธีสร้าง',
'วิธีฝึก') so admins/trainees know what to do at each step.
- Rebuild dist.
5 lines
11 KiB
JavaScript
5 lines
11 KiB
JavaScript
import{_ as G,D as z,o as v,c as f,a as l,t as i,w as s,v as u,C as A,e as c,E as M,r as k,k as D,l as S,m as I,u as T,i as N,j as y,F as P,p as E,G as q,h as J,q as _,s as R,z as F}from"./index-B2m5OgR7.js";const H={class:"persona-form"},K={class:"muted"},Q={class:"sec"},W={class:"row"},X={class:"f"},Y={class:"f"},Z={class:"f"},h={class:"row"},ll={class:"f"},el={class:"f"},nl={class:"f"},tl={class:"sec"},ol={class:"row"},sl={class:"f"},il={class:"f"},al={class:"f"},ul={class:"sec"},rl={class:"sec"},dl={class:"row"},ml={class:"f"},vl={class:"f"},fl={key:0,class:"muted"},gl={class:"row actions"},bl=["disabled"],yl={__name:"PersonaForm",props:{persona:{type:Object,required:!0}},emits:["save","cancel"],setup(w,{emit:L}){const x=w,$=L,t=M({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(""),m=k(""),V=k(!1);function U(n){return Array.isArray(n)?n.join(`
|
|
`):String(n||"")}function C(n){return n.split(`
|
|
`).map(e=>e.trim()).filter(Boolean)}z(()=>x.persona,n=>{Object.assign(t,{name:(n==null?void 0:n.name)||"",difficulty:(n==null?void 0:n.difficulty)??1,tier:(n==null?void 0:n.tier)||"B",profession:(n==null?void 0:n.profession)||"",age_group:(n==null?void 0:n.age_group)||"",location:(n==null?void 0:n.location)||"",income:(n==null?void 0:n.income)||"",budget:(n==null?void 0:n.budget)||"",lifestyle:(n==null?void 0:n.lifestyle)||"",background:(n==null?void 0:n.background)||"",personality:(n==null?void 0:n.personality)||"",communication_style:(n==null?void 0:n.communication_style)||"",goal:(n==null?void 0:n.goal)||"",decision_timeline:(n==null?void 0:n.decision_timeline)||"",opener:(n==null?void 0:n.opener)||"",channel:(n==null?void 0:n.channel)||"line",initiation_mode:(n==null?void 0:n.initiation_mode)||"customer",special:(n==null?void 0:n.special)||""}),d.value=U(n==null?void 0:n.pains),b.value=U(n==null?void 0:n.objections),m.value=U(n==null?void 0:n.negotiation_levers)},{immediate:!0});function B(){$("save",{...t,pains:C(d.value),objections:C(b.value),negotiation_levers:C(m.value)})}return(n,e)=>(v(),f("div",H,[l("h3",null,i(w.persona.name||"New persona"),1),l("p",K,i(w.persona.profession)+" · "+i(w.persona.personality),1),l("div",Q,[e[28]||(e[28]=l("h4",null,"👤 ข้อมูลพื้นฐาน",-1)),l("div",W,[l("div",X,[e[21]||(e[21]=l("label",null,"ชื่อ",-1)),s(l("input",{"onUpdate:modelValue":e[0]||(e[0]=o=>t.name=o)},null,512),[[u,t.name]])]),l("div",Y,[e[22]||(e[22]=l("label",null,"ระดับความยาก (1-5)",-1)),s(l("input",{"onUpdate:modelValue":e[1]||(e[1]=o=>t.difficulty=o),type:"number",min:"1",max:"5"},null,512),[[u,t.difficulty,void 0,{number:!0}]])]),l("div",Z,[e[24]||(e[24]=l("label",null,"ระดับลูกค้า",-1)),s(l("select",{"onUpdate:modelValue":e[2]||(e[2]=o=>t.tier=o)},[...e[23]||(e[23]=[l("option",{value:"A"},"A — พร้อมตัดสินใจซื้อ",-1),l("option",{value:"B"},"B — ยังไม่แน่ใจ",-1),l("option",{value:"C"},"C — ไม่สนใจแต่มีปัญหา",-1)])],512),[[A,t.tier]])])]),l("div",h,[l("div",ll,[e[25]||(e[25]=l("label",null,"อาชีพ",-1)),s(l("input",{"onUpdate:modelValue":e[3]||(e[3]=o=>t.profession=o)},null,512),[[u,t.profession]])]),l("div",el,[e[26]||(e[26]=l("label",null,"ช่วงอายุ",-1)),s(l("input",{"onUpdate:modelValue":e[4]||(e[4]=o=>t.age_group=o)},null,512),[[u,t.age_group]])]),l("div",nl,[e[27]||(e[27]=l("label",null,"พื้นที่",-1)),s(l("input",{"onUpdate:modelValue":e[5]||(e[5]=o=>t.location=o)},null,512),[[u,t.location]])])])]),l("div",tl,[e[32]||(e[32]=l("h4",null,"💼 ข้อมูลลูกค้า",-1)),l("div",ol,[l("div",sl,[e[29]||(e[29]=l("label",null,"รายได้/สถานะการเงิน",-1)),s(l("input",{"onUpdate:modelValue":e[6]||(e[6]=o=>t.income=o)},null,512),[[u,t.income]])]),l("div",il,[e[30]||(e[30]=l("label",null,"งบประมาณ",-1)),s(l("input",{"onUpdate:modelValue":e[7]||(e[7]=o=>t.budget=o)},null,512),[[u,t.budget]])]),l("div",al,[e[31]||(e[31]=l("label",null,"ไลฟ์สไตล์",-1)),s(l("input",{"onUpdate:modelValue":e[8]||(e[8]=o=>t.lifestyle=o)},null,512),[[u,t.lifestyle]])])]),e[33]||(e[33]=l("label",null,"ภูมิหลัง",-1)),s(l("textarea",{"onUpdate:modelValue":e[9]||(e[9]=o=>t.background=o)},null,512),[[u,t.background]]),e[34]||(e[34]=l("label",null,"บุคลิก / วิธีพูดคุย",-1)),s(l("textarea",{"onUpdate:modelValue":e[10]||(e[10]=o=>t.personality=o)},null,512),[[u,t.personality]]),e[35]||(e[35]=l("label",null,"สไตล์การสื่อสาร",-1)),s(l("textarea",{"onUpdate:modelValue":e[11]||(e[11]=o=>t.communication_style=o)},null,512),[[u,t.communication_style]])]),l("div",ul,[e[36]||(e[36]=l("h4",null,"🎯 การขาย",-1)),e[37]||(e[37]=l("label",null,"เป้าหมาย",-1)),s(l("textarea",{"onUpdate:modelValue":e[12]||(e[12]=o=>t.goal=o)},null,512),[[u,t.goal]]),e[38]||(e[38]=l("label",null,"กรอบเวลาในการตัดสินใจ",-1)),s(l("input",{"onUpdate:modelValue":e[13]||(e[13]=o=>t.decision_timeline=o)},null,512),[[u,t.decision_timeline]]),e[39]||(e[39]=l("label",null,"Pain (ปัญหา) แบบ 1 ต่อบรรทัด",-1)),s(l("textarea",{"onUpdate:modelValue":e[14]||(e[14]=o=>d.value=o),placeholder:`เช่น ต้นทุนสูงเกินไป
|
|
ระบบล้าสมัย`},null,512),[[u,d.value]]),e[40]||(e[40]=l("label",null,"ข้อโต้แย้ง (Objections) 1 ต่อบรรทัด",-1)),s(l("textarea",{"onUpdate:modelValue":e[15]||(e[15]=o=>b.value=o)},null,512),[[u,b.value]]),e[41]||(e[41]=l("label",null,"สิ่งที่ใช้ต่อรอง (เช่น ส่วนลด, ฟรีติดตั้ง)",-1)),s(l("textarea",{"onUpdate:modelValue":e[16]||(e[16]=o=>m.value=o)},null,512),[[u,m.value]]),e[42]||(e[42]=l("label",null,"ช่องทางสำหรับลูกค้าเปิดบทสนทนา (opener)",-1)),s(l("textarea",{"onUpdate:modelValue":e[17]||(e[17]=o=>t.opener=o)},null,512),[[u,t.opener]])]),l("div",rl,[e[47]||(e[47]=l("h4",null,"📡 ช่องทาง & โหมด",-1)),l("div",dl,[l("div",ml,[e[44]||(e[44]=l("label",null,"ช่องทาง",-1)),s(l("select",{"onUpdate:modelValue":e[18]||(e[18]=o=>t.channel=o)},[...e[43]||(e[43]=[l("option",{value:"line"},"LINE",-1),l("option",{value:"facebook"},"Facebook",-1)])],512),[[A,t.channel]])]),l("div",vl,[e[46]||(e[46]=l("label",null,"ใครเริ่มคุยก่อน",-1)),s(l("select",{"onUpdate:modelValue":e[19]||(e[19]=o=>t.initiation_mode=o)},[...e[45]||(e[45]=[l("option",{value:"customer"},"ลูกค้าทักก่อน",-1),l("option",{value:"seller"},"เราต้องเริ่มขาย (เชิงรุก)",-1)])],512),[[A,t.initiation_mode]])])]),t.special?(v(),f("label",fl,"พิเศษ: "+i(t.special),1)):c("",!0)]),l("div",gl,[l("button",{class:"primary",onClick:B,disabled:V.value},i(V.value?"กำลังบันทึก…":"💾 บันทึกบุคคลต้นแบบ"),9,bl),l("button",{onClick:e[20]||(e[20]=o=>n.$emit("cancel"))},"ปิด")])]))}},kl=G(yl,[["__scopeId","data-v-738758fc"]]),xl={class:"row",style:{"align-items":"center","margin-bottom":"8px"}},Vl={style:{margin:"0"}},cl={class:"row",style:{"margin-left":"auto",gap:"10px"}},wl=["disabled"],$l={key:0,class:"spinner"},Ul={key:0,class:"muted"},Cl={key:1,class:"error",style:{margin:"12px 0"}},pl={key:2,class:"card empty-state"},_l={class:"grid"},Bl={class:"row",style:{"justify-content":"space-between","align-items":"center"}},jl={class:"diff"},Al={class:"muted"},Nl={class:"muted"},Pl=["onClick"],El={class:"modal"},Ll={__name:"GroupEdit",setup(w){const x=J().params.gid,$=k(null),t=k([]),d=k(!1),b=k(""),m=k(null);async function V(){const a=await _.getGroup(x);$.value=a.group,t.value=(await _.listPersonas(x)).personas}function U(a){return t.value.filter(r=>r.tier===a)}function C(a){return N.t(a==="A"?"tierA":a==="B"?"tierB":"tierC")}function B(a){return{A:"tier-a",B:"tier-b",C:"tier-c"}[a]||""}async function n(){d.value=!0,b.value="";try{const a=await _.analyzeGroup(x);t.value=a.personas,await V()}catch(a){b.value=a.message}finally{d.value=!1}}function e(a){m.value=JSON.parse(JSON.stringify(a))}async function o(a){d.value=!0;try{await _.updatePersona(x,m.value.id,a),m.value=null,await V()}catch(r){b.value=r.message}finally{d.value=!1}}return D(V),(a,r)=>{const O=R("router-link");return v(),f("div",null,[S(O,{to:"/training",class:"btn-back"},{default:I(()=>[y("← "+i(T(N).t("training")),1)]),_:1}),l("div",xl,[l("h2",Vl,"🛠 "+i(T(N).t("managePersonas")),1),l("div",cl,[l("button",{onClick:n,disabled:d.value,class:"primary"},[d.value?(v(),f("span",$l)):c("",!0),y(i(d.value?"กำลังสร้าง…":"✨ สร้าง/วิเคราะห์บุคคลต้นแบบ"),1)],8,wl)])]),$.value?(v(),f("p",Ul,[r[2]||(r[2]=y("สินค้า: ",-1)),l("strong",null,i($.value.title),1)])):c("",!0),b.value?(v(),f("div",Cl,i(b.value),1)):c("",!0),r[4]||(r[4]=l("div",{class:"card guide"},[l("strong",null,"วิธีใช้หน้านี้"),l("ol",{style:{margin:"8px 0 0","padding-left":"20px","line-height":"1.8"}},[l("li",null,[y("กดปุ่ม "),l("strong",null,"✨ สร้าง/วิเคราะห์บุคคลต้นแบบ"),y(" เพื่อให้ระบบสร้างลูกค้าจำลอง 15 คน (ระดับ A/B/C)")]),l("li",null,[y("แต่ละการ์ดคือลูกค้าจำลอง 1 คน — กด "),l("strong",null,"✏️ แก้ไข"),y(" เพื่อปรับรายละเอียดให้ตรงใจ")]),l("li",null,[y("เมื่อพร้อมให้ผู้ใช้ฝึก กด "),l("strong",null,"เปิดใช้งาน"),y(" (ยังทำในขั้นถัดไป)")])])],-1)),t.value.length===0&&!d.value?(v(),f("div",pl,[...r[3]||(r[3]=[l("strong",null,"ยังไม่มีบุคคลต้นแบบ",-1),l("span",null,'กด "✨ สร้าง/วิเคราะห์บุคคลต้นแบบ" เพื่อให้ระบบสร้างลูกค้าจำลองให้',-1)])])):c("",!0),(v(),f(P,null,E(["A","B","C"],p=>l("div",{key:p,style:{"margin-bottom":"20px"}},[l("h4",null,i(C(p)),1),l("div",_l,[(v(!0),f(P,null,E(U(p),g=>(v(),f("div",{key:g.id,class:"card pcard"},[l("div",Bl,[l("strong",null,i(g.name),1),l("span",{class:F(["badge",B(g.tier)])},i(g.tier),3)]),l("div",jl,[(v(),f(P,null,E(5,j=>l("span",{key:j,class:F(["star",{on:j<=(g.difficulty||1)}])},"★",2)),64))]),l("div",Al,i(g.profession)+" · "+i(g.age_group)+" · "+i(g.location),1),l("div",Nl,i(g.channel)+" · "+i(g.initiation_mode==="seller"?"เริ่มขายเอง":"ลูกค้าทักก่อน"),1),l("button",{class:"edit-btn",onClick:j=>e(g)},"✏️ แก้ไขรายละเอียด",8,Pl)]))),128))])])),64)),m.value?(v(),f("div",{key:3,class:"modal-backdrop",onClick:r[1]||(r[1]=q(p=>m.value=null,["self"]))},[l("div",El,[S(kl,{persona:m.value,onSave:o,onCancel:r[0]||(r[0]=p=>m.value=null)},null,8,["persona"])])])):c("",!0)])}}},Tl=G(Ll,[["__scopeId","data-v-812ba03f"]]);export{Tl as default};
|