PageSourceSearch

https://app.my-voice.ai/assets/TherapistDashboard-CUbLT9wD.js

js my-voice.ai collected 2026-10-05 14:18:01 UTC 14,155 bytes, 6 lines download raw bytes

1import{c as R,r as a,b as m,j as e,d as $,h as N,ah as H}from"./index-D1KjZIYs.js";import{P as M,a as V,b as L,c as O,d as U,e as G}from"./PatientVoice-BclUEAPc.js";import{S as q}from"./shield-check-JIZbAzZD.js";import{R as J,U as K,C as Q}from"./users-BZgMfiSq.js";import{A as X}from"./activity-DDuL7pQz.js";import"./FillMissingSymbols-D6S06wuU.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const Y=R("CircleCheck",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);function Z({patientId:s}){const[n,g]=a.useState(null);if(a.useEffect(()=>{let l=!1;return m.get(`/activity/completeness/${s}`).then(i=>{l||g(i)}).catch(()=>{l||g(null)}),()=>{l=!0}},[s]),!(n!=null&&n.may_be_incomplete))return null;const c=n.devices.filter(l=>l.stale);return e.jsxs("div",{role:"status","data-testid":"session-incomplete",dir:"rtl",style:{margin:"12px 0",padding:"14px 16px",borderRadius:12,background:"#FEF3C7",border:"1px solid #FCD34D",color:"#78350F",fontSize:15,lineHeight:1.6},children:[e.jsx("strong",{style:{display:"block",marginBlockEnd:6},children:"ייתכן שהתיעוד חלקי"}),e.jsxs("p",{style:{margin:0},children:[c.length===1?"מכשיר אחד לא דיווח":`${c.length} מכשירים לא דיווחו`," ","ביותר מ־",n.stale_after_hours," שעות. פערים בציר הזמן עשויים לנבוע מכך שהמכשיר לא התחבר לרשת — ולא מכך שהילד/ה לא תקשר/ה."]}),e.jsx("ul",{style:{margin:"8px 0 0",paddingInlineStart:20,fontSize:13},children:c.map(l=>e.jsxs("li",{children:[l.device_id.slice(0,12),"… — נשמע לאחרונה"," ",new Date(l.last_received_at).toLocaleString()]},l.device_id))})]})}function ee({patientId:s}){const[n,g]=a.useState(null);return a.useEffect(()=>{let c=!1;return m.get(`/activity/exploration/${s}`).then(l=>{c||g(l)}).catch(()=>{c||g(null)}),()=>{c=!0}},[s]),!n||n.explored_touches===0?null:e.jsxs("section",{"data-testid":"exploration-context",dir:"rtl",style:{margin:"16px 0",padding:16,borderRadius:12,background:"#F8FAFC",border:"1px dashed #CBD5E1",color:"#475569"},children:[e.jsx("h3",{style:{margin:"0 0 4px",fontSize:15,color:"#334155"},children:"נגיעות שלא הפכו למשפט"}),e.jsxs("p",{"data-testid":"exploration-ratio",style:{margin:"0 0 6px",fontSize:15,color:"#334155"},children:[e.jsx("strong",{children:n.explored_touches})," נגיעות ב־",e.jsx("strong",{children:n.explored_distinct})," סמלים שונים לא הפכו למשפט, מול ",e.jsx("strong",{children:n.spoken_sentences})," משפטים שנאמרו ב־",n.days," הימים האחרונים."]}),e.jsxs("p",{style:{margin:0,fontSize:13,lineHeight:1.6},children:["הקשר בלבד — ",e.jsx("strong",{children:"לא נספר באף מדד"}),". ילד/ה שקיבל/ה את הטאבלט באמצע שיעור עשוי/ה לחקור את הממשק ולא לחפש מילה מסוימת. אילו סמלים — בתוך מפגש שפתחתם, ברצועת המפגש."]})]})}const u={background:"#FFFFFF",border:"1px solid #E2E8F0",borderRadius:8,boxShadow:"0 8px 22px rgba(15, 23, 42, 0.07)",padding:18},te={...u,display:"flex",flexDirection:"column",gap:8,minHeight:112},se=()=>e.jsxs("div",{className:"animate-pulse flex flex-col gap-4",children:[e.jsx("div",{className:"h-6 bg-slate-200 rounded w-1/3"}),e.jsx("div",{className:"h-4 bg-slate-200 rounded w-full"}),e.jsx("div",{className:"h-4 bg-slate-200 rounded w-5/6"}),e.jsx("div",{className:"h-4 bg-slate-200 rounded w-4/6"}),e.jsxs("div",{className:"flex flex-col gap-2 mt-4",children:[e.jsx("div",{className:"h-5 bg-slate-200 rounded w-1/4"}),e.jsx("div",{className:"h-4 bg-slate-200 rounded w-full"}),e.jsx("div",{className:"h-4 bg-slate-200 rounded w-11/12"})]})]});function de(){const{t:s,locale:n}=$(),g=N(),[c,l]=a.useState([]),[i,k]=a.useState(null),[o,D]=a.useState(null),[r,z]=a.useState(null),[F,b]=a.useState(!1),[_,f]=a.useState(""),[C,B]=a.useState(""),[W,v]=a.useState(!1),y=a.useRef(null);a.useEffect(()=>()=>{y.current&&y.current.close()},[]),a.useEffect(()=>{let t=!1;async function d(){try{const h=await m.get("/therapist/patients");if(t)return;l(h),k(p=>{var x;return p||((x=h[0])==null?void 0:x.id)||null})}catch(h){t||f(h instanceof Error?h.message:"Failed to load patients")}}return d(),()=>{t=!0}},[]);async function E(t=i){if(t){b(!0),f(""),B(""),v(!0),y.current&&y.current.close();try{const[d,h]=await Promise.all([m.get(`/therapist/patients/${t}/stats`),m.get(`/therapist/patients/${t}/cds-insights`)]);D(d),z(h),b(!1);const p=new EventSource(`/api/therapist/patients/${t}/ai-insights-stream`,{withCredentials:!0});y.current=p,p.onmessage=x=>{if(x.data==="[DONE]")p.close(),v(!1);else try{const w=JSON.parse(x.data);B(P=>P+w)}catch(w){console.error("Error parsing SSE chunk:",w)}},p.onerror=x=>{console.error("SSE Error:",x),p.close(),v(!1)}}catch(d){f(d instanceof Error?d.message:"Failed to load dashboard"),v(!1),b(!1)}}}a.useEffect(()=>{E(i)},[i]);
6const[S,I]=a.useState(!1);async function A(t){if(!(!i||S)){I(!0);try{await m.put(`/therapist/patients/${i}/gender`,{gender:t}),l(await m.get("/therapist/patients"))}catch{f(s("cds.error"))}finally{I(!1)}}}const j=a.useMemo(()=>c.find(t=>t.id===i)||null,[c,i]),T=(r==null?void 0:r.vocabulary_in_use)??(o==null?void 0:o.vocabulary_in_use)??0;return e.jsx("div",{style:{minHeight:"100dvh",background:"#F8FAFC",color:"#172033",direction:n==="he"?"rtl":"ltr"},children:e.jsxs("main",{style:{maxWidth:1180,margin:"0 auto",padding:"20px 12px 32px"},children:[e.jsxs("header",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:16,marginBottom:24},children:[e.jsxs("div",{children:[e.jsx("button",{className:"btn-nav",onClick:()=>g("/"),style:{marginBottom:18},children:s("common.back")}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,color:"#6D28D9",fontWeight:800,marginBottom:8},children:[e.jsx(q,{size:20}),s("cds.decisionSupportOnly")]}),e.jsx("h1",{style:{margin:0,fontSize:"clamp(32px, 5vw, 54px)",fontWeight:900,color:"#2E2459"},children:s("cds.title")}),e.jsx("p",{style:{maxWidth:760,color:"#64748B",fontSize:18,lineHeight:1.6},children:s("cds.subtitle")})]}),e.jsxs("button",{onClick:()=>void E(),disabled:F||!i,style:{minHeight:52,padding:"0 20px",borderRadius:8,border:"1px solid #C4B5FD",background:"#FFFFFF",color:"#5B21B6",fontWeight:800,display:"inline-flex",alignItems:"center",gap:8,cursor:F?"wait":"pointer"},children:[e.jsx(J,{size:18}),s("cds.refresh")]})]}),e.jsxs("section",{style:{...u,marginBottom:18},children:[e.jsx("label",{style:{display:"block",fontWeight:800,marginBottom:8},children:s("cds.patientSelect")}),c.length?e.jsx("select",{value:i||"",onChange:t=>k(Number(t.target.value)||null),style:{width:"100%",minHeight:48,borderRadius:8,border:"1px solid #CBD5E1",padding:"0 12px",fontWeight:700},children:c.map(t=>e.jsx("option",{value:t.id,children:t.name||t.email},t.id))}):e.jsx("div",{style:{color:"#64748B"},children:s("cds.noPatients")}),(j==null?void 0:j.needs_gender)&&e.jsxs("div",{style:{marginTop:14,padding:14,borderRadius:12,background:"#FEF3C7",border:"1px solid #FCD34D"},children:[e.jsx("div",{style:{fontWeight:800,marginBottom:4},children:"בחר קול — הגדר מין המשתמש"}),e.jsx("p",{style:{margin:"0 0 10px",fontSize:14,color:"#78350F"},children:"ללא הגדרה, המכשיר מדבר בלשון זכר כברירת מחדל — גם אם היא אינה מתאימה. ההגדרה משפיעה על הקול, על הטיית הפעלים ועל התאמת המשפטים."}),e.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[["female","נקבה"],["male","זכר"],["unspecified","לא לציין"]].map(([t,d])=>e.jsx("button",{type:"button",disabled:S,onClick:()=>void A(t),style:{minHeight:64,minWidth:96,padding:"0 18px",borderRadius:12,border:"1.5px solid #D97706",background:"#fff",color:"#78350F",fontWeight:800,fontFamily:"inherit",fontSize:16,cursor:S?"wait":"pointer"},children:d},t))})]})]}),_&&e.jsx("div",{style:{...u,borderColor:"#FCA5A5",color:"#B91C1C",marginBottom:18},children:_}),j&&o&&e.jsxs(e.Fragment,{children:[e.jsx("section",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(min(100%, 180px), 1fr))",gap:14,marginBottom:18},children:[{icon:K,label:s("cds.sessionsThisWeek"),value:o.sessions_this_week},{icon:X,label:s("cds.wordsToday"),value:o.words_today},{icon:Q,label:s("cds.wordsThisWeek"),value:o.total_words_week},{icon:Y,label:s("cds.completedTasks"),value:`${o.tasks_completed}/${o.tasks_total}`}].map(t=>{const d=t.icon;return e.jsxs("div",{style:te,children:[e.jsx(d,{size:24,color:"#6D28D9"}),e.jsx("div",{style:{fontSize:30,fontWeight:900},children:t.value}),e.jsx("div",{style:{color:"#64748B",fontWeight:700},children:t.label})]},t.label)})}),i!=null&&e.jsx(Z,{patientId:i}),i!=null&&e.jsx(ee,{patientId:i}),i!=null&&e.jsxs("section",{style:{...u,marginBottom:18},children:[e.jsx(M,{patientId:i}),e.jsx(V,{patientId:i}),e.jsx(L,{patientId:i}),e.jsx(O,{patientId:i}),e.jsx(U,{patientId:i}),e.jsx(G,{patientId:i})]}),o&&e.jsxs("section",{style:{...u,marginBottom:18},children:[e.jsx("h2",{style:{marginTop:0,marginBottom:12,fontSize:18,color:"#334155"},children:s("cds.activityViz")||"Activity Visualization"}),e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:24},children:[o.daily_activity&&o.daily_activity.length>0&&e.jsxs("div",{style:{flex:"1 1 300px",minWidth:260},children:[e.jsx("div",{style:{fontWeight:700,marginBottom:8,color:"#475569"},children:s("cds.dailyActivity")||"Daily Activity (last 7 days)"}),e.jsx("div",{style:{display:"flex",alignItems:"flex-end",height:90,gap:6,borderBottom:"1px solid #E2E8F0",paddingBottom:4},children:o.daily_activity.map((t,d)=>{const h=Math.max(...o.daily_activity.map(x=>x.count),1),p=Math.max(8,Math.round(t.count/h*80));return e.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",minWidth:28},children:[e.jsx("div",{title:`${t.date}: ${t.count}`,style:{width:"100%",maxWidth:32,height:p,background:"#7C3AED",borderRadius:3,transition:"height .2s"}}
6),e.jsx("div",{style:{fontSize:10,color:"#64748B",marginTop:4,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",width:"100%",textAlign:"center"},children:new Date(t.date).toLocaleDateString(n==="he"?"he-IL":"en-US",{month:"numeric",day:"numeric"})})]},d)})})]}),(r==null?void 0:r.peak_activity_hours)&&r.peak_activity_hours.length>0&&e.jsxs("div",{style:{flex:"1 1 240px",minWidth:200},children:[e.jsx("div",{style:{fontWeight:700,marginBottom:8,color:"#475569"},children:s("cds.peakHoursViz")||"Peak Activity Hours"}),r.peak_activity_hours.map((t,d)=>{const h=Math.max(...r.peak_activity_hours.map(x=>x.count),1),p=Math.round(t.count/h*100);return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:6},children:[e.jsx("div",{style:{width:42,fontSize:12,color:"#64748B"},children:`${String(t.hour).padStart(2,"0")}:00`}),e.jsx("div",{style:{flex:1,background:"#E0E7FF",borderRadius:4,height:18,position:"relative"},children:e.jsx("div",{style:{width:`${p}%`,height:"100%",background:"#6366F1",borderRadius:4,transition:"width .3s"}})}),e.jsx("div",{style:{width:28,fontSize:12,fontWeight:600,color:"#4F46E5"},children:t.count})]},d)})]})]}),e.jsx("p",{style:{fontSize:11,color:"#94A3B8",marginTop:8},children:s("cds.vizNote")||"Visual trends help therapists identify patterns for AAC support planning."})]}),e.jsxs("section",{style:{...u,marginBottom:18,border:"2px solid #E2E8F0"},children:[e.jsxs("h2",{style:{marginTop:0,display:"flex",alignItems:"center",gap:8,color:"#4C1D95"},children:["✨ ",s("cds.aiInsights")||"AI Clinical Insights"]}),W&&!C?e.jsx(se,{}):e.jsx("div",{style:{whiteSpace:"pre-wrap",lineHeight:1.6,color:"#334155"},children:C})]}),e.jsxs("section",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(min(100%, 240px), 1fr))",gap:14},children:[e.jsxs("div",{style:u,children:[e.jsx("h2",{style:{marginTop:0},children:n==="he"?"אוצר מילים בשימוש":"Vocabulary in use"}),e.jsx("p",{"data-testid":"vocabulary-in-use",style:{margin:0,fontSize:28,fontWeight:800,color:"#4F46E5"},children:T}),e.jsx("p",{style:{color:"#64748B",margin:"6px 0 0"},children:n==="he"?"מילים שונות השבוע. המילים עצמן — בתוך מפגש מתועד.":"distinct words this week. The words themselves — inside a recorded session."})]}),e.jsxs("div",{style:u,children:[e.jsx("h2",{style:{marginTop:0},children:s("cds.peakHours")}),r!=null&&r.peak_activity_hours.length?r.peak_activity_hours.map(t=>e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"10px 0",borderBottom:"1px solid #F1F5F9"},children:[e.jsx(H,{size:18,color:"#7C3AED"}),e.jsx("strong",{children:`${String(t.hour).padStart(2,"0")}:00`}),e.jsxs("span",{style:{color:"#64748B"},children:[t.count," ",s("cds.events")]})]},t.hour)):e.jsx("p",{style:{color:"#64748B"},children:s("cds.emptyData")})]}),e.jsxs("div",{style:u,children:[e.jsx("h2",{style:{marginTop:0},children:s("cds.reviewQueue")}),e.jsx("p",{"data-testid":"review-pointer",style:{color:"#64748B",margin:0,lineHeight:1.6},children:n==="he"?"ההמלצות האוטומטיות הוסרו — הן נגזרו מתדירות בלבד. מה לבדוק נקבע בסקירת 30 הימים.":"Automatic recommendations were removed — they were derived from frequency alone. What to review is decided by the 30-day review."})]})]}),e.jsxs("section",{style:{...u,marginTop:14},children:[e.jsx("h2",{style:{marginTop:0},children:s("cds.recentSentences")}),e.jsx("p",{"data-testid":"sentences-in-session",style:{color:"#64748B",margin:0},children:n==="he"?`${(r==null?void 0:r.sentences_spoken)??0} משפטים נאמרו השבוע. המשפטים עצמם מוצגים רק בתוך מפגש מתועד.`:`${(r==null?void 0:r.sentences_spoken)??0} sentences spoken this week. The sentences themselves appear only inside a recorded session.`})]})]})]})})}export{de as TherapistDashboard};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.