1import{c as V,r as n,j as e,B as F,w,I as M,t as E,q as T,a5 as I,p as S,v as Y,a7 as X,L as D,bu as Z,s as ee,e as se,ad as te,ae,$ as re}from"./index-CfXbMZ_V.js";import{P as ne}from"./PortalHeader-BREe-gcq.js";import{D as $,a as R,b as H,c as q}from"./dialog-D3H816yE.js";import{E as ie}from"./EditOfficeDialog-B5BVX8y1.js";import{P as le}from"./pencil-DCKB3rA6.js";import"./chevron-left-BFeklwt6.js";import"./image-plus-jcrtLFLV.js";/** 2 * @license lucide-react v0.475.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 de=[["path",{d:"m18 14 4 4-4 4",key:"10pe0f"}],["path",{d:"m18 2 4 4-4 4",key:"pucp1d"}],["path",{d:"M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22",key:"1ailkh"}],["path",{d:"M2 6h1.972a4 4 0 0 1 3.6 2.2",key:"km57vx"}],["path",{d:"M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45",key:"os18l9"}]],ce=V("Shuffle",de);/** 7 * @license lucide-react v0.475.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 oe=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],me=V("UserMinus",oe),G={name:"",trading_name:"",office_type:"Branch",address:"",state:"",phone:"",email:""};function xe({open:y,onOpenChange:f,onCreated:i}){const[l,c]=n.useState(G),[m,j]=n.useState(!1),[p,b]=n.useState(""),v=async()=>{var a,h,_;if(l.name.trim()){j(!0),b("");try{const r=await S.functions.invoke("manageOffice",{action:"create_office",...l});c(G),f(!1),i==null||i((a=r==null?void 0:r.data)==null?void 0:a.office)}catch(r){b(((_=(h=r.response)==null?void 0:h.data)==null?void 0:_.error)||r.message||"Failed to create office")}finally{j(!1)}}};return e.jsx($,{open:y,onOpenChange:a=>{a||b(""),f(a)},children:e.jsxs(R,{className:"max-w-md bg-card border-border text-foreground",children:[e.jsx(H,{children:e.jsxs(q,{className:"text-foreground flex items-center gap-2",children:[e.jsx(F,{size:18})," New office"]})}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Office name *"}),e.jsx(M,{value:l.name,onChange:a=>c({...l,name:a.target.value}),className:"mt-1 bg-muted border-border",placeholder:"e.g. Melbourne Branch"})]}),e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Trading name"}),e.jsx(M,{value:l.trading_name,onChange:a=>c({...l,trading_name:a.target.value}),className:"mt-1 bg-muted border-border"})]}),e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Type"}),e.jsxs("select",{value:l.office_type,onChange:a=>c({...l,office_type:a.target.value}),className:"mt-1 w-full h-10 rounded-md bg-muted border border-border px-3 text-foreground",children:[e.jsx("option",{value:"Main",children:"Main"}),e.jsx("option",{value:"Branch",children:"Branch"}),e.jsx("option",{value:"Franchise",children:"Franchise"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"State"}),e.jsx(M,{value:l.state,onChange:a=>c({...l,state:a.target.value}),className:"mt-1 bg-muted border-border"})]}),e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Phone"}),e.jsx(M,{value:l.phone,onChange:a=>c({...l,phone:a.target.value}),className:"mt-1 bg-muted border-border"})]})]}),e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Email"}),e.jsx(M,{value:l.email,onChange:a=>c({...l,email:a.target.value}),className:"mt-1 bg-muted border-border"})]}),p&&e.jsx("p",{className:"text-xs text-red-500",children:p})]}),e.jsxs("div",{className:"flex gap-2 pt-1",children:[e.jsx(E,{variant:"outline",className:"flex-1 border-border text-muted-foreground",onClick:()=>f(!1),children:"Cancel"}),e.jsxs(E,{className:"flex-1 bg-blue-600 hover:bg-blue-700",disabled:m||!l.name.trim(),onClick:v,children:[m?e.jsx(T,{size:16,className:"animate-spin mr-1"}):e.jsx(I,{size:16,className:"mr-1"}),"Create"]})]})]})})}const ue=[{key:"accountant",label:"Accountant"},{key:"staff",label:"Staff"},{key:"office_admin",label:"Office Admin"},{key:"office_owner",label:"Office Owner"}];function fe({open:y,onOpenChange:f,office:i,onDone:l}){const[c,m]=n.useState(""),[j,p]=n.useState("accountant"),[b,v]=n.useState(""),[a,h]=n.useState(!0),[_,r]=n.useState(!1),[N,k]=n.useState(""),g=async()=>{var d,C;if(c.trim()){r(!0),k("");try{await S.functions.invoke("manageOffice",{action:"add_member",office_id:i.id,email:c.trim(),role_key:j,job_title:b,invite:a}),m(""),p("accountant"),v(""),h(!0),f(!1),l==null||l()}catch(L){k(((C=(d=L.response)==null?void 0:d.data)==null?void 0:C.error)||L.message||"Failed to add member")}finally{r(!1)}}};return e.jsx($,{open:y,onOpenChange:d=>{d||k(""),f(d)},children:e.jsxs(R,{className:"max-w-md bg-card border-border text-foreground",children:[e.jsx(H,{children:e.jsxs(q,{className:"text-foreground flex items-center gap-2",children:[e.jsx(Y,{size:18})," Add member to ",i==null?void 0:i.name]})}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Email *"}
11),e.jsx(M,{type:"email",value:c,onChange:d=>m(d.target.value),className:"mt-1 bg-muted border-border",placeholder:"[email protected]"})]}),e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Role"}),e.jsx("select",{value:j,onChange:d=>p(d.target.value),className:"mt-1 w-full h-10 rounded-md bg-muted border border-border px-3 text-foreground",children:ue.map(d=>e.jsx("option",{value:d.key,children:d.label},d.key))})]}),e.jsxs("div",{children:[e.jsx(w,{className:"text-muted-foreground",children:"Job title (optional)"}),e.jsx(M,{value:b,onChange:d=>v(d.target.value),className:"mt-1 bg-muted border-border"})]}),e.jsxs("label",{className:"flex items-center gap-2 text-xs text-muted-foreground cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:a,onChange:d=>h(d.target.checked),className:"accent-blue-600"}),e.jsx(X,{size:13})," Send platform invite if they aren't registered yet"]}),N&&e.jsx("p",{className:"text-xs text-red-500",children:N})]}),e.jsxs("div",{className:"flex gap-2 pt-1",children:[e.jsx(E,{variant:"outline",className:"flex-1 border-border text-muted-foreground",onClick:()=>f(!1),children:"Cancel"}),e.jsxs(E,{className:"flex-1 bg-blue-600 hover:bg-blue-700",disabled:_||!c.trim(),onClick:g,children:[_?e.jsx(T,{size:16,className:"animate-spin mr-1"}):e.jsx(Y,{size:16,className:"mr-1"}),"Add"]})]})]})})}function he({open:y,onOpenChange:f,fromOffice:i,offices:l,onDone:c}){const[m,j]=n.useState(""),[p,b]=n.useState(!1),[v,a]=n.useState(""),h=()=>{j(""),a("")},_=async()=>{var r,N,k;if(m){if(m===(i==null?void 0:i.id)){a("Choose a different target office");return}if(confirm(`Move ALL clients from "${i==null?void 0:i.name}" into the target office? This is used when a franchise changes ownership.`)){b(!0),a("");try{const g=await S.functions.invoke("manageClientOffice",{action:"transfer_office",from_office_id:i.id,to_office_id:m});h(),f(!1),c==null||c((r=g==null?void 0:g.data)==null?void 0:r.moved)}catch(g){a(((k=(N=g.response)==null?void 0:N.data)==null?void 0:k.error)||g.message||"Failed to transfer")}finally{b(!1)}}}};return e.jsx($,{open:y,onOpenChange:r=>{r||h(),f(r)},children:e.jsxs(R,{className:"max-w-sm bg-card border-border text-foreground",children:[e.jsx(H,{children:e.jsxs(q,{className:"text-foreground flex items-center gap-2",children:[e.jsx(ce,{size:16})," Transfer all clients"]})}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Move every client currently in ",e.jsx("span",{className:"font-semibold text-foreground",children:i==null?void 0:i.name})," into another office. Use this when a franchise changes ownership â all client ledger records move with them."]}),e.jsxs("select",{value:m,onChange:r=>j(r.target.value),className:"w-full h-10 rounded-md border border-input bg-muted px-3 text-sm text-foreground",children:[e.jsx("option",{value:"",children:"Target officeâ¦"}),l.filter(r=>r.id!==(i==null?void 0:i.id)).map(r=>e.jsxs("option",{value:r.id,children:[r.name,r.is_default?" (Default)":""]},r.id))]}),v&&e.jsx("p",{className:"text-xs text-red-600",children:v})]}),e.jsxs("div",{className:"flex gap-2 pt-1",children:[e.jsx(E,{variant:"outline",className:"flex-1 border-border text-muted-foreground",onClick:()=>f(!1),children:"Cancel"}),e.jsxs(E,{className:"flex-1 bg-violet-600 hover:bg-violet-700",disabled:p||!m,onClick:_,children:[p?e.jsx(T,{size:16,className:"animate-spin mr-1"}):null," Transfer all"]})]})]})})}const be={office_owner:"Office Owner",office_admin:"Office Admin",accountant:"Accountant",staff:"Staff"},Q={active:"bg-emerald-500/15 text-emerald-600",invited:"bg-amber-500/15 text-amber-600",suspended:"bg-red-500/15 text-red-600",revoked:"bg-gray-500/15 text-gray-500"};function ke(){const[y,f]=n.useState([]),[i,l]=n.useState(!0),[c,m]=n.useState(""),[j,p]=n.useState(!1),[b,v]=n.useState(null),[a,h]=n.useState({}),[_,r]=n.useState(null),[N,k]=n.useState(null),[g,d]=n.useState(null),[C,L]=n.useState(!1),[A,B]=n.useState(null),[P,U]=n.useState(null),O=async()=>{var s,o,x,t;l(!0),m("");try{const[u,z]=await Promise.all([S.functions.invoke("manageOffice",{action:"list_office
11s"}),S.functions.invoke("manageOffice",{action:"org_overview"}).catch(()=>null)]);f(((s=u==null?void 0:u.data)==null?void 0:s.offices)||[]),(o=z==null?void 0:z.data)!=null&&o.organisation&&L(!0)}catch(u){m(((t=(x=u.response)==null?void 0:x.data)==null?void 0:t.error)||u.message||"Failed to load offices")}finally{l(!1)}};n.useEffect(()=>{O()},[]);const J=async s=>{if(b===s.id){v(null);return}if(v(s.id),!!s.accessible){r(s.id);try{const o=await S.functions.invoke("manageOffice",{action:"list_members",office_id:s.id});h(x=>{var t;return{...x,[s.id]:((t=o==null?void 0:o.data)==null?void 0:t.members)||[]}})}catch{h(o=>({...o,[s.id]:[]}))}finally{r(null)}}},K=async(s,o)=>{var x,t;d(s.id);try{await S.functions.invoke("manageOffice",{action:"update_member",membership_id:s.id,membership_status:o}),h(u=>({...u,[s.office_id]:(u[s.office_id]||[]).map(z=>z.id===s.id?{...z,membership_status:o}:z)}))}catch(u){alert(((t=(x=u.response)==null?void 0:x.data)==null?void 0:t.error)||u.message||"Failed")}finally{d(null)}},W=async s=>{var o,x;if(confirm(`Remove ${s.user_email||s.user_id} from this office?`)){d(s.id);try{await S.functions.invoke("manageOffice",{action:"remove_member",membership_id:s.id}),h(t=>({...t,[s.office_id]:(t[s.office_id]||[]).filter(u=>
11u.id!==s.id)})),await O()}catch(t){alert(((x=(o=t.response)==null?void 0:o.data)==null?void 0:x.error)||t.message||"Failed")}finally{d(null)}}};return e.jsxs("div",{className:"space-y-4 pb-10",children:[e.jsx(ne,{title:"Offices",subtitle:"Manage workspaces and members"}),e.jsxs("div",{className:"flex justify-between gap-2 items-center",children:[C&&e.jsxs(D,{to:"/org",className:"inline-flex items-center gap-1.5 text-sm font-semibold text-violet-600",children:[e.jsx(F,{size:16})," Organisation overview"]}),C&&e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs(D,{to:"/org/staff",className:"inline-flex items-center gap-1.5 text-sm font-semibold text-blue-600",children:[e.jsx(Z,{size:16})," Staff"]}),e.jsxs(E,{onClick:()=>p(!0),size:"sm",className:"bg-blue-600 hover:bg-blue-700",children:[e.jsx(I,{size:16})," New office"]})]})]}),i?e.jsx("div",{className:"flex justify-center py-16",children:e.jsx(T,{className:"w-6 h-6 text-blue-500 animate-spin"})}):c?e.jsx("div",{className:"bg-red-50 border border-red-200 rounded-2xl p-4 text-sm text-red-700",children:c}):y.length===0?e.jsxs("div",{className:"bg-card border border-border rounded-2xl p-8 text-center",children:[e.jsx(F,{size:28,className:"mx-auto text-gray-400 mb-2"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No offices yet. Create your first office."})]}):e.jsx("div",{className:"space-y-3",children:y.map(s=>{const o=b===s.id,x=a[s.id]||[];return e.jsxs("div",{className:"bg-card border border-border rounded-2xl overflow-hidden",children:[e.jsxs("button",{onClick:()=>J(s),className:"w-full flex items-center justify-between p-4 text-left hover:bg-muted/50 transition-colors",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(F,{size:16,className:"text-blue-600 shrink-0"}),e.jsx("span",{className:"font-semibold text-foreground truncate",children:s.name}),s.is_default&&e.jsx("span",{className:"text-[10px] bg-blue-500/15 text-blue-600 px-1.5 py-0.5 rounded-full",children:"Default"}),s.office_type!=="Branch"&&e.jsx("span",{className:"text-[10px] bg-muted text-muted-foreground px-1.5 py-0.5 rounded-full",children:s.office_type}),!s.accessible&&e.jsx(ee,{size:12,className:"text-amber-500"})]}),s.address&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-1 truncate",children:[s.address,s.state?`, ${s.state}`:""]})]}),e.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(se,{size:13})," ",s.member_count]}),s.accessible&&e.jsx(D,{to:`/org/offices/${s.id}`,onClick:t=>t.stopPropagation(),className:"text-[11px] font-semibold text-blue-600 px-2 py-1 rounded hover:bg-blue-50",children:"Dashboard"}),C&&s.accessible&&e.jsxs("button",{onClick:t=>{t.stopPropagation(),U(s)},className:"text-[11px] font-semibold text-blue-600 px-2 py-1 rounded hover:bg-blue-50",title:"Edit office details",children:[e.jsx(le,{size:11,className:"inline -mt-0.5"})," Edit"]}),C&&s.accessible&&e.jsx("button",{onClick:t=>{t.stopPropagation(),B(s)},className:"text-[11px] font-semibold text-violet-600 px-2 py-1 rounded hover:bg-violet-50",title:"Transfer all clients to another office",children:"Transfer"}),o?e.jsx(te,{size:16,className:"text-muted-foreground"}):e.jsx(ae,{size:16,className:"text-muted-foreground"})]})]}),o&&e.jsx("div",{className:"border-t border-border p-4 space-y-2",children:s.accessible?_===s.id?e.jsx("div",{className:"flex justify-center py-4",children:e.jsx(T,{className:"w-5 h-5 text-blue-500 animate-spin"})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-wide",children:["Members (",x.length,")"]}),e.jsxs("button",{onClick:()=>k(s),className:"text-xs font-semibold text-blue-600 flex items-center gap-1",children:[e.jsx(I,{size:13})," Add"]})]}),x.length===0?e.jsx("p",{className:"text-xs text-muted-foreground py-2",children:"No members yet."}):x.map(t=>e.jsxs("div",{className:"flex items-center justify-between gap-2 py-2 border-b border-border last:border-0",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(re,{size:15,className:"text-muted-foreground shrink-0"}),e.jsx("span",{className:"text-sm text-foreground truncate",children:t.user_email||t.user_id||"Unknown"})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-0.5 ml-5",children:[e.jsx("span",{className:"text-[11px] text-muted-foreground",children:be[t.role_key]||t.role_key}),t.job_title&&e.jsxs("span",{className:"text-[11px] text-muted-foreground",children:["· ",t.j
11ob_title]}),e.jsx("span",{className:`text-[10px] px-1.5 py-0.5 rounded-full ${Q[t.membership_status]||Q.invited}`,children:t.membership_status})]})]}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[t.membership_status==="active"?e.jsx("button",{disabled:g===t.id,onClick:()=>K(t,"suspended"),className:"text-[11px] text-amber-600 px-2 py-1 rounded hover:bg-amber-50 disabled:opacity-50",children:"Suspend"}):e.jsx("button",{disabled:g===t.id,onClick:()=>K(t,"active"),className:"text-[11px] text-emerald-600 px-2 py-1 rounded hover:bg-emerald-50 disabled:opacity-50",children:"Activate"}),e.jsx("button",{disabled:g===t.id,onClick:()=>W(t),className:"w-7 h-7 rounded hover:bg-red-50 flex items-center justify-center disabled:opacity-50","aria-label":"Remove",children:e.jsx(me,{size:14,className:"text-red-500"})})]})]},t.id))]}):e.jsx("p",{className:"text-xs text-muted-foreground py-2",children:"You don't have access to manage this office."})})]},s.id)})}),e.jsx(xe,{open:j,onOpenChange:p,onCreated:()=>O()}),N&&e.jsx(fe,{open:!!N,onOpenChange:s=>!s&&k(null),office:N,onDone:()=>{J(N),O()}}),A&&e.jsx(he,{open:!!A,onOpenChange:s=>!s&&B(null),fromOffice:A,offices:y,onDone:s=>{B(null),O(),alert(`${s||0} clients transferred.`)}}),P&&e.jsx(ie,{office:P,open:!!P,onOpenChange:s=>!s&&U(null),onDone:()=>{U(null),O()}})]})}export{ke 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.