PageSourceSearch

https://digitalbehandling.se/assets/Statistics-Bs7yU7rI.js

js digitalbehandling.se collected 2026-09-30 08:26:29 UTC 78,316 bytes, 24 lines download raw bytes

1import{a0 as ie,j as e,U as Re,d5 as Ie,ei as Ke,C as b,c as k,d as w,a as _,aS as L,aT as T,aU as N,aV as d,aW as M,aX as c,r as g,l as C,e as O,s as Q,cY as be,cZ as _e,B as P,k as ve,E as ye,c$ as ke,L as at,m as we,aL as De,cB as qe,cC as Oe,cD as Be,ad as le,cE as Ue,eB as nt,ha as it,hc as lt,he as dt,ac as ct,a2 as I,h as V,aZ as Ge,d1 as ot,ae as X,a_ as mt,n as ee,b2 as xt,ci as ut,b1 as ht,x as gt,bL as ft,aA as pt,b as jt,I as Nt,bn as bt,g as _t,A as vt,aH as yt,aI as kt,aJ as wt,aK as Z}from"./index-CobRY8C4.js";import{T as Ve}from"./trending-up-Ugz6L0_X.js";import{E as Se,M as Ee}from"./types-BTnUriPV.js";import{F as St}from"./filter-CnkHemX1.js";import{ensurePdfMake as Et}from"./pdfmakeSetup-jY1X3cRL.js";import{D as ze}from"./download-3GrjRmzB.js";import{G as At}from"./globe-B6XoPFpG.js";import{p as He,a as Ae}from"./vfs_fonts-BwDagwDl.js";import{C as Ct}from"./crown-BZWv7_J5.js";import{u as Lt}from"./useLovableAi-C6SrlLm6.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 Tt=ie("Map",[["path",{d:"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z",key:"169xi5"}],["path",{d:"M15 5.764v15",key:"1pn4in"}],["path",{d:"M9 3.236v15",key:"1uimfh"}]]);/**
7 * @license lucide-react v0.462.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const Mt=ie("MessageSquareHeart",[["path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",key:"1lielz"}],["path",{d:"M14.8 7.5a1.84 1.84 0 0 0-2.6 0l-.2.3-.3-.3a1.84 1.84 0 1 0-2.4 2.8L12 13l2.7-2.7c.9-.9.8-2.1.1-2.8",key:"1blaws"}]]);/**
12 * @license lucide-react v0.462.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const Pt=ie("Network",[["rect",{x:"16",y:"16",width:"6",height:"6",rx:"1",key:"4q2zg0"}],["rect",{x:"2",y:"16",width:"6",height:"6",rx:"1",key:"8cvhb9"}],["rect",{x:"9",y:"2",width:"6",height:"6",rx:"1",key:"1egb70"}],["path",{d:"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3",key:"1jsf9p"}],["path",{d:"M12 12V8",key:"2874zd"}]]);/**
17 * @license lucide-react v0.462.0 - ISC
18 *
19 * This source code is licensed under the ISC license.
20 * See the LICENSE file in the root directory of this source tree.
21 */const $t=ie("Table",[["path",{d:"M12 3v18",key:"108xh3"}],["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M3 15h18",key:"5xshup"}]]),Ft="—",Rt="Maskerat: färre än 5 individer (k-anonymitet)";function U({label:t,value:r,Icon:s,isRate:a=!1,masked:n=!1}){const i=r===null?Ft:a?`${r}%`:String(r);return e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(w,{className:"text-sm font-medium text-muted-foreground",children:t}),e.jsx(s,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx(_,{children:e.jsx("div",{className:"text-2xl font-bold",style:!n&&r!==null&&a&&r>0?{color:"hsl(var(--primary))"}:void 0,title:r===null||n?Rt:void 0,children:i})})]})}function ae({active:t,aftercare:r,inactiveTotal:s,completionRate:a}){return e.jsxs("div",{className:"grid gap-4 md:grid-cols-4",children:[e.jsx(U,{label:"Aktiva klienter",value:t,Icon:Re}),e.jsx(U,{label:"Eftervård",value:r,Icon:Ie}),e.jsx(U,{label:"Inaktiva klienter",value:s,Icon:Ke}),e.jsx(U,{label:"Genomförandegrad",value:s===0?null:a,Icon:Ve,isRate:!0,masked:s===0})]})}function It({active:t,aftercare:r,inactiveTotal:s,completionRate:a}){return e.jsxs("div",{className:"grid gap-4 md:grid-cols-4",children:[e.jsx(U,{label:"Aktiva klienter",value:t,Icon:Re}),e.jsx(U,{label:"Eftervård",value:r,Icon:Ie}),e.jsx(U,{label:"Inaktiva klienter",value:s,Icon:Ke}),e.jsx(U,{label:"Genomförandegrad",value:a,Icon:Ve,isRate:!0})]})}function Ce({title:t,items:r,labelMap:s}){const a=Math.max(...r.map(i=>i.count),1),n=r.reduce((i,o)=>i+o.count,0);return e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:t})}),e.jsx(_,{className:"space-y-3",children:r.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Ingen data."}):r.sort((i,o)=>o.count-i.count).map(i=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{children:s[i.label]??i.label}),e.jsxs("span",{className:"text-muted-foreground",children:[i.count,n>0?` (${Math.round(i.count/n*100)}%)`:""]})]}),e.jsx("div",{className:"h-2 rounded-full bg-muted overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full bg-primary transition-all",style:{width:`${i.count/a*100}
21%`}})})]},i.label))})]})}function Le({label:t,intervals:r,cohortKey:s}){return e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2 text-muted-foreground",children:t}),e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Uppföljning"}),e.jsx(d,{className:"text-right",children:"Drogfria"}),e.jsx(d,{className:"text-right",children:"Ej drogfria"}),e.jsx(d,{className:"text-right",children:"Okänt"}),e.jsx(d,{className:"text-right",children:"Efter återfall"}),e.jsx(d,{className:"text-right",children:"Drogfrigrad"})]})}),e.jsx(M,{children:r.map(a=>{const n=a[s];return n.total===0?null:e.jsxs(N,{className:"border-border",children:[e.jsxs(c,{className:"font-medium",children:[a.months," månader"]}),e.jsx(c,{className:"text-right",children:n.ja}),e.jsx(c,{className:"text-right",children:n.nej}),e.jsx(c,{className:"text-right",children:n.vet_ej}),e.jsx(c,{className:"text-right",children:n.ja_efter_aterfall}),e.jsxs(c,{className:"text-right font-medium",style:n.drug_free_rate>0?{color:"hsl(var(--primary))"}:void 0,children:[n.drug_free_rate,"%"]})]},a.months)})})]})]})}function he({stats:t}){const r=s=>{if(s<30)return`${s} dagar`;if(s<365)return`${Math.round(s/30)} mån`;const a=Math.floor(s/365),n=Math.round(s%365/30);return n===0?`${a} år`:`${a} år ${n} mån`};return e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Nykterhetstatistik"})}),e.jsxs(_,{className:"space-y-6",children:[(t==null?void 0:t.aggregate)&&t.aggregate.total_episodes>0&&e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Episoder totalt"}),e.jsx("p",{className:"text-xl font-semibold",children:t.aggregate.total_episodes})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Pågående"}),e.jsx("p",{className:"text-xl font-semibold",children:t.aggregate.ongoing})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Snittlängd"}),e.jsx("p",{className:"text-xl font-semibold",children:r(t.aggregate.avg_days)})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Längsta"}),e.jsx("p",{className:"text-xl font-semibold",children:r(t.aggregate.max_days)})]})]}),(t==null?void 0:t.by_method)&&t.by_method.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2 text-muted-foreground",children:"Drogfri tid per metod"}),e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Metod"}),e.jsx(d,{className:"text-right",children:"Episoder"}),e.jsx(d,{className:"text-right",children:"Pågående"}),e.jsx(d,{className:"text-right",children:"Snittlängd"}),e.jsx(d,{className:"text-right",children:"Längsta"})]})}),e.jsx(M,{children:t.by_method.map(s=>e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:s.method_label??s.method_code}),e.jsx(c,{className:"text-right",children:s.total_episodes}),e.jsx(c,{className:"text-right",children:s.ongoing}),e.jsx(c,{className:"text-right",children:r(s.avg_days)}),e.jsx(c,{className:"text-right",children:r(s.max_days)})]},s.method_code))})]})]}),!(t!=null&&t.intervals)||t.intervals.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Ingen uppföljningsdata tillgänglig ännu."}):e.jsxs("div",{className:"space-y-6",children:[e.jsx(Le,{label:"Fullföljt behandling",intervals:t.intervals,cohortKey:"completed"}),e.jsx(Le,{label:"Ej fullföljt behandling",intervals:t.intervals,cohortKey:"not_completed"})]})]})]})}function Kt({therapistId:t}){const[r,s]=g.useState(!0),[a,n]=g.useState(null),[i,o]=g.useState(null);if(g.useEffect(()=>{t&&(s(!0),Promise.all([C("get_therapist_client_stats",{p_therapist_id:t}),C("get_therapist_sobriety_stats",{p_therapist_id:t})]).then(([l,f])=>{l.data&&n(l.data),f.data&&o(f.data),s(!1)}))},[t]),r)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(O,{className:"h-6 w-6 animate-spin text-primary"})});if(!a)return e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Kunde inte hämta statistik."});const u=a.primary,m=a.secondary;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3",children:"Primära klienter"}),e.jsx(ae,{active:u.active,aftercare:u.aftercare,inactiveTotal:u.inactive,completionRate:a.own_completion_rate})]}),m.active+m.aftercare+m.inactive>0&&e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3",children:"Sekundära klienter (via grupper)"}),e.jsx(ae,{active:m.active,aftercare:m.aftercare,inactiveTotal:m.inactive,completionRate:m.inactive===0?0:Math.round(m.completed/m.inactive*1e3)/10})]}),a.program_breakdown&&a.program_breakdown.length>0&&e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Programstatistik"})}),e.jsx(_,{children:e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Program"}),e.jsx(d,{className:"text-right",children:"Aktiva"}),e.jsx(d,{className:"text-right",children:"Eftervård"}),e.jsx(d,{className:"text-right",children:"Inaktiva"}),e.jsx(d,{className:"text-right",children:"Fullföljda"}),e.jsx(d,{className:"text-right",children:"Avbrott"})]})}),e.jsx(M,{children:a.program_breakdown.map(l=>e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:l.program_name}),e.jsx(c,{className:"text-right",children:l.primary.active+l.secondary.active}),e.jsx(c,{className:"text-right",children:l.primary.aftercare+l.secondary.aftercare}),e.jsx(c,{className:"text-right",children:l.primary.inactive+l.secondary.inactive}),e.jsx(c,{className:"text-right",children:l.primary.completed+l.secondary.c
21ompleted}),e.jsx(c,{className:"text-right",children:l.primary.discontinued+l.secondary.discontinued})]},l.program_id))})]})})]}),e.jsx(he,{stats:i})]})}const Te={tolvsteg:"12-stegs",psykoterapi:"Psykoterapi",farmakologisk:"Farmakologisk",ovrigt:"Övrigt"};function Dt({methodCodes:t,setMethodCodes:r,engagementTypes:s,setEngagementTypes:a}){var h;const[n,i]=g.useState([]);g.useEffect(()=>{Q.from("sobriety_methods").select("code, label, classification").order("classification").order("label").then(({data:x})=>{x&&i(x)})},[]);const o=x=>{const v=t??[],j=v.includes(x)?v.filter(p=>p!==x):[...v,x];r(j.length===0?null:j)},u=x=>{const v=s??[],j=v.includes(x)?v.filter(p=>p!==x):[...v,x];a(j.length===0?null:j)},m=x=>{const v=n.filter(j=>j.classification===x).map(j=>j.code);r(v)},l=n.reduce((x,v)=>{var j;return(x[j=v.classification]||(x[j]=[])).push(v),x},{}),f=t===null?"Alla metoder":t.length===1?((h=n.find(x=>x.code===t[0]))==null?void 0:h.label)??"1 metod":`${t.length} metoder`,S=s===null?"Alla statusar":s.length===1?Se[s[0]]??"1 status":`${s.length} statusar`;return e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(St,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"Filter:"}),e.jsxs(be,{children:[e.jsx(_e,{asChild:!0,children:e.jsxs(P,{variant:"outline",size:"sm",className:"gap-1.5",children:[e.jsx("span",{className:"text-xs",children:"Metod:"}),e.jsx(ve,{variant:"secondary",className:"font-normal",children:f}),e.jsx(ye,{className:"h-3 w-3"})]})}),e.jsx(ke,{className:"w-80 max-h-96 overflow-y-auto bg-popover",align:"start",children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap gap-1",children:[e.jsx(P,{variant:t===null?"default":"outline",size:"sm",className:"h-7 text-xs",onClick:()=>r(null),children:"Alla"}),Object.keys(l).map(x=>e.jsx(P,{variant:"outline",size:"sm",className:"h-7 text-xs",onClick:()=>m(x),children:Te[x]??x},x))]}),e.jsx("div",{className:"border-t border-border pt-2 space-y-3",children:Object.entries(l).map(([x,v])=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(at,{className:"text-xs uppercase tracking-wide text-muted-foreground",children:Te[x]??x}),v.map(j=>e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer text-sm",children:[e.jsx(we,{checked:(t==null?void 0:t.includes(j.code))??!1,onCheckedChange:()=>o(j.code)}),e.jsx("span",{children:j.label})]},j.code))]},x))})]})})]}),e.jsxs(be,{children:[e.jsx(_e,{asChild:!0,children:e.jsxs(P,{variant:"outline",size:"sm",className:"gap-1.5",children:[e.jsx("span",{className:"text-xs",children:"Status:"}),e.jsx(ve,{variant:"secondary",className:"font-normal",children:S}),e.jsx(ye,{className:"h-3 w-3"})]})}),e.jsx(ke,{className:"w-72 bg-popover",align:"start",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(P,{variant:s===null?"default":"outline",size:"sm",className:"h-7 text-xs w-full",onClick:()=>a(null),children:"Alla statusar"}),e.jsx("div",{className:"border-t border-border pt-2 space-y-1.5",children:Object.entries(Se).map(([x,v])=>e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer text-sm",children:[e.jsx(we,{checked:(s==null?void 0:s.includes(x))??!1,onCheckedChange:()=>u(x)}),e.jsx("span",{children:v})]},x))})]})})]}),(t!==null||s!==null)&&e.jsx(P,{variant:"ghost",size:"sm",className:"h-7 text-xs",onClick:()=>{r(null),a(null)},children:"Återställ"})]})}function qt({stats:t}){return!t||t.total_clients_on_medication===0?e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Medicineringsstatistik"})}),e.jsx(_,{children:e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Ingen medicineringsdata registrerad ännu."})})]}):e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsxs(k,{children:[e.jsx(w,{className:"text-lg",children:"Medicineringsstatistik"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[t.total_clients_on_medication," klient(er) har registrerad medicinering"]})]}),e.jsxs(_,{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2 text-muted-foreground",children:"Per medicinklass — utfall"}),e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Klass"}),e.jsx(d,{className:"text-right",children:"Klienter"}),e.jsx(d,{className:"text-right",children:"Aktiva"}),e.jsx(d,{className:"text-right",children:"Fullföljt"}),e.jsx(d,{className:"text-right",children:"Avbrutit"})]})}),e.jsx(M,{children:t.by_class.map(r=>e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:Ee[r.med_class]??r.med_class}),e.jsx(c,{className:"text-right",children:r.client_count}),e.jsx(c,{className:"text-right",children:r.active_count}),e.jsx(c,{className:"text-right",children:r.completed_count}),e.jsx(c,{className:"text-right",children:r.not_completed_count})]},r.med_class))})]})]}),t.by_medication.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2 text-muted-foreground",children:"Top mediciner"}),e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Medicin"}),e.jsx(d,{children:"Klass"}),e.jsx(d,{className:"text-right",children:"Klienter"}),e.jsx(d,{className:"text-right",children:"Fullföljt"})]})}),e.jsx(M,{children:t.by_medication.slice(0,15).map(r=>e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:r.med_name}),e.jsx(c,{className:"text-muted-foreground text-sm",children:Ee[r.med_class]??r.med_class}),e.jsx(c,{className:"text-right",children:r.client_count}),e.jsx(c,{className:"text-right",children:r.completed_count})]},`${r.med_name}-${r.med_class}`))})]})]})]})]})}const q=5,Je=`Genomförandegrad = andelen utskrivna klienter där behandlingen markerats som fullföljd (räknat på fullföljda + avbrott + överflyttning). Visas inte förrän det finns minst en utskriven klient. Rader med färre än ${q} utskrivna klienter maskeras som "<${q}" för sekretess.`;function D(t){return t>0&&t<q?`<${q}`:String(t)}function ge(t){return t.inactive>0&&t.inactive<q}function Ot(t){const r=["Terapeut","Aktiva","Eftervård","Utskrivna","Fullföljda","Avbrott","Genomförandegrad"],s=t.map(n=>
21[n.name||"—",String(n.active),String(n.aftercare),D(n.inactive),D(n.completed),D(n.discontinued),n.completion_rate===null?"—":ge(n)?`<${q}`:`${n.completion_rate}%`]),a=n=>`"${n.replace(/"/g,'""')}"`;return[r,...s].map(n=>n.map(a).join(",")).join(`\r
22`)}function Bt(t){const r="\uFEFF"+Ot(t),s=new Blob([r],{type:"text/csv;charset=utf-8"}),a=URL.createObjectURL(s),n=document.createElement("a");n.href=a,n.download=`terapeut-statistik-${new Date().toISOString().slice(0,10)}.csv`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(a)}function Ut(t){const r=Et(),s=[[{text:"Terapeut",style:"th"},{text:"Aktiva",style:"th"},{text:"Eftervård",style:"th"},{text:"Utskrivna",style:"th"},{text:"Fullföljda",style:"th"},{text:"Avbrott",style:"th"},{text:"Genomförandegrad",style:"th"}],...t.map(a=>[a.name||"—",String(a.active),String(a.aftercare),D(a.inactive),D(a.completed),D(a.discontinued),a.completion_rate===null?"—":ge(a)?`<${q}`:`${a.completion_rate}%`])];r.createPdf({pageOrientation:"landscape",content:[{text:"Terapeutstatistik",style:"title"},{text:Je,style:"note",margin:[0,0,0,10]},{table:{headerRows:1,widths:["*","auto","auto","auto","auto","auto","auto"],body:s},layout:"lightHorizontalLines"},{text:`Genererad ${new Date().toLocaleString("sv-SE")}`,style:"footer",margin:[0,12,0,0]}],styles:{title:{fontSize:16,bold:!0,margin:[0,0,0,8]},th:{bold:!0,fillColor:"#f3f4f6"},note:{fontSize:9,color:"#6b7280",italics:!0},footer:{fontSize:8,color:"#9ca3af"}},defaultStyle:{fontSize:10}}).download(`terapeut-statistik-${new Date().toISOString().slice(0,10)}.pdf`)}function Gt({stats:t}){const r=t.length>0;return e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsxs(k,{className:"flex flex-row items-center justify-between gap-2",children:[e.jsx(w,{className:"text-lg",children:"Terapeuter"}),r&&e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(P,{variant:"outline",size:"sm",onClick:()=>Bt(t),children:[e.jsx(ze,{className:"h-4 w-4 mr-1.5"})," CSV"]}),e.jsxs(P,{variant:"outline",size:"sm",onClick:()=>Ut(t),children:[e.jsx(De,{className:"h-4 w-4 mr-1.5"})," PDF"]})]})]}),e.jsx(_,{children:r?e.jsx(qe,{delayDuration:150,children:e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Terapeut"}),e.jsx(d,{className:"text-right",children:"Aktiva"}),e.jsx(d,{className:"text-right",children:"Eftervård"}),e.jsx(d,{className:"text-right",children:"Utskrivna"}),e.jsx(d,{className:"text-right",children:"Fullföljda"}),e.jsx(d,{className:"text-right",children:"Avbrott"}),e.jsx(d,{className:"text-right",children:e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:["Genomförandegrad",e.jsxs(Oe,{children:[e.jsx(Be,{asChild:!0,children:e.jsx(le,{className:"h-3.5 w-3.5 text-muted-foreground cursor-help","aria-label":"Info om genomförandegrad"})}),e.jsx(Ue,{side:"top",className:"max-w-xs text-xs",children:Je})]})]})})]})}),e.jsx(M,{children:t.map(s=>{const a=ge(s);return e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:s.name||"—"}),e.jsx(c,{className:"text-right",children:s.active}),e.jsx(c,{className:"text-right",children:s.aftercare}),e.jsx(c,{className:"text-right",children:D(s.inactive)}),e.jsx(c,{className:"text-right",children:D(s.completed)}),e.jsx(c,{className:"text-right",children:D(s.discontinued)}),e.jsx(c,{className:"text-right font-medium",style:!a&&s.completion_rate!==null&&s.completion_rate>0?{color:"hsl(var(--primary))"}:void 0,children:s.completion_rate===null?"—":a?e.jsx("span",{className:"text-muted-foreground",title:`Färre än ${q} utskrivna — maskerat`,children:`<${q}`}):`${s.completion_rate}%`})]},s.therapist_id)})})]})}):e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Inga aktiva terapeuter att visa statistik för."})})]})}const R=t=>t===-1?"<5":String(t);function Vt({organizationId:t}){const[r,s]=g.useState(null),[a,n]=g.useState(null),[i,o]=g.useState(null),[u,m]=g.useState(!0);return g.useEffect(()=>{t&&(m(!0),Promise.all([C("get_relapse_stats",{p_org_id:t}),C("get_satisfaction_summary",{p_org_id:t}),C("get_relapse_step9_buckets",{p_org_id:t})]).then(([l,f,S])=>{l.data&&s(l.data),f.data&&n(f.data),S.data&&o(S.data),m(!1)}))},[t]),u?e.jsx(b,{className:"bg-card shadow-sm",children:e.jsx(_,{className:"py-8 flex justify-center",children:e.jsx(O,{className:"h-5 w-5 animate-spin text-primary"})})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Återfall"})}),e.jsxs(_,{className:"space-y-4",children:[e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Cellvärden under ",(r==null?void 0:r.min_cell_threshold)??5,' individer maskeras som "<5" för sekretess.']}),!r||r.total_clients_with_response===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Ingen uppföljningsdata att visa än."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Drogfria (senaste svar)"}),e.jsx("p",{className:"text-xl font-semibold",children:R(r.latest_response_breakdown.yes)})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Ej drogfria"}),e.jsx("p",{className:"text-xl font-semibold",children:R(r.latest_response_breakdown.no)})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Drogfri efter återfall"}),e.jsx("p",{className:"text-xl font-semibold",children:R(r.latest_response_breakdown.yes_after_relapse)})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Okänt"}),e.jsx("p",{className:"text-xl font-semibold",children:R(r.latest_response_breakdown.unknown)})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Klienter med uppföljning"}),e.jsx("p",{className:"text-xl font-semibold",children:r.relapse_summary.clients_with_any_followup})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Klienter med återfall"}),e.jsx("p",{className:"text-xl font-semibold",children:R(r.relapse_summary.clients_with_relapse)})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Snitt återfall (när relapse)"}),e.jsx("p",{className:"text-xl font-semibold",children:r.relapse_summary.avg_relapse_count_when_relapsed})]})]})]}),i&&(i.pre_step9.count!==0||i.post_step9.count!==0)&&e.jsxs("div",{className:"pt-2 border-t border-border",children:[e.jsx("p",{className:"text-sm font-medium mb-2",children:"Återfall i förhållande till Steg 9"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-3",children:"Återfall innan Steg 9 = klienten har inte slutfört Steg 9 vid återfallstillfället."}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Innan Steg 9"}),e.jsxs("p",{className:"text-xl font-semibold",children:[R(i.pre_step9.count)," ",e.jsxs("span",{className:"text-xs font-normal text-muted-foreground",children:["(",R(i.pre_step9.clients)," klienter)"]})]})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Efter Steg 9"}),e.jsxs("p",{className:"text-xl font-semibold",children:[R(i.post_step9.count)," ",e.jsxs("span",{className:"text-xs font-normal text-muted-foreground",children:["(",R(i.post_step9.clients)," klienter)"]})]})]})]})]})]})]}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Brukarundersökning"})}),e.jsxs(_,{className:"space-y-3",children:[e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Totalt ",(a==null?void 0:a.total_surveys)??
220," undersökningar. Frågor med färre än ",(a==null?void 0:a.min_cell_threshold)??5," svar maskeras."]}),!a||a.questions.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Inga brukarundersökningsfrågor konfigurerade."}):e.jsx("ul",{className:"divide-y divide-border",children:a.questions.map(l=>e.jsx("li",{className:"py-3",children:e.jsxs("div",{className:"flex justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm font-medium",children:[l.question_number,". ",l.title]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[l.n_answers," svar"]})]}),e.jsx("div",{className:"text-right text-sm",children:l.masked?e.jsx("span",{className:"text-muted-foreground",children:"Maskerad"}):l.question_type==="rating"&&l.avg_rating!=null?e.jsxs("span",{className:"font-semibold",children:["⌀ ",l.avg_rating]}):l.question_type==="yes_no"?e.jsxs("span",{children:["Ja: ",e.jsx("strong",{children:R(l.yes_count)})," · Nej: ",e.jsx("strong",{children:R(l.no_count)})]}):e.jsx("span",{className:"text-muted-foreground",children:"—"})})]})},l.question_id))})]})]})]})}function zt(t){const[r,s]=g.useState({data:null,loading:!0,error:null});return g.useEffect(()=>{if(!t){s({data:null,loading:!1,error:null});return}let a=!0;return s(n=>({...n,loading:!0,error:null})),C("get_self_relapse_aggregate",{p_org_id:t}).then(({data:n,error:i})=>{if(a){if(i){s({data:null,loading:!1,error:i.message});return}s({data:n??null,loading:!1,error:null})}}),()=>{a=!1}},[t]),r}const Ht={night:"Natt (00–05)",morning:"Morgon (06–11)",afternoon:"Eftermiddag (12–17)",evening:"Kväll (18–23)"},Jt={0:"Samma dag","1-3":"1–3 dagar","4-7":"4–7 dagar","8-30":"8–30 dagar","31+":"31+ dagar"};function Yt(t){return nt[t]??t}function Qt(t){return it[t]??t}function Wt(t){return lt[t]??t}function Xt(t){return dt[t]??t}function Zt(t){return Ht[t]??t}function es(t){return Jt[t]??t}function ue(t,r){return t===null?`< ${r}`:String(t)}function H({title:t,cells:r,labelFn:s,minCell:a}){return e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-foreground mb-2",children:t}),r.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Ingen data."}):e.jsx("ul",{className:"space-y-1",children:r.map(n=>e.jsxs("li",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:s(n.value)}),e.jsx("span",{className:"font-medium tabular-nums",children:ue(n.count,a)})]},n.value))})]})}function ts(t){return t.by_substance.length>0||t.top_triggers.length>0||t.by_location.length>0||t.by_who_with.length>0||t.time_of_day_buckets.length>0||t.duration_buckets.length>0}function ss({organizationId:t}){const{data:r,loading:s}=zt(t);if(s)return e.jsx(b,{className:"bg-card shadow-sm",children:e.jsx(_,{className:"py-8 flex justify-center",children:e.jsx(O,{className:"h-5 w-5 animate-spin text-primary"})})});const a=(r==null?void 0:r.min_cell)??5;return e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Riskmönster (anonymt)"})}),e.jsxs(_,{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-start gap-2 rounded-md bg-muted/50 p-3",children:[e.jsx(ct,{className:"h-4 w-4 text-primary mt-0.5 shrink-0"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Sammanställt från klienternas egna återfallsloggar. Anonymiserat — grupper under ",a," händelser döljs som « <"," ",a," » och inga fritextsvar ingår. Underlag för framtida riskbedömning."]})]}),!r||!ts(r)?e.jsx("p",{className:"text-sm text-muted-foreground py-2",children:"Ingen återfallsdata loggad ännu."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Händelser"}),e.jsx("p",{className:"text-2xl font-semibold",children:ue(r.total_events,a)})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Klienter"}),e.jsx("p",{className:"text-2xl font-semibold",children:ue(r.distinct_clients,a)})]}),e.jsxs("div",{className:"rounded-lg border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Sökte hjälp"}),e.jsx("p",{className:"text-2xl font-semibold",children:r.sought_help_rate===null?"—":`${r.sought_help_rate}%`})]})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2",children:[e.jsx(H,{title:"Vanligaste utlösande faktorer",cells:r.top_triggers,labelFn:Qt,minCell:a}),e.jsx(H,{title:"Substans",cells:r.by_substance,labelFn:Yt,minCell:a}),e.jsx(H,{title:"Tid på dygnet",cells:r.time_of_day_buckets,labelFn:Zt,minCell:a}),e.jsx(H,{title:"Plats",cells:r.by_location,labelFn:Wt,minCell:a}),e.jsx(H,{title:"Sällskap",cells:r.by_who_with,labelFn:Xt,minCell:a}),e.jsx(H,{title:"Längd på återfall",cells:r.duration_buckets,labelFn:es,minCell:a})]})]})]})]})}const rs={man:"Man",kvinna:"Kvinna",transman:"Transman",transkvinna:"Transkvinna",ickebin_r:"Ickebinär",vill_ej_svara:"Vill ej svara"},as={socialtjanst:"Socialtjänst",kriminalvard:"Kriminalvård",frivard:"Frivård",foretag_arbetsgivare:"Företag/Arbetsgivare",egenfinansierad:"Egenfinansierad"};function ns(t){return I({queryKey:["leave-stats","per-therapist",t],enabled:!!t,queryFn:async()=>{const{data:r,error:s}=await C("get_leave_stats_per_therapist",{p_org_id:t});if(s)throw s;return r??[]}})}function is(t){return I({queryKey:["leave-stats","per-program",t],enabled:!!t,queryFn:async()=>{const{data:r,error:s}=await C("get_leave_stats_per_program",{p_org_id:t});if(s)throw s;return r??[]}})}function ls(t){return I({queryKey:["leave-stats","by-duration",t],enabled:!!t,queryFn:async()=>{const{data:r,error:s}=await C("get_leave_stats_by_treatment_duration",{p_org_id:t});if(s)throw s;return r??[]}})}function ds(){return I({queryKey:["leave-stats","cross-org"],queryFn:async()=>{const{data:t,error:r}=await C("get_leave_stats_cross_org_anonymized");if(r)throw r;return t}})}const cs=["0-4v","5-8v","9-12v","3-6m","6m+","unknown"],Me={"0-4v":"0–4 veckor","5-8v":"5–8 veckor","9-12v":"9–12 veckor","3-6m":"3–6 månader","6m+":"6+ månader",unknown:"Okänd"};function os(t){const r=cs;return[...t].sort((s,a)=>r.indexOf(s.bucket)-r.indexOf(a.bucket))}function se(){return e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(O,{className:"h-5 w-5 animate-spin text-primary"})})}function re({msg:t}){return e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:t})}function Ye({organizationId:t,showCrossOrg:r=!1}){var o,u,m,l,f,S;const s=ns(t),a=is(t),n=ls(t),i=ds();return e.jsxs("div",{className:"space-y-4",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Ledigheter"}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-base",children:"Per behandlare"})}),e.jsx(_,{children:s.isLoading?e.jsx(se,{}):(o=s.data)!=null&&o.length?e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Behandlare"}),e.jsx(d,{className:"text-right",children:"Totalt"}),e.jsx(d,{className:"text-right",children:"Beviljade"}),e.jsx(d,{className:"text-right",children:"Avslagna"}),e.jsx(d,{className:"text-right",children:"Väntande"}),e.jsx(d,{className:"text-right",children:"Snitt dagar"})]})}),e.jsx(M,{children:s.data.map(h=>{var x;return e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:h.therapist_name}),e.jsx(c,{className:"text-right",children:h.total}),e.jsx(c,{className:"text-right",children:h.approved}),e.jsx(c,{className:"text-right",children:h.denied}),e.jsx(c,{className:"text-right",children:h.pending}),e.jsx(c,{className:"text-right",children:((x=h.avg_days)==null?void 0:x.toFixed(1))??"—"})]},h.therapist_id??h.therapist_name)})})]}):e.jsx(re,{msg:"Inga ledighetsansökningar registrerade."})})]}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-base",children:"Per program"})}),e.jsx(_,{children:a.isLoading?e.jsx(se,{}):(u=a.data)!=null&&u.length?e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Program"}),e.jsx(d,{className:"text-right",children:"Totalt"}),e.jsx(d,{className:"text-right",children:"Beviljade"}),e.jsx(d,{className:"text-right",children:"Avslagna"})]})}),e.jsx(M,{children:a.data.map(h=>e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:h.program_name}),e.jsx(c,{className:"text-right",children:h.total}),e.jsx(c,{className:"text-right",children:h.approved}),e.jsx(c,{className:"text-right",children:h.denied})]},h.program_id??h.program_name))})]}):e.jsx(re,{msg:"Inga ledigheter kopplade till program."})})]}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-base",children:"Per behandlingstid (utfallskorrelation)"})}),e.jsx(_,{children:n.isLoading?e.jsx(se,{}):(m=n.data)!=null&&m.length?e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Behandlingstid vid ledighet"}),e.jsx(d,{className:"text-right",children:"Ledigheter"}),e.jsx(d,{className:"text-right",children:"Klienter"}),e.jsx(d,{className:"text-right",children:"Avslag"}),e.jsx(d,{className:"text-right",children:"Fullföljt"}),e.jsx(d,{className:"text-right",children:"Avbrott"})]})}),e.jsx(M,{children:os(n.data).map(h=>e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:Me[h.bucket]}),e.jsx(c,{className:"text-right",children:h.total_leaves}),e.jsx(c,{className:"text-right",children:h.unique_clients}),e.jsx(c,{className:"text-right",children:h.denied}),e.jsx(c,{className:"text-right",children:h.clients_completed}),e.jsx(c,{className:"text-right",children:h.clients_discontinued})]},h.bucket))})]}
22):e.jsx(re,{msg:"Inga ledigheter att korrelera."})})]}),r&&e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-base",children:"Plattformen (anonymiserad, k≥5)"})}),e.jsx(_,{children:i.isLoading?e.jsx(se,{}):(f=(l=i.data)==null?void 0:l.by_duration_bucket)!=null&&f.length?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-muted-foreground mb-3",children:[i.data.total_leaves," ledigheter från ",i.data.participating_orgs," organisationer. Snitt: ",((S=i.data.avg_days_overall)==null?void 0:S.toFixed(1))??"—"," dagar."]}),e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Behandlingstid"}),e.jsx(d,{className:"text-right",children:"Antal"}),e.jsx(d,{className:"text-right",children:"Snitt dagar"}),e.jsx(d,{className:"text-right",children:"Beviljade"}),e.jsx(d,{className:"text-right",children:"Avslag"})]})}),e.jsx(M,{children:i.data.by_duration_bucket.map(h=>{var x;return e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:Me[h.duration_bucket]}),e.jsx(c,{className:"text-right",children:h.total}),e.jsx(c,{className:"text-right",children:((x=h.avg_days)==null?void 0:x.toFixed(1))??"—"}),e.jsx(c,{className:"text-right",children:h.approved}),e.jsx(c,{className:"text-right",children:h.denied})]},h.duration_bucket)})})]})]}):e.jsx(re,{msg:"Otillräckligt underlag för anonymiserad statistik (k<5)."})})]})]})}function ms({organizationId:t}){const[r,s]=g.useState(!0),[a,n]=g.useState(null),[i,o]=g.useState([]),[u,m]=g.useState(null),[l,f]=g.useState(null),[S,h]=g.useState([]),[x,v]=g.useState([]),[j,p]=g.useState(null),[B,K]=g.useState(null);if(g.useEffect(()=>{t&&C("get_sobriety_stats",{p_org_id:t,p_method_codes:j,p_engagement_types:B}).then(({data:y})=>{y&&m(y)})},[t,j,B]),g.useEffect(()=>{t&&(s(!0),Promise.all([C("get_org_client_stats",{p_org_id:t}),C("get_program_completion_stats",{p_org_id:t}),C("get_sobriety_stats",{p_org_id:t}),C("get_medication_stats",{p_org_id:t}),C("get_org_therapist_stats",{p_org_id:t})]).then(async([y,z,$,je,Ze])=>{y.data&&n(y.data),o(z.data??[]),$.data&&m($.data),je.data&&f(je.data),v(Ze.data??[]);const{data:te}=await Q.from("unit_managers").select("id, first_name, last_name").eq("organization_id",t).eq("is_active",!0).order("last_name");if(!te||te.length===0){h([]),s(!1);return}const et=te.map(A=>A.id),[{data:tt},{data:st}]=await Promise.all([Q.from("referrers").select("id, unit_manager_id").in("unit_manager_id",et),Q.from("clients").select("id, status, discharge_reason, referrer_id").eq("organization_id",t)]),rt=st??[],Ne=new Map,ce=new Map;(tt??[]).forEach(A=>{A.unit_manager_id&&(Ne.set(A.id,A.unit_manager_id),ce.set(A.unit_manager_id,(ce.get(A.unit_manager_id)??0)+1))});const oe=new Map,me=new Map,xe=new Map;rt.forEach(A=>{if(!A.referrer_id)return;const G=Ne.get(A.referrer_id);G&&(A.status==="active"||A.status==="aftercare"?oe.set(G,(oe.get(G)??0)+1):["inactive","deceased","deregistered"].includes(A.status)&&(me.set(G,(me.get(G)??0)+1),A.discharge_reason==="completed"&&xe.set(G,(xe.get(G)??0)+1)))}),h(te.map(A=>({id:A.id,name:`${A.first_name} ${A.last_name}`,referrerCount:ce.get(A.id)??0,activeClients:oe.get(A.id)??0,inactiveClients:me.get(A.id)??0,completedClients:xe.get(A.id)??0}))),s(!1)}))},[t]),r)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(O,{className:"h-6 w-6 animate-spin text-primary"})});const E=a;return e.jsxs("div",{className:"space-y-6",children:[e.jsx(ae,{active:(E==null?void 0:E.active)??0,aftercare:(E==null?void 0:E.aftercare)??0,inactiveTotal:(E==null?void 0:E.inactive_total)??0,completionRate:(E==null?void 0:E.completion_rate)??0}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(Ce,{title:"Könsfördelning",items:(E==null?void 0:E.gender_breakdown)??[],labelMap:rs}),e.jsx(Ce,{title:"Remitteringskälla",items:(E==null?void 0:E.referral_source_breakdown)??[],labelMap:as})]}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Programstatistik"})}),e.jsx(_,{children:i.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Inga program tilldelade."}):e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Program"}),e.jsx(d,{className:"text-right",children:"Aktiva"}),e.jsx(d,{className:"text-right",children:"Eftervård"}),e.jsx(d,{className:"text-right",children:"Inaktiva"}),e.jsx(d,{className:"text-right",children:"Fullföljda"}),e.jsx(d,{className:"text-right",children:"Avbrott"}),e.jsx(d,{className:"text-right",title:"Andel utskrivna klienter där behandlingen markerats som fullföljd. Visas inte förrän det finns minst en utskriven klient.",children:"Genomförandegrad"})]})}),e.jsx(M,{children:i.map(y=>e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:y.program_name}),e.jsx(c,{className:"text-right",children:y.active_count}),e.jsx(c,{className:"text-right",children:y.aftercare_count}),e.jsx(c,{className:"text-right",children:y.inactive_count}),e.jsx(c,{className:"text-right",children:y.completed_count}),e.jsx(c,{className:"text-right",children:y.discontinued_count}),e.jsx(c,{className:"text-right font-medium",style:y.completion_rate>0?{color:"hsl(var(--primary))"}:void 0,children:y.inactive_count===0?"—":`${y.completion_rate}%`})]},y.program_id))})]})})]}),e.jsx(b,{className:"bg-card shadow-sm",children:e.jsx(_,{className:"pt-6",children:e.jsx(Dt,{methodCodes:j,setMethodCodes:p,engagementTypes:B,setEngagementTypes:K})})}),e.jsx(he,{stats:u}),e.jsx(qt,{stats:l}),e.jsx(Vt,{organizationId:t}),e.jsx(ss,{organizationId:t}),e.jsx(Gt,{stats:x}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Enhetschefer"})}),e.jsx(_,{children:S.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Inga aktiva enhetschefer att visa statistik för."}):e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Enhetschef"}),e.jsx(d,{children:"Handläggare"}),e.jsx(d,{children:"Aktiva klienter"}),e.jsx(d,{children:"Utskrivna klienter"}),e.jsx(d,{children:"Genomförandegrad"})]})}),e.jsx(M,{children:S.map(y=>{const z=y.inactiveClients===0?"—":`${Math.round(y.completedClients/y.inactiveClients*100)}%`;return e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:y.name}),e.jsx(c,{children:y.referrerCount}),e.jsx(c,{children:y.activeClients}),e.jsx(c,{children:y.inactiveClients}),e.jsx(c,{children:z})]},y.id)})})]})})]}),e.jsx(Ye,{organizationId:t})]})}function xs({organizationId:t}){const[r,s]=g.useState(!0),[a,n]=g.useState(null),[i,o]=g.useState(null);if(g.useEffect(()=>{t&&(s(!0),o(null),C("get_conglomerate_client_stats",{p_parent_org_id:t}).then(({data:m,error:l})=>{l?o("Kunde inte hämta koncernens samlade statistik."):m&&n(m),s(!1)}))},[t]),r)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(O,{className:"h-6 w-6 animate-spin text-primary"})});if(i)return e.jsx("p",{className:"py-8 text-center text-sm text-muted-foreground",children:i});const u=(a==null?void 0:a.units)??[];return e.jsxs("div",{className:"space-y-6",children:[e.jsx(ae,{active:(a==null?void 0:a.active)??0,aftercare:(a==null?void 0:a.aftercare)??0,inactiveTotal:(a==null?void 0:a.inactive_total)??0,completionRate:(a==null?void 0:a.completion_rate)??0}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Per verksamhet"})}),e.jsxs(_,{children:[u.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Inga verksamheter i koncernen ännu."}):e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{children:[e.jsx(d,{children:"Verksamhet"}),e.jsx(d,{className:"text-right",children:"Aktiva"}),e.jsx(d,{className:"text-right",children:"Eftervård"}),e.jsx(d,{className:"text-right",children:"Inaktiva"}),e.jsx(d,{className:"text-right",children:"Fullföljt"}),e.jsx(d,{className:"text-right",children:"Genomförandegrad"})]})}),e.jsx(M,{children:u.map(m=>e.jsxs(N,{children:[e.jsxs(c,{className:"font-medium",children:[m.organization_name,m.is_parent&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground",children:"(moderverksamhet)"})]}),e.jsx(c,{className:"text-right",children:m.active}),e.jsx(c,{className:"text-right",children:m.aftercare}),e.jsx(c,{className:"text-right",children:m.inactive_total}),e.jsx(c,{className:"text-right",children:m.completed}),e.jsx(c,{className:"text-right",children:m.inactive_total===0?"—":`${m.completion_rate}%`})]},m.organization_id))})]}),e.jsx("p",{className:"mt-4 text-xs text-muted-foreground",children:"Samlade siffror för koncernen. Enskilda klientuppgifter och journaler visas bara i de verksamheter där du själv 
22är administratör."})]})]})]})}const Qe="—",J="Maskerat: färre än 5 individer (k-anonymitet)";function Y(t,r=""){return t===null?Qe:`${t}${r}`}function Pe(){const[t,r]=g.useState(!0),[s,a]=g.useState(null),[n,i]=g.useState(null),[o,u]=g.useState([]);return g.useEffect(()=>{r(!0),Promise.all([C("get_platform_stats"),C("get_platform_sobriety_stats"),C("get_platform_program_completion_stats")]).then(([m,l,f])=>{m.data&&a(m.data),l.data&&i(l.data),u(f.data??[]),r(!1)})},[]),t?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(O,{className:"h-6 w-6 animate-spin text-primary"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-start gap-2 rounded-lg border border-border bg-muted/40 p-3 text-xs text-muted-foreground",children:[e.jsx(le,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsxs("p",{children:["Plattformsstatistik visas anonymt över alla anslutna organisationer. Värden där färre än 5 individer ingÃ¥r i en grupp maskeras som ",e.jsx("span",{className:"font-mono",children:Qe})," enligt Datainspektionens praxis för känsliga personkategorier."]})]}),e.jsx(It,{active:(s==null?void 0:s.active)??null,aftercare:(s==null?void 0:s.aftercare)??null,inactiveTotal:(s==null?void 0:s.inactive_total)??null,completionRate:(s==null?void 0:s.completion_rate)??null}),e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsx(w,{className:"text-lg",children:"Programstatistik (plattformsaggregat)"})}),e.jsx(_,{children:o.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Inga behandlingsprogram med aktiva grupper ännu."}):e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{className:"border-border",children:[e.jsx(d,{children:"Program"}),e.jsx(d,{className:"text-right",children:"Aktiva"}),e.jsx(d,{className:"text-right",children:"EftervÃ¥rd"}),e.jsx(d,{className:"text-right",children:"Inaktiva"}),e.jsx(d,{className:"text-right",children:"Fullföljda"}),e.jsx(d,{className:"text-right",children:"Avbrott"}),e.jsx(d,{className:"text-right",title:"Andel utskrivna klienter där behandlingen markerats som fullföljd. Maskerad vid <5 utskrivna.",children:"Genomförandegrad"})]})}),e.jsx(M,{children:o.map(m=>{const l=m.completion_rate;return e.jsxs(N,{className:"border-border",children:[e.jsx(c,{className:"font-medium",children:m.program_name}),e.jsx(c,{className:"text-right",title:m.active_count===null?J:void 0,children:Y(m.active_count)}),e.jsx(c,{className:"text-right",title:m.aftercare_count===null?J:void 0,children:Y(m.aftercare_count)}),e.jsx(c,{className:"text-right",title:m.inactive_count===null?J:void 0,children:Y(m.inactive_count)}),e.jsx(c,{className:"text-right",title:m.completed_count===null?J:void 0,children:Y(m.completed_count)}),e.jsx(c,{className:"text-right",title:m.discontinued_count===null?J:void 0,children:Y(m.discontinued_count)}),e.jsx(c,{className:"text-right font-medium",style:l!==null&&l>0?{color:"hsl(var(--primary))"}:void 0,title:l===null?J:void 0,children:Y(l,"%")})]},m.program_id)})})]})})]}),e.jsx(he,{stats:n}),e.jsx(Ye,{organizationId:null,showCrossOrg:!0})]})}const F=Q;function us(){return typeof window>"u"||!window.matchMedia?!1:window.matchMedia("(prefers-reduced-motion: reduce)").matches}function de(){const{user:t}=V(),[r,s]=g.useState("classic"),[a,n]=g.useState(!0),i=us();g.useEffect(()=>{let m=!1;if(!t){n(!1);return}return F.from("profiles").select("stats_view_mode").eq("id",t.id).maybeSingle().then(({data:l})=>{if(m)return;const f=(l==null?void 0:l.stats_view_mode)??"classic";s(f),n(!1)}),()=>{m=!0}},[t]);const o=g.useCallback(async m=>{s(m),t&&await F.from("profiles").update({stats_view_mode:m}).eq("id",t.id)},[t]);return{mode:i?"classic":r,rawMode:r,setMode:o,loading:a,reducedMotion:i}}function hs(){const{rawMode:t,setMode:r,reducedMotion:s}=de();return s?e.jsx("div",{className:"text-xs text-muted-foreground italic",role:"status",children:"Visar klassisk vy (reducerade rörelser aktiverat)"}):e.jsxs("div",{className:"inline-flex items-center gap-1 rounded-lg border bg-card p-1",role:"group","aria-label":"VÃ
22¤lj statistikvy",children:[e.jsxs(P,{size:"sm",variant:t==="classic"?"default":"ghost",onClick:()=>r("classic"),"aria-pressed":t==="classic",className:"gap-1.5",children:[e.jsx($t,{className:"h-3.5 w-3.5"}),"Klassisk"]}),e.jsxs(P,{size:"sm",variant:t==="visual"?"default":"ghost",onClick:()=>r("visual"),"aria-pressed":t==="visual",className:"gap-1.5",children:[e.jsx(Ge,{className:"h-3.5 w-3.5"}),"Visuell"]})]})}function gs({end:t,duration:r=1200}){const[s,a]=g.useState(0),n=g.useRef(null);return g.useEffect(()=>{let i=0;const o=u=>{n.current===null&&(n.current=u);const m=Math.min((u-n.current)/r,1);a(Math.floor(m*t)),m<1&&(i=requestAnimationFrame(o))};return i=requestAnimationFrame(o),()=>cancelAnimationFrame(i)},[t,r]),e.jsx(e.Fragment,{children:s})}function fs(){const{mode:t}=de(),{data:r,isLoading:s,error:a}=I({queryKey:["sprint2","rm12-trained"],queryFn:async()=>{const{data:n,error:i}=await F.rpc("get_rm12_trained_count");if(i)throw i;return n},staleTime:5*60*1e3});return e.jsxs(b,{children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(w,{className:"text-sm font-medium",children:"Utbildade i RM-12"}),e.jsx(ot,{className:"h-4 w-4 text-muted-foreground","aria-hidden":"true"})]}),e.jsxs(_,{children:[s&&e.jsx(X,{className:"h-10 w-24"}),a&&e.jsx("p",{className:"text-sm text-destructive",children:"Kunde inte hämta data."}),r&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"text-3xl font-bold text-primary","aria-label":`${r.total} personer utbildade i RM-12`,children:t==="visual"?e.jsx(gs,{end:r.total}):r.total}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[r.referrers," remittenter · ",r.verified_claims," verifierade krav"]}),e.jsxs("p",{className:"text-[10px] text-muted-foreground mt-2",children:["Senast uppdaterad: ",new Date(r.updated_at).toLocaleTimeString("sv-SE",{hour:"2-digit",minute:"2-digit"})]})]})]})]})}function W({message:t}){return e.jsxs("div",{className:"flex flex-col items-center gap-2 rounded-lg border border-dashed bg-muted/30 px-4 py-8 text-center",children:[e.jsx(le,{className:"h-5 w-5 text-muted-foreground","aria-hidden":"true"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t??"Statistik visas när minst 5 personer matchar."})]})}function fe(){return e.jsx(qe,{children:e.jsxs(Oe,{children:[e.jsx(Be,{asChild:!0,children:e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-accent/40 px-2 py-0.5 text-[10px] font-medium text-muted-foreground","aria-label":"K-anonymitet aktiv: visas endast vid minst 5 personer",children:[e.jsx(mt,{className:"h-3 w-3"}),"N ≥ 5"]})}),e.jsx(Ue,{children:"Statistik visas aldrig för färre än 5 personer (GDPR Art. 89)."})]})})}function ps(){V();const t=ee(),{data:r,isLoading:s,error:a}=I({queryKey:["sprint2","satisfaction",t],queryFn:async()=>{const{data:n,error:i}=await F.rpc("get_client_satisfaction_summary",{_org_id:t});if(i)throw i;return n},staleTime:5*60*1e3,enabled:!!t});return e.jsxs(b,{children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsxs(w,{className:"text-sm font-medium flex items-center gap-2",children:["Klientutvärdering",(r==null?void 0:r.k_anon_applied)&&e.jsx(fe,{})]}),e.jsx(Mt,{className:"h-4 w-4 text-muted-foreground","aria-hidden":"true"})]}),e.jsxs(_,{children:[s&&e.jsx(X,{className:"h-20 w-full"}),a&&e.jsx("p",{className:"text-sm text-destructive",children:"Kunde inte hämta data."}),r&&r.k_anon_applied&&e.jsx(W,{message:"Statistik visas när minst 5 utvärderingar finns."}),r&&!r.k_anon_applied&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[e.jsx("span",{className:"text-3xl font-bold",children:r.avg_rating??"—"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["/ 5 (",r.total_surveys," utvärderingar)"]})]}),r.recent_comments.length>0&&e.jsx("ul",{className:"mt-3 space-y-1",children:r.recent_comments.map((n,i)=>e.jsxs("li",{className:"text-xs text-muted-foreground italic line-clamp-2",children:['"',n.text,'"']},i))}),e.jsxs("p",{className:"text-[10px] text-muted-foreground mt-2",children:["Senast uppdaterad: ",new Date(r.updated_at).toLocaleTimeString("sv-SE",{hour:"2-digit",minute:"2-digit"})]})]})]})]})}function js(){V();const{mode:t}=de(),r=ee(),{data:s,isLoading:a,error:n}=I({queryKey:["sprint2","education",r],queryFn:async()=>{const{data:o,error:u}=await F.rpc("get_education_breakdown",{_org_id:r});if(u)throw u;return o},staleTime:5*60*1e3,enabled:!!r}),i=Math.max(1,...(s==null?void 0:s.breakdown.map(o=>o.count))??[0]);return e.jsxs(b,{children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(w,{className:"text-sm font-medium",children:"UtbildningsnivÃ¥ (klienter)"}),e.jsx(xt,{className:"h-4 w-4 text-muted-foreground","aria-hidden":"true"})]}),e.jsxs(_,{children:[a&&e.jsx(X,{className:"h-32 w-full"}),n&&e.jsx("p",{className:"text-sm text-destructive",children:"Kunde inte hämta data."}
22),s&&s.breakdown.length===0&&e.jsx(W,{message:"Ingen utbildningsdata registrerad än."}),s&&s.breakdown.length>0&&e.jsxs(e.Fragment,{children:[t==="classic"?e.jsxs(L,{children:[e.jsx(T,{children:e.jsxs(N,{children:[e.jsx(d,{children:"Nivå"}),e.jsx(d,{className:"text-right",children:"Antal"})]})}),e.jsx(M,{children:s.breakdown.map(o=>e.jsxs(N,{children:[e.jsx(c,{className:"capitalize",children:o.education}),e.jsx(c,{className:"text-right font-medium",children:o.count})]},o.education))})]}):e.jsx("div",{className:"space-y-2",children:s.breakdown.map(o=>e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between text-xs mb-1",children:[e.jsx("span",{className:"capitalize",children:o.education}),e.jsx("span",{className:"font-medium",children:o.count})]}),e.jsx("div",{className:"h-2 rounded-full bg-muted overflow-hidden",children:e.jsx("div",{className:"h-full bg-primary transition-all duration-700",style:{width:`${o.count/i*100}%`},"aria-label":`${o.education}: ${o.count}`})})]},o.education))}),e.jsxs("p",{className:"text-[10px] text-muted-foreground mt-3",children:["Senast uppdaterad: ",new Date(s.updated_at).toLocaleTimeString("sv-SE",{hour:"2-digit",minute:"2-digit"})]})]})]})]})}const $e={completed:"diagonal",discontinued:"horizontal",transferred:"vertical"};function Ns(t,r){return`hsl(${t==="completed"?"var(--primary)":t==="discontinued"?"var(--destructive)":"var(--accent)"} / ${.25+r*.65})`}function bs(){V();const{mode:t}=de(),r=ee(),{data:s,isLoading:a,error:n}=I({queryKey:["sprint2","discharge-employment",r],queryFn:async()=>{const{data:l,error:f}=await F.rpc("get_discharge_by_employment",{_org_id:r});if(f)throw f;return l},staleTime:5*60*1e3,enabled:!!r}),i=Array.from(new Set((s==null?void 0:s.matrix.map(l=>l.employment))??[])),o=Array.from(new Set((s==null?void 0:s.matrix.map(l=>l.discharge_reason))??[])),u=Math.max(1,...(s==null?void 0:s.matrix.map(l=>l.count))??[0]),m=(l,f)=>{var S;return((S=s==null?void 0:s.matrix.find(h=>h.employment===l&&h.discharge_reason===f))==null?void 0:S.count)??0};return e.jsxs(b,{children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(w,{className:"text-sm font-medium",children:"Avbrott per yrkeskategori"}),e.jsx(ut,{className:"h-4 w-4 text-muted-foreground","aria-hidden":"true"})]}),e.jsxs(_,{children:[a&&e.jsx(X,{className:"h-40 w-full"}),n&&e.jsx("p",{className:"text-sm text-destructive",children:"Kunde inte hämta data."}),s&&s.matrix.length===0&&e.jsx(W,{}),s&&s.matrix.length>0&&e.jsxs("div",{className:"overflow-x-auto",children:[e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left p-1.5 font-medium",children:"Yrke \\ Orsak"}),o.map(l=>e.jsx("th",{className:"text-center p-1.5 font-medium capitalize",children:l},l))]})}),e.jsx("tbody",{children:i.map(l=>e.jsxs("tr",{children:[e.jsx("td",{className:"p-1.5 font-medium capitalize",children:l}),o.map(f=>{const S=m(l,f),h=S/u;return e.jsx("td",{className:"p-1.5 text-center",style:{backgroundColor:t==="visual"?Ns(f,h):void 0,backgroundImage:t==="visual"?`repeating-linear-gradient(${$e[f]==="diagonal"?"45deg":$e[f]==="horizontal"?"0deg":"90deg"}, transparent, transparent 4px, hsl(0 0% 100% / 0.15) 4px, hsl(0 0% 100% / 0.15) 5px)`:void 0},title:`${l} – ${f}: ${S}`,"aria-label":`${l}, ${f}: ${S} klienter`,children:S},f)})]},l))})]}),e.jsxs("p",{className:"text-[10px] text-muted-foreground mt-3",children:["Senast uppdaterad: ",new Date(s.updated_at).toLocaleTimeString("sv-SE",{hour:"2-digit",minute:"2-digit"})]})]})]})]})}const _s=[{value:"own",label:"Min enhet",icon:ht},{value:"concern",label:"Koncern",icon:Pt},{value:"national",label:"Sverige",icon:Tt},{value:"international",label:"Internationellt",icon:At}];function vs(){const[t,r]=g.useState("own"),{data:s,isLoading:a,error:n}=I({queryKey:["sprint2","scoped",t],queryFn:async()=>{const{data:i,error:o}=await F.rpc("get_statistics_scoped",{_scope:t});if(o)throw o;return i},staleTime:5*60*1e3});return e.jsxs(b,{children:[e.jsxs(k,{className:"pb-2",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs(w,{className:"text-sm font-medium flex items-center gap-2",children:["Räckvidd",t==="national"&&e.jsx(fe,{})]})}),e.jsx("div",{className:"flex flex-wrap gap-1 mt-2",role:"tablist","aria-label":"Statistik-räckvidd",children:_s.map(({value:i,label:o,icon:u})=>e.jsxs(P,{size:"sm",variant:t===i?"default":"ghost",onClick:()=>r(i),role:"tab","aria-selected":t===i,className:"gap-1.5 h-7 text-xs",children:[e.jsx(u,{className:"h-3 w-3"}),o]},i))})]}),e.jsxs(_,{children:[a&&e.jsx(X,{className:"h-20 w-full"}),n&&e.jsx("p",{className:"text-sm text-destructive",children:"Kunde inte hämta data."}),(s==null?void 0:s.placeholder)&&e.jsx(W,{message:s.message??"Inte tillgängligt."}),(s==null?void 0:s.k_anon_applied)&&!s.placeholder&&e.jsx(W,{message:s.message}),s&&!s.placeholder&&!s.k_anon_applied&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[e.jsxs("span",{className:"text-3xl font-bold text-primary",children:[s.completion_rate??0,"%"]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"slutförandegrad"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[s.completed," av ",s.total_clients," klienter slutförda",s.org_count&&s.org_count>1&&` (${s.org_count} enheter)`]}),s.updated_at&&e.jsxs("p",{className:"text-[10px] text-muted-foreground",children:["Senast uppdaterad: ",new Date(s.updated_at).toLocaleTimeString("sv-SE",{hour:"2-digit",minute:"2-digit"})]})]})]})]})}var Fe;He.vfs=((Fe=Ae.pdfMake)==null?void 0:Fe.vfs)??Ae.vfs;async function ys(t,r){const{error:s}=await F.rpc("log_statistics_export",{_export_type:"discharge_by_employment_pdf",_period_from:null,_period_to:null,_filters:{org:r},_row_count:t.length});if(s)throw new Error(s.message||"Export blockerad (rate limit?)");const a=Array.from(new Set(t.map(u=>u.employment))),n=Array.from(new Set(t.map(u=>u.discharge_reason))),i=["Yrkeskategori",...n],o=a.map(u=>[u,...n.map(m=>{var l;return String(((l=t.find(f=>f.employment===u&&f.discharge_reason===m))==null?void 0:l.count)??0)})]);He.createPdf({info:{title:`Avbrott per yrkeskategori - ${r}`,author:"Avstampet"},pageSize:"A4",pageOrientation:"landscape",content:[{text:r,style:"brand"},{text:"Avbrott per yrkeskategori",style:"header"}
22,{text:`Genererad: ${new Date().toLocaleString("sv-SE")}`,style:"meta",margin:[0,0,0,16]},{table:{headerRows:1,widths:["*",...n.map(()=>"auto")],body:[i,...o]},layout:"lightHorizontalLines"},{text:"Statistik visas aldrig för färre än 5 personer (GDPR Art. 89).",style:"footer",margin:[0,16,0,0]}],styles:{brand:{color:"#4EA981",fontSize:10,bold:!0},header:{fontSize:18,bold:!0,margin:[0,4,0,0]},meta:{fontSize:9,color:"#6B7280"},footer:{fontSize:8,color:"#6B7280",italics:!0}},defaultStyle:{fontSize:10}}).download(`avbrott-yrkeskategori-${Date.now()}.pdf`)}function ks(){V();const{toast:t}=gt(),r=ee(),[s,a]=g.useState(!1),{data:n}=I({queryKey:["sprint2","discharge-employment",r],queryFn:async()=>{const{data:o,error:u}=await F.rpc("get_discharge_by_employment",{_org_id:r});if(u)throw u;return o},enabled:!!r,staleTime:5*60*1e3}),i=async()=>{if(!(n!=null&&n.matrix.length)){t({title:"Ingen data att exportera",variant:"destructive"});return}a(!0);try{await ys(n.matrix,"RM-12 / Avstampet"),t({title:"PDF genererad"})}catch(o){t({title:"Kunde inte exportera",description:o.message,variant:"destructive"})}finally{a(!1)}};return e.jsxs(b,{children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(w,{className:"text-sm font-medium",children:"Manuell export"}),e.jsx(De,{className:"h-4 w-4 text-muted-foreground","aria-hidden":"true"})]}),e.jsxs(_,{children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-3",children:"Ladda ner avbrott-per-yrke-statistik som PDF. Max 10 exporter per timme."}),e.jsxs(P,{onClick:i,disabled:s||!(n!=null&&n.matrix.length),size:"sm",className:"gap-1.5",children:[e.jsx(ze,{className:"h-3.5 w-3.5"}),s?"Genererar…":"Ladda ner PDF"]})]})]})}function ws(){const{user:t,hasRole:r}=V(),[s,a]=g.useState(null),[n,i]=g.useState(null);if(g.useEffect(()=>{!t||!r("superuser")||(F.from("notifications").select("id",{count:"exact",head:!0}).eq("user_id",t.id).eq("type","stats_annat_used").eq("is_read",!1).then(({count:u})=>a(u??0)),F.from("notifications").select("id",{count:"exact",head:!0}).eq("user_id",t.id).eq("type","suggestion_pending").eq("is_read",!1).then(({count:u})=>i(u??0)))},[t,r]),!r("superuser"))return null;const o=(s??0)+(n??0);return e.jsxs(b,{children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(w,{className:"text-sm font-medium",children:'"Annat" & nya förslag'}),e.jsx(ft,{className:"h-4 w-4 text-muted-foreground","aria-hidden":"true"})]}),e.jsxs(_,{children:[e.jsx("div",{className:"text-2xl font-bold","aria-label":`${o} olästa notiser totalt`,children:s===null&&n===null?"—":o}),e.jsxs("div",{className:"mt-2 space-y-1 text-xs text-muted-foreground",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:'"Annat" i klient-fält'}),e.jsx("span",{className:"font-medium tabular-nums",children:s??"—"})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Pending förslag (10 bibliotek)"}),e.jsx("span",{className:"font-medium tabular-nums",children:n??"—"})]})]})]})]})}function Ss(){const{data:t,isLoading:r,error:s}=I({queryKey:["sprint2","owner-aggregated"],queryFn:async()=>{const{data:a,error:n}=await F.rpc("get_owner_aggregated_stats");if(n)throw n;return a},staleTime:3e5,retry:!1});return s?null:e.jsxs(b,{className:"border-primary/20",children:[e.jsxs(k,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsxs(w,{className:"text-sm font-medium flex items-center gap-2",children:["Ägar-vy (alla utbildade enheter)",e.jsx(fe,{})]}),e.jsx(Ct,{className:"h-4 w-4 text-primary","aria-hidden":"true"})]}),e.jsxs(_,{children:[r&&e.jsx(X,{className:"h-16 w-full"}),(t==null?void 0:t.k_anon_applied)&&e.jsx(W,{message:t.message}),t&&!t.k_anon_applied&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enheter"}),e.jsx("p",{className:"text-2xl font-bold",children:t.org_count})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Totalt klienter"}),e.jsx("p",{className:"text-2xl font-bold",children:t.total_clients})]})]}),t.updated_at&&e.jsxs("p",{className:"text-[10px] text-muted-foreground mt-2",children:["Senast uppdaterad: ",new Date(t.updated_at).toLocaleTimeString("sv-SE",{hour:"2-digit",minute:"2-digit"})]})]})]})]})}function Es(){return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Utökad statistik"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Klassisk vy är standard. Slå på Visuell för animationer och färgade kort."})]}),e.jsx(hs,{})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:[e.jsx(fs,{}),e.jsx(ps,{}),e.jsx(vs,{}),e.jsx(js,{}),e.jsx(bs,{}),e.jsx(ks,{}),e.jsx(ws,{}),e.jsx(Ss,{})]})]})}const We={platform_overview:{intentId:"platform_overview",rpcName:"get_platform_stats",allowedParams:[],requiredRoles:["superuser"],title:"Plattformsöversikt",description:"Antal aktiva, eftervård och inaktiva klienter samt genomförandegrad (completion rate) aggregerat över hela plattformen."},platform_sobriety:{intentId:"platform_sobriety",rpcName:"get_platform_sobriety_stats",allowedParams:[],requiredRoles:["superuser"],title:"Nykterhet över plattformen",description:"Drogfrihet/nykterhet vid uppföljning (6, 12, 18, 24, 36 månader) aggregerat över alla organisationer, k-anonymiserat."},platform_program_completion:{intentId:"platform_program_completion",rpcName:"get_platform_program_completion_stats",allowedParams:[],requiredRoles:["superuser"],title:"Genomförande per program",description:"Genomförandegrad och klientfördelning per behandlingsprogram (t.ex. RM-12) aggregerat över plattformen."},platform_owner_aggregate:{intentId:"platform_owner_aggregate",rpcName:"get_owner_aggregated_stats",allowedParams:[],requiredRoles:["superuser"],title:"Ägaraggregerad statistik",description:"Sammanställd aggregatstatistik för plattformsägaren över alla anslutna organisationer."},org_overview:{intentId:"org_overview",rpcName:"get_statistics_scoped",allowedParams:[{name:"_scope",type:"enum",required:!1,enumValues:["own","concern"],description:"'own' = egna organisationen, 'concern' = hela koncernen."}],requiredRoles:["company_admin","therapist"],title:"Översikt för organisationen",description:"Antal klienter och genomförandegrad för din organisation ('own') eller hela koncernen ('concern'). K-anonymiserad."},org_therapist_breakdown:{intentId:"org_therapist_breakdown",rpcName:"get_org_therapist_stats_self",allowedParams:[],requiredRoles:["company_admin","therapist"],title:"Per terapeut i organisationen",description:"Fördelning av klienter och utfall per terapeut inom din organisation."},org_relapse:{intentId:"org_relapse",rpcName:"get_relapse_stats_self",allowedParams:[],requiredRoles:["company_admin","therapist"],title:"Återfall i organisationen",description:"Återfallsstatistik vid uppföljning för din organisation. K-anonymiserad (celler < 5 döljs)."}},As="none";function Cs(t){const r=new Set(t);return Object.values(We).filter(s=>s.requiredRoles.some(a=>r.has(a)))}function Ls(t,r){const s=r??{},a=new Map(t.allowedParams.map(i=>[i.name,i]));for(const i of Object.keys(s))if(!a.has(i))return{ok:!1,args:{},reason:`Okänd parameter: ${i}`};const n={};for(const i of t.allowedParams){const o=s[i.name];if(o==null||o===""){if(i.required)return{ok:!1,args:{},reason:`Parameter saknas: ${i.name}`};continue}if(!Ts(o,i))return{ok:!1,args:{},reason:`Ogiltigt värde för ${i.name}`};n[i.name]=o}return{ok:!0,args:n}}function Ts(t,r){var s;switch(r.type){case"integer":return typeof t=="number"&&Number.isInteger(t);case"uuid":return typeof t=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t);case"date":return typeof t=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(t);case"enum":case"period":return typeof t=="string"&&(((s=r.enumValues)==null?void 0:s.includes(t))??!1);default:return!1}}const Ms=.5;function Ps(t){return["Du är en router som mappar en svensk statistikfråga till EXAKT ett intent ur en fast katalog.","Du får ALDRIG hitta på ett intentId eller en parameter som inte finns i katalogen.","Du skriver ALDRIG SQL och du beräknar aldrig siffror själv.",'Om ingen intent matchar frågan tillräckligt väl, returnera intentId="none".',"","Katalog över tillåtna intents:",t.map(s=>{const a=s.allowedParams.length===0?"inga parametrar":s.allowedParams.map(n=>`${n.name} (${n.type}${n.required?", obligatorisk":""})${n.enumValues?` [${n.enumValues.join("|")}]`:""}`).join(", ");return`- ${s.intentId}: ${s.description} Parametrar: ${a}.`}).join(`
23`),"",'Svara enbart med JSON på formen {"intentId": string, "params": object, "confidence": number}.',"confidence är 0–1 för hur säker mappningen är. params är {} när inga parametrar behövs."].join(`
24`)}const $s={type:"object",properties:{intentId:{type:"string"},params:{type:"object"},confidence:{type:"number"}},required:["intentId","confidence"],additionalProperties:!1};function Fs(t){const{call:r}=Lt(),[s,a]=g.useState(!1),[n,i]=g.useState(null),o=Cs(t);return{ask:g.useCallback(async m=>{const l=(h,x,v,j,p)=>{C("log_stats_nl_query",{_intent_id:v??null,_confidence:j??null,_outcome:h,_question_category:x,_rpc_name:p??null}).then(()=>{},()=>{})},f=(h,x)=>{const v={status:"cannot_answer",reason:h};return i(v),l("cannot_answer",x),v},S=m.trim();if(!S)return f("Tom fråga.","empty");if(o.length===0)return f("Inga statistikfrågor är tillgängliga för din roll ännu.","no_access");a(!0);try{const h=await r({surface:"stats-nl-intent",system:Ps(o),messages:[{role:"user",content:S}],jsonSchema:$s,maxTokens:300,temperature:0});if(!h||typeof h.content!="object"||h.content===null)return f("AI-tjänsten kunde inte tolka frågan just nu.","ai_error");const{intentId:x,params:v,confidence:j=0}=h.content;if(!x||x===As)return f("Frågan matchar ingen tillgänglig statistik. Prova att formulera om.","unmatched");const p=We[x];if(!p)return f("Frågan kunde inte kopplas till en giltig statistikkälla.","invali
24d_intent");const B=new Set(t);if(!p.requiredRoles.some($=>B.has($))){const $={status:"cannot_answer",reason:"Du har inte behörighet till den här statistiken."};return i($),l("denied","role_denied",x,j),$}if(j<Ms)return f("Osäker på vad du menar. Prova att formulera om frågan mer specifikt.","low_confidence");const K=Ls(p,v);if(!K.ok){const $={status:"cannot_answer",reason:K.reason??"Ogiltiga parametrar för frågan."};return i($),l("cannot_answer","invalid_params",x,j),$}const{data:E,error:y}=await C(p.rpcName,Object.keys(K.args).length?K.args:void 0);if(y){const $={status:"cannot_answer",reason:"Kunde inte hämta statistiken just nu."};return i($),l("cannot_answer","rpc_error",x,j,p.rpcName),$}const z={status:"ok",intent:p,data:E,confidence:j};return i(z),l("ok","matched",x,j,p.rpcName),z}finally{a(!1)}},[o,r,t]),loading:s,result:n,setResult:i}}const Rs="—";function ne(t){return t==null?Rs:typeof t=="boolean"?t?"Ja":"Nej":typeof t=="number"?String(t):typeof t=="string"?t:JSON.stringify(t)}function pe(t){return t.replace(/_/g," ").replace(/^\w/,r=>r.toUpperCase())}function Is({obj:t}){const r=Object.entries(t).filter(([,s])=>s===null||typeof s!="object");return r.length===0?null:e.jsx("dl",{className:"grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-3",children:r.map(([s,a])=>e.jsxs("div",{className:"flex flex-col rounded-md border border-border bg-muted/30 p-2",children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:pe(s)}),e.jsx("dd",{className:"text-sm font-medium tabular-nums",children:ne(a)})]},s))})}function Ks({rows:t}){if(t.length===0)return e.jsx("p",{className:"text-sm text-muted-foreground py-2",children:"Inga rader."});const r=Array.from(new Set(t.flatMap(s=>Object.keys(s))));return e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsx("tr",{className:"border-b border-border text-left text-xs text-muted-foreground",children:r.map(s=>e.jsx("th",{className:"py-1 pr-4 font-medium",children:pe(s)},s))})}),e.jsx("tbody",{children:t.map((s,a)=>e.jsx("tr",{className:"border-b border-border/50",children:r.map(n=>e.jsx("td",{className:"py-1 pr-4 tabular-nums",children:ne(s[n])},n))},a))})]})})}function Xe({data:t}){if(t==null)return e.jsx("p",{className:"text-sm text-muted-foreground",children:"Ingen data."});if(Array.isArray(t)){const r=t.filter(s=>typeof s=="object"&&s!==null);return r.length===t.length&&t.length>0?e.jsx(Ks,{rows:r}):e.jsx("ul",{className:"list-disc pl-5 text-sm",children:t.map((s,a)=>e.jsx("li",{children:ne(s)},a))})}if(typeof t=="object"){const r=t,s=Object.entries(r).filter(([,a])=>typeof a=="object"&&a!==null);return e.jsxs("div",{className:"space-y-4",children:[e.jsx(Is,{obj:r}),s.map(([a,n])=>e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground",children:pe(a)}),e.jsx(Xe,{data:n})]},a))]})}return e.jsx("p",{className:"text-sm",children:ne(t)})}function Ds({result:t}){return t.status==="cannot_answer"?e.jsxs("div",{className:"flex items-start gap-2 rounded-lg border border-warning/40 bg-warning/10 p-3 text-sm",children:[e.jsx(pt,{className:"h-4 w-4 mt-0.5 flex-shrink-0 text-warning"}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Kan inte svara på frågan"}),e.jsx("p",{className:"text-muted-foreground",children:t.reason})]})]}):e.jsxs("div",{className:"space-y-3 rounded-lg border border-border p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(jt,{className:"h-4 w-4 text-primary"}),e.jsx("span",{className:"font-medium",children:t.intent.title}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["(tolkning: ",t.intent.intentId," · säkerhet ",Math.round(t.confidence*100),"%)"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t.intent.description}),e.jsx(Xe,{data:t.data})]})}const qs=["Hur många aktiva klienter finns på plattformen?","Visa nykterhet vid uppföljning","Genomförandegrad per program"];function Os({roles:t}){const{ask:r,loading:s,result:a}=Fs(t),[n,i]=g.useState(""),o=()=>{!s&&n.trim()&&r(n)};return e.jsxs(b,{className:"bg-card shadow-sm",children:[e.jsx(k,{children:e.jsxs(w,{className:"flex items-center gap-2 text-lg",children:[e.jsx(Ge,{className:"h-4 w-4 text-primary"}),"Fråga statistiken (AI)"]})}),e.jsxs(_,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start gap-2 rounded-lg border border-border bg-muted/40 p-3 text-xs text-muted-foreground",children:[e.jsx(le,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsx("p",{children:"Ställ en fråga i fritext. AI:n väljer bland fördefinierade, anonymiserade statistikkällor och kör dem — den skriver aldrig egna databasfrågor och beräknar inga egna siffror. Kan frågan inte kopplas till en källa svarar den att den inte kan svara."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Nt,{value:n,onChange:u=>i(u.target.value),onKeyDown:u=>{u.key==="Enter"&&o()},placeholder:"t.ex. Hur många aktiva klienter finns på plattformen?",disabled:s,"aria-label":"Statistikfråga"}),e.jsx(P,{onClick:o,disabled:s||!n.trim(),children:s?e.jsx(O,{className:"h-4 w-4 animate-spin"}):e.jsx(bt,{className:"h-4 w-4"})})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:qs.map(u=>e.jsx("button",{type:"button",disabled:s,onClick:()=>{i(u),r(u)},className:"rounded-full border border-border px-3 py-1 text-xs text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:opacity-50",children:u},u))}),a&&e.jsx(Ds,{result:a})]})]})}function Xs(){const t=_t(),{effectiveRole:r,user:s,hasRole:a}=V(),n=ee(),[i,o]=g.useState(null),[u,m]=g.useState(!1),l=a("therapist"),f=r==="superuser",S=a("company_admin"),h=a("conglomerate_admin"),x=g.useMemo(()=>{const p=[];return f&&p.push("superuser"),S&&p.push("company_admin"),l&&p.push("therapist"),p},[f,S,l]);g.useEffect(()=>{!l||!s||Q.from("therapists").select("id, is_active").eq("user_id",s.id).then(({data:p})=>{const B=p??[],K=B.find(E=>E.is_active)??B[0];K&&o(K.id),m(!0)})},[l,s]);const v=g.useMemo(()=>
24{if(f)return[{value:"platform",label:"Plattformen"},{value:"extended",label:"Utökad"}];const p=[];return l&&p.push({value:"mine",label:"Mina"}),p.push({value:"company",label:"Företaget"}),h&&p.push({value:"conglomerate",label:"Koncernen"}),p.push({value:"platform",label:"Plattformen"}),p.push({value:"extended",label:"Utökad"}),p},[l,f,h]),j=v[0].value;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(P,{variant:"ghost",size:"sm",onClick:()=>t(-1),className:"gap-1.5 text-muted-foreground hover:text-foreground",children:[e.jsx(vt,{className:"w-4 h-4"}),"Gå tillbaka"]}),e.jsx("h1",{className:"text-2xl font-semibold tracking-tight",children:"Statistik"}),x.length>0&&e.jsx(Os,{roles:x}),v.length===1?e.jsx(Pe,{}):e.jsxs(yt,{defaultValue:j,children:[e.jsx(kt,{children:v.map(p=>e.jsx(wt,{value:p.value,children:p.label},p.value))}),l&&e.jsx(Z,{value:"mine",children:i?e.jsx(Kt,{therapistId:i}):u?e.jsx("p",{className:"text-sm text-muted-foreground py-8 text-center",children:"Ingen terapeutprofil hittades. Kontakta din administratör."}):e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(O,{className:"h-6 w-6 animate-spin text-primary"})})}),!f&&e.jsx(Z,{value:"company",children:e.jsx(ms,{organizationId:n})}),h&&e.jsx(Z,{value:"conglomerate",children:e.jsx(xs,{organizationId:n})}),e.jsx(Z,{value:"platform",children:e.jsx(Pe,{})}),e.jsx(Z,{value:"extended",children:e.jsx(Es,{})})]})]})}export{Xs as default};

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.