feat(ui): 3-tab UI per spec — admin dashboard + date filter, personal dashboard, training w/ difficulty, settings profile
Tab 1 Admin overview (/): aggregate stats + DATE FILTER (?from&to), hardest personas, admin quick actions (Users / + Add product). Tab 2 My dashboard (/my/board): per-user win/lose/session summary (works for admin too). Tab 3 Training (/training): product list w/ status + persona count; admins see all groups (draft->analyze/edit), trainees see ready->personas; persona list shows DIFFICULTY (1-5 stars); admins get a Manage-personas button. Settings (/settings): profile (name/email) via new PATCH /api/auth/profile + change password + language. Backend: analytics date filter; profile endpoint; /api/me/board + /api/chat/sessions opened to any authed user. Rebuilt frontend/dist.
This commit is contained in:
1
frontend/dist/assets/GroupBuilder-BmWUlUx8.js
vendored
Normal file
1
frontend/dist/assets/GroupBuilder-BmWUlUx8.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{c as g,a as e,t as l,u as o,i as n,w as r,v,B as m,e as x,r as p,g as k,o as f,p as w}from"./index-Hx407ukZ.js";const V={class:"card"},B={class:"row"},U={style:{flex:"1"}},C={value:"facebook"},D={value:"line"},F={style:{flex:"1"}},S={value:"th"},E={value:"en"},G={key:0,class:"error"},M=["disabled"],O={__name:"GroupBuilder",setup(N){const h=k(),t=p({product:"",segment:"",description:"",channel:"facebook",language:"th"}),c=p([]),d=p(""),i=p(!1);function _(a){c.value=Array.from(a.target.files||[])}async function b(){i.value=!0,d.value="";try{const a=new FormData;a.append("product",t.value.product),a.append("segment",t.value.segment),a.append("description",t.value.description),a.append("channel",t.value.channel),a.append("language",t.value.language),c.value.forEach(y=>a.append("files",y));const u=(await w.createGroup(a)).group.id;h.push(`/admin/groups/${u}/edit`)}catch(a){d.value=a.message}finally{i.value=!1}}return(a,s)=>(f(),g("div",V,[e("h2",null,l(o(n).t("groupBuilder")),1),e("label",null,l(o(n).t("product")),1),r(e("textarea",{"onUpdate:modelValue":s[0]||(s[0]=u=>t.value.product=u),rows:"3",placeholder:"e.g. Cloud POS for small restaurants"},null,512),[[v,t.value.product]]),e("label",null,l(o(n).t("segment")),1),r(e("input",{"onUpdate:modelValue":s[1]||(s[1]=u=>t.value.segment=u)},null,512),[[v,t.value.segment]]),e("label",null,l(o(n).t("description")),1),r(e("textarea",{"onUpdate:modelValue":s[2]||(s[2]=u=>t.value.description=u),rows:"3"},null,512),[[v,t.value.description]]),e("div",B,[e("div",U,[e("label",null,l(o(n).t("channel")),1),r(e("select",{"onUpdate:modelValue":s[3]||(s[3]=u=>t.value.channel=u)},[e("option",C,l(o(n).t("facebook")),1),e("option",D,l(o(n).t("line")),1)],512),[[m,t.value.channel]])]),e("div",F,[e("label",null,l(o(n).t("language")),1),r(e("select",{"onUpdate:modelValue":s[4]||(s[4]=u=>t.value.language=u)},[e("option",S,l(o(n).t("thai")),1),e("option",E,l(o(n).t("english")),1)],512),[[m,t.value.language]])])]),e("label",null,"📎 Files (.pdf/.md/.txt) — "+l(o(n).t("product"))+" can come from here",1),e("input",{type:"file",multiple:"",accept:".pdf,.md,.txt",onChange:_},null,32),d.value?(f(),g("div",G,l(d.value),1)):x("",!0),e("button",{class:"primary",style:{"margin-top":"16px"},disabled:i.value||!t.value.product&&!c.value.length,onClick:b},l(i.value?"...":o(n).t("create")),9,M)]))}};export{O as default};
|
||||
Reference in New Issue
Block a user