ux(ui): readable persona form instead of raw JSON + step-by-step guides for non-IT users

- 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.
This commit is contained in:
Macky
2026-08-08 10:24:53 +07:00
parent 55759a3a50
commit 39d1aa04e4
25 changed files with 273 additions and 83 deletions

View File

@@ -0,0 +1 @@
import{_ as x,k,c,a as s,t,u as o,i as l,l as m,m as y,w as h,v as f,n as C,e as N,F as V,p as L,q as A,s as B,r as u,o as _}from"./index-B2m5OgR7.js";const S={class:"row",style:{"align-items":"center","margin-bottom":"16px"}},j={style:{margin:"0"}},z={class:"row",style:{"margin-left":"auto",gap:"10px"}},D={class:"users-btn"},F={class:"primary"},M={class:"card filter-bar"},P={class:"muted"},R=["disabled"],T=["disabled"],U={class:"row",style:{gap:"16px",margin:"16px 0"}},W={class:"card stat"},q={class:"card stat"},E={style:{color:"var(--green)"}},I={class:"card stat"},O={style:{color:"var(--red)"}},G={class:"card stat"},H={class:"card stat"},J={class:"card"},K={class:"row",style:{"justify-content":"space-between","align-items":"center"}},Q={class:"bar"},X={class:"muted",style:{"font-size":"12px","margin-top":"6px"}},Y={style:{"margin-top":"20px"}},Z={key:0,class:"card empty-state"},$={class:"grid"},ss={class:"row",style:{"justify-content":"space-between"}},ts={class:"muted"},es={class:"row",style:{"margin-top":"10px",gap:"8px"}},as={class:"badge won"},os={class:"badge lost"},ls={class:"badge not_tried"},ns={class:"muted",style:{"margin-top":"8px"}},is={__name:"Analytics",setup(rs){const a=u({overall:{total_sessions:0,wins:0,losses:0,close_rate:0,avg_score:0},trainee_count:0,hardest_personas:[]}),i=u(""),r=u(""),d=u(!1);async function v(){d.value=!0;try{a.value=await A.analytics({from:i.value,to:r.value})}finally{d.value=!1}}function w(){v()}function b(){i.value="",r.value="",v()}return k(v),(ds,e)=>{const p=B("router-link");return _(),c("div",null,[s("div",S,[s("h2",j,"📊 "+t(o(l).t("adminOverview")),1),s("div",z,[m(p,{to:"/admin/users"},{default:y(()=>[s("button",D,"👥 "+t(o(l).t("users")),1)]),_:1}),m(p,{to:"/admin/new-group"},{default:y(()=>[s("button",F," "+t(o(l).t("addProduct")),1)]),_:1})])]),s("div",M,[s("span",P,"🗓 "+t(o(l).t("dateRange")),1),h(s("input",{type:"date","onUpdate:modelValue":e[0]||(e[0]=n=>i.value=n)},null,512),[[f,i.value]]),e[2]||(e[2]=s("span",null,"",-1)),h(s("input",{type:"date","onUpdate:modelValue":e[1]||(e[1]=n=>r.value=n)},null,512),[[f,r.value]]),s("button",{class:"primary",onClick:w,disabled:d.value},"→ "+t(o(l).t("apply")),9,R),s("button",{onClick:b,disabled:d.value},t(o(l).t("clear")),9,T)]),s("div",U,[s("div",W,[e[3]||(e[3]=s("div",null,"Sessions",-1)),s("strong",null,t(a.value.overall.total_sessions),1)]),s("div",q,[e[4]||(e[4]=s("div",null,"Wins",-1)),s("strong",E,t(a.value.overall.wins),1)]),s("div",I,[e[5]||(e[5]=s("div",null,"Losses",-1)),s("strong",O,t(a.value.overall.losses),1)]),s("div",G,[e[6]||(e[6]=s("div",null,"Avg score",-1)),s("strong",null,t(a.value.overall.avg_score),1)]),s("div",H,[e[7]||(e[7]=s("div",null,"Trainees",-1)),s("strong",null,t(a.value.trainee_count),1)])]),s("div",J,[s("div",K,[s("strong",null,t(o(l).t("closeRate")),1),s("strong",null,t(a.value.overall.close_rate)+"%",1)]),s("div",Q,[s("div",{class:"bar-fill",style:C({width:(a.value.overall.close_rate||0)+"%"})},null,4)]),s("div",X,t(a.value.overall.wins)+" "+t(o(l).t("won").toLowerCase())+" / "+t(a.value.overall.total_sessions)+" sessions ",1)]),s("h3",Y,t(o(l).t("hardestPersonas")),1),a.value.hardest_personas.length===0?(_(),c("div",Z,[...e[8]||(e[8]=[s("strong",null,"No data",-1),s("span",null,"No sessions in this date range.",-1)])])):N("",!0),s("div",$,[(_(!0),c(V,null,L(a.value.hardest_personas,(n,g)=>(_(),c("div",{key:g,class:"card lift tier-card"},[s("div",ss,[s("strong",null,t(n.persona_name),1),s("span",ts,"#"+t(g+1),1)]),s("div",es,[s("span",as,t(n.wins)+"W",1),s("span",os,t(n.losses)+"L",1),s("span",ls,t(n.plays)+" plays",1)]),s("div",ns,t(o(l).t("score"))+": "+t(n.avg_score),1)]))),128))])])}}},us=x(is,[["__scopeId","data-v-9558687f"]]);export{us as default};