1import{H as ne,K as te,P as oe,r as s,ax as de,ay as ce,j as e,h as W,S as o,G as n,v as he,T as c,B as p,g as q,e as G,V as H,o as A,A as P,w as ue,i as me}from"./index-CB1LRsvg.js";import{C as xe,I as je}from"./IconCopy-Coo_r-4m.js";import{I as N}from"./IconTrash-B56plgcD.js";import{u as pe}from"./usePageTitle-PP7G01cs.js";import{S as ve}from"./StatusText-gwUfW1V-.js";import{S as J}from"./SectionTitle-DUWdJHXc.js";import{u as be,P as ge}from"./Pagination-B0OfeLTu.js";import{u as fe}from"./use-form-CaiTdMy3.js";import{T as a}from"./Table-D4aHVX52.js";import{A as Te}from"./Avatar-BsrwxVRy.js";import{B as y}from"./Badge-CvorhVBt.js";import{S as ye}from"./SegmentedControl-B2vw4mHc.js";import{A as we}from"./Alert-Dvpb9ICu.js";import"./use-clipboard-Dyb8n21I.js";import"./layout-2mrj5SBU.js";import"./index-C148XJoK.js";/** 2 * @license @tabler/icons-react v3.41.1 - MIT 3 * 4 * This source code is licensed under the MIT license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const Se=[["path",{d:"M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0",key:"svg-0"}],["path",{d:"M16 19h6",key:"svg-1"}],["path",{d:"M19 16v6",key:"svg-2"}],["path",{d:"M6 21v-2a4 4 0 0 1 4 -4h4",key:"svg-3"}]],Ce=ne("outline","user-plus","UserPlus",Se);function Ie(h){return`${window.location.origin}/invites/${h}`}function We(){pe("Team Members");const{user:h}=te(),K=(h==null?void 0:h.id)??null,{teams:w}=oe(),l=w==null?void 0:w.find(r=>r.is_active),_=l==null?void 0:l.id,S=l==null?void 0:l.role,L=S==="owner"||S==="admin",C=20,[I,R]=s.useState(1),[V,Z]=s.useState(""),[k]=be(V,250),[v,Q]=s.useState("");s.useEffect(()=>{R(1)},[k,v]);const X=s.useMemo(()=>({q:k,role:v,limit:C,offset:(I-1)*C}),[k,v,I]),{members:b,total:F,loading:E,updateRole:Y,removeMember:ee}=de(_,X),D=Math.max(1,Math.ceil(F/C)),{invites:t,createInvite:re,revokeInvite:ae}=ce(_),[se,g]=s.useState(!1),d=fe({mode:"controlled",initialValues:{email:"",role:"viewer"},validate:{email:r=>r.trim()?null:"Email is required."}}),{role:O}=d.values,[le,B]=s.useState(!1),[U,M]=s.useState(null),[f,u]=s.useState(null),[z,T]=s.useState(null);if(!l)return e.jsx(W,{role:"status","aria-label":"Loading team"});const $=l.is_system,m=L&&!$,ie=async r=>{M(null),B(!0);const i=r.email.trim().toLowerCase(),x=await re(i,r.role);if(B(!1),!x.ok){M(x.error);return}const j=x.invite.token;T(i),u(j?Ie(j):null),d.setFieldValue("email","")};return e.jsxs(o,{gap:"xl",children:[e.jsxs(n,{justify:"space-between",align:"flex-end",children:[e.jsxs(o,{gap:2,children:[e.jsxs(he,{order:2,children:["Members of ",l.name]}),e.jsx(c,{size:"sm",c:"dimmed",children:$?"Every signup automatically joins this team.":"People who can access this team's workspaces and datasources."})]}),m&&e.jsx(p,{variant:"primary",leftSection:e.jsx(Ce,{size:16,"aria-hidden":!0}),onClick:()=>{g(!0),u(null)},children:"Invite member"})]}),e.jsxs(o,{gap:"xs",children:[e.jsx(J,{order:3,count:F,mb:0,children:"Members"}),e.jsxs(n,{gap:"xs",wrap:"wrap",children:[e.jsx(q,{"aria-label":"Search members",placeholder:"Search by name or email",value:V,onChange:r=>Z(r.currentTarget.value),w:280}),e.jsx(G,{"aria-label":"Filter by role",placeholder:"All roles",value:v||null,onChange:r=>Q(r??""),data:[{value:"owner",label:"Owner"},{value:"admin",label:"Admin"},{value:"creator",label:"Creator"},{value:"viewer",label:"Viewer"}],clearable:!0,w:160})]}),e.jsx(a.ScrollContainer,{minWidth:640,children:e.jsxs(a,{"aria-label":"Members",children:[e.jsx(a.Thead,{children:e.jsxs(a.Tr,{children:[e.jsx(a.Th,{children:"User"}),e.jsx(a.Th,{children:"Seat"}),e.jsx(a.Th,{children:"Team role"}),e.jsx(a.Th,{children:"Joined"}),e.jsx(a.Th,{children:"Last login"}),m&&e.jsx(a.Th,{children:e.jsx(H,{children:"Actions"})})]})}),e.jsxs(a.Tbody,{children:[E&&e.jsx(a.Tr,{children:e.jsx(a.Td,{colSpan:m?6:5,children:e.jsx(n,{justify:"center",py:"sm",children:e.jsx(W,{size:"sm",role:"status","aria-label":"Loading members"})})})}),!E&&(b??[]).map(r=>{const i=r.user_id===K,x=m&&!i;return e.jsxs(a.Tr,{children:[e.jsx(a.Td,{children:e.jsxs(n,{gap:"xs",wrap:"nowrap",children:[e.jsx(Te,{name:r.username,size:"sm",radiu
6s:"xl"}),e.jsx(c,{children:r.username}),i&&e.jsx(y,{size:"xs",variant:"light",color:"gray",children:"you"})]})}),e.jsx(a.Td,{children:e.jsx(y,{size:"xs",variant:"outline",color:r.role==="viewer"?"gray":"blue",children:r.role==="viewer"?"Free":"Paid"})}),e.jsx(a.Td,{children:x&&r.role!=="owner"?e.jsx(G,{"aria-label":`Change role for ${r.username}`,size:"xs",w:120,value:r.role,onChange:j=>j&&Y(r.user_id,j),data:[{value:"viewer",label:"Viewer"},{value:"creator",label:"Creator"},{value:"admin",label:"Admin"},...S==="owner"?[{value:"owner",label:"Owner"}]:[]],allowDeselect:!1}):e.jsx(y,{variant:"light",children:r.role})}),e.jsx(a.Td,{children:new Date(r.joined_at).toLocaleDateString()}),e.jsx(a.Td,{children:r.last_login_at?new Date(r.last_login_at).toLocaleString():e.jsx(c,{size:"xs",c:"dimmed",children:"never"})}),m&&e.jsx(a.Td,{children:!i&&e.jsx(A,{label:"Remove",children:e.jsx(P,{"aria-label":`Remove ${r.username}`,variant:"subtle",color:"red",onClick:()=>ee(r.user_id),children:e.jsx(N,{size:16,"aria-hidden":!0})})})})]},r.user_id)})]})]})}),!E&&((b==null?void 0:b.length)??0)===0&&e.jsx(ve,{size:"sm",c:"dimmed",ta:"center",py:"md",children:"No members match these filters."}),D>1&&e.jsx(n,{justify:"center",mt:"xs",children:e.jsx(ge,{value:I,onChange:R,total:D})})]}),((t==null?void 0:t.length)??0)>0&&e.jsxs(o,{gap:"xs",children:[e.jsx(J,{order:3,count:t==null?void 0:t.length,mb:0,children:"Pending invites"}),e.jsx(a.ScrollContainer,{minWidth:480,children:e.jsxs(a,{"aria-label":"Pending invites",children:[e.jsx(a.Thead,{children:e.jsxs(a.Tr,{children:[e.jsx(a.Th,{children:"Email"}),e.jsx(a.Th,{children:"Role"}),e.jsx(a.Th,{children:"Expires"}),e.jsx(a.Th,{children:e.jsx(H,{children:"Actions"})})]})}),e.jsx(a.Tbody,{children:(t??[]).map(r=>e.jsxs(a.Tr,{children:[e.jsx(a.Td,{children:r.email}),e.jsx(a.Td,{children:e.jsx(y,{variant:"light",children:r.role})}),e.jsx(a.Td,{children:new Date(r.expires_at).toLocaleDateString()}),e.jsx(a.Td,{children:L&&e.jsx(A,{label:"Revoke",children:e.jsx(P,{"aria-label":`Revoke invitation for ${r.email}`,variant:"subtle",color:"red",onClick:()=>ae(r.id),children:e.jsx(N,{size:16,"aria-hidden":!0})})})})]},r.id))})]})})]}),e.jsx(ue,{opened:se,onClose:()=>{g(!1),u(null),T(null),M(null),d.clearErrors()},title:z?"Invite created":"Invite a member",children:z?e.jsxs(o,{gap:"md",children:[e.jsxs(c,{size:"sm",children:["Invite created for ",e.jsx("strong",{children:z}),".",f?" Email delivery isn't wired up yet â copy this link and send it manually.":""]}),f&&e.jsxs(n,{gap:"xs",wrap:"nowrap",children:[e.jsx(c,{size:"xs",ff:"monospace",truncate:!0,flex:1,children:f}),e.jsx(xe,{value:f,children:({copied:r,copy:i})=>e.jsx(A,{label:r?"Copied":"Copy invite link",children:e.jsx(P,{onClick:i,variant:"subtle","aria-label":r?"Copied invite link":"Copy invite link",children:r?e.jsx(me,{size:16,"aria-hidden":!0}):e.jsx(je,{size:16,"aria-hidden":!0})})})})]}),e.jsxs(n,{justify:"flex-end",children:[e.jsx(p,{variant:"default",onClick:()=>{u(null),T(null)},children:"Invite another"}),e.jsx(p,{variant:"primary",onClick:()=>{g(!1),u(null),T(null)},children:"Done"})]})]}):e.jsx("form",{onSubmit:d.onSubmit(r=>void ie(r)),noValidate:!0,children:e.jsxs(o,{gap:"md",children:[e.jsx(q,{label:"Email",type:"email",placeholder:"[email protected]",required:!0,"data-autofocus":!0,...d.getInputProps("email")}),e.jsxs(o,{gap:4,children:[e.jsx(ye,{"aria-label":"Role","aria-describedby":"invite-role-hint",value:O,onChange:r=>d.setFieldValue("role",r),data:[{label:"Viewer",value:"viewer"},{label:"Creator",value:"creator"},{label:"Admin",value:"admin"}],fullWidth:!0}),e.jsx(c,{size:"xs",c:"dimmed",id:"invite-role-hint",children:O==="viewer"?"Free â viewers can browse but not create.":"Paid seat â billed at the next cycle."})]}),U&&e.jsx(we,{color:"red",children:U}),e.jsxs(n,{justify:"flex-end",children:[e.jsx(p,{type:"button",variant:"default",onClick:()=>g(!1),children:"Cancel"}),e.jsx(p,{type:"submit",variant:"primary",loading:le,children:"Send invite"})]})]})})})]})}export{We 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.