feat(ui): 3-tab layout (Admin overview / My dashboard / Training) + Settings page

- App.vue: top tab bar (Admin overview [admin], My dashboard, Training) + Settings icon
- router: / = admin overview, /my/board, /training, /settings; non-admin '/' -> /my/board
- New views: Training.vue (pick ready product group -> personas), MyBoard.vue (win/lose +
  sessions summary), Settings.vue (change email/password, language)
- Backend: allow /api/me/board + /api/chat/sessions for any authenticated user (so the
  My dashboard tab works for admins too), not just 'user' role
- i18n EN/TH keys; rebuilt frontend/dist
Verified: build ok, /api/me/board + /api/chat/sessions + /api/groups all 200 for admin.
This commit is contained in:
Macky
2026-08-07 22:07:16 +07:00
parent aec596d1d6
commit ac35be8906
32 changed files with 308 additions and 61 deletions

View File

@@ -0,0 +1 @@
import{_ as m,k as y,l as v,c as r,a as t,t as n,u as d,i as u,e as g,F as f,p as k,r as c,q as x,o,x as h,n as b,s as w}from"./index-EpRXsI-R.js";const N={key:0,class:"card",style:{"min-height":"80px"}},B={key:1,class:"card empty-state"},C={class:"grid"},F={class:"card lift train-card"},P={class:"row",style:{"justify-content":"space-between"}},T={class:"muted",style:{margin:"6px 0 12px"}},V={class:"primary",style:{width:"100%","margin-top":"12px"}},j={__name:"Training",setup(q){const l=c([]),i=c(!0);function p(e){return e.sales_kit&&e.sales_kit.productName||e.input&&e.input.product||""}return y(async()=>{try{const e=(await v.listGroups()).groups||[];l.value=e.filter(s=>s.status==="ready")}finally{i.value=!1}}),(e,s)=>{const _=x("router-link");return o(),r("div",null,[t("h2",null,"🎯 "+n(d(u).t("training")),1),s[3]||(s[3]=t("p",{class:"muted"},"Pick a product group to practice closing a sale.",-1)),i.value?(o(),r("div",N,[...s[0]||(s[0]=[t("div",{class:"skeleton",style:{height:"50px"}},null,-1)])])):l.value.length===0?(o(),r("div",B,[...s[1]||(s[1]=[t("strong",null,"No training groups available",-1),t("span",null,"Ask an admin to create a persona group first.",-1)])])):g("",!0),t("div",C,[(o(!0),r(f,null,k(l.value,a=>(o(),h(_,{key:a.id,to:`/groups/${a.id}/personas`,style:{"text-decoration":"none"}},{default:b(()=>[t("div",F,[t("div",P,[t("strong",null,n(a.title),1),s[2]||(s[2]=t("span",{class:"badge ready"},"ready",-1))]),t("div",T,n(p(a)),1),t("div",{class:w(["badge",a.channel])},n(a.channel||"line"),3),t("button",V,n(d(u).t("selectPersona")),1)])]),_:2},1032,["to"]))),128))])])}}},A=m(j,[["__scopeId","data-v-493baf1e"]]);export{A as default};