1import{a as N,u as S,d as f,j as e,L as J}from"./vendor-react-Dw2qv6jq.js";import{u as W,F as X,a,b as i,c as n,d as o,e as l,t as Z,o as G,i as Y,j as _,s as m,l as p}from"./form-BDC63DnN.js";import{A as ee}from"./layout-gPbt2FIS.js";import{x as te,U as se,Z as re,B as d,V as ae,W as ie,X as ne,I as h,C as oe,j as le,J as de,K as j,L as g,A as ce,f as ue,h as me,d as T}from"./index-BMu9MsG3.js";import{T as xe}from"./textarea-7tf-1ePq.js";import{S as D,a as E,b as F,c as A,d as y}from"./select-BSpOv3xm.js";import{P as he}from"./page-header-BTbQCW9W.js";import{E as pe}from"./empty-state-azFV2EZ_.js";import{C as I}from"./confirm-dialog-HT802eiJ.js";import{D as je}from"./data-table-BmeFXXDR.js";import{aE as $,ae as ge,aq as be,aO as L,U as ve}from"./vendor-ui-DNVmduUd.js";import"./label-Dtzn2d--.js";import"./separator-BQa-vWro.js";import"./alert-dialog-DPKAjx3p.js";import"./table-BYW17xkq.js";import"./checkbox-CkZwdvfA.js";const we=G({email:m().email("Valid email required"),name:m().min(1,"Name is required"),bio:m().optional().or(p("")),twitterUrl:m().optional().or(p("")),linkedinUrl:m().optional().or(p("")),password:m().min(6,"Password must be at least 6 characters").optional().or(p("")),roleId:_.number().min(1,"Role is required"),status:Y(["active","inactive"])});function qe(){const[P,x]=N.useState(!1),[u,b]=N.useState(null),{toast:c}=te(),{data:q,isLoading:R,isError:V,refetch:K}=S({queryKey:["/api/users"]}),{data:C}=S({queryKey:["/api/roles"]}),r=W({resolver:Z(we),defaultValues:{email:"",name:"",bio:"",twitterUrl:"",linkedinUrl:"",password:"",roleId:1,status:"active"}}
1),v=f({mutationFn:async t=>{const s={...t};return s.password||delete s.password,u?g("PATCH",`/api/users/${u.id}`,s):g("POST","/api/users",s)},onSuccess:()=>{j.invalidateQueries({queryKey:["/api/users"]}),c({title:u?"User updated":"User created"}),x(!1),b(null),r.reset()},onError:()=>{c({title:"Error",description:"Failed to save user.",variant:"destructive"})}}),M=f({mutationFn:async t=>g("DELETE",`/api/users/${t}`),onSuccess:()=>{j.invalidateQueries({queryKey:["/api/users"]}),c({title:"User deleted successfully"})},onError:t=>{const s=t?.message||"Failed to delete user.";c({title:"Error",description:s,variant:"destructive"})}}),z=f({mutationFn:async t=>{const s=await Promise.allSettled(t.map(w=>g("DELETE",`/api/users/${w}`))),k=s.filter(w=>w.status==="fulfilled").length,H=s.length-k;return{succeeded:k,failed:H}},onSuccess:({succeeded:t,failed:s})=>{j.invalidateQueries({queryKey:["/api/users"]}),c(s===0?{title:`${t} user${t!==1?"s":""} deleted`}:{title:`Deleted ${t} of ${t+s}`,description:`${s} user${s!==1?"s":""} could not be deleted.`,variant:"destructive"})},onError:t=>{j.invalidateQueries({queryKey:["/api/users"]});const s=t?.message||"Failed to delete users.";c({title:"Error",description:s,variant:"destructive"})}}),U=()=>{b(null),r.reset({email:"",name:"",bio:"",twitterUrl:"",linkedinUrl:"",password:"",roleId:C?.[0]?.id||1,status:"active"}),x(!0)},O=t=>{b(t),r.reset({email:t.email,name:t.name,bio:t.bio||"",twitterUrl:t.twitterUrl||"",linkedinUrl:t.linkedinUrl||"",password:"",roleId:t.roleId,status:t.status}),x(!0)},Q=t=>{switch(t.toLowerCase()){case"admin":return"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300";case"editor":return"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300";case"author":return"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300";default:return"bg-muted text-muted-foreground"}},B=[{id:"name",header:"User",sortable:!0,sortValue:t=>t.name?.toLowerCase(),cell:t=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs(ce,{className:"h-9 w-9",children:[e.jsx(ue,{src:t.avatarUrl||void 0}),e.jsx(me,{children:t.name.charAt(0)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:t.name}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t.email})]})]})},{id:"role",header:"Role",sortable:!0,sortValue:t=>t.role?.name?.toLowerCase(),cell:t=>e.jsx(T,{className:Q(t.role?.name||""),children:t.role?.name||"Unknown"})},{id:"articles",header:"Articles",sortable:!0,sortValue:t=>t.postCount,cell:t=>t.postCount>0?e.jsx(J,{href:`/admin/posts?author=${t.id}`,children:e.jsxs(d,{variant:"ghost",size:"sm",className:"h-auto px-2 py-1 gap-1","data-testid":`link-user-posts-${t.id}`,children:[e.jsx(ve,{className:"h-3 w-3"}),t.postCount]})}):e.jsx("span",{className:"text-muted-foreground",children:"0"})},{id:"status",header:"Status",sortable:!0,sortValue:t=>t.status,cell:t=>e.jsx(T,{variant:t.status==="active"?"default":"secondary",children:t.status})},{id:"joined",header:"Joined",sortable:!0,sortValue:t=>t.createdAt?new Date(t.createdAt).getTime():0,className:"text-muted-foreground",cell:t=>de(t.createdAt)}];return e.jsx(ee,{title:"Users",children:e.jsxs("div",{className:"p-6 space-y-6",children:[e.jsx(he,{title:"Users",description:"Manage user accounts and permissions.",actions:e.jsxs(se,{open:P,onOpenChange:x,children:[e.jsx(re,{asChild:!0,children:e.jsxs(d,{onClick:U,"data-testid":"button-new-user",children:[e.jsx($,{className:"h-4 w-4 mr-2"}),"New User"]})}),e.jsxs(ae,{children:[e.jsx(ie,{children:e.jsx(ne,{children:u?"Edit User":"New User"})}),e.jsx(X,{...r,children:e.jsxs("form",{onSubmit:r.handleSubmit(t=>v.mutate(t)),className:"space-y-4",children:[e.jsx(a,{control:r.control,name:"name",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:"Name"}),e.jsx(o,{children:e.jsx(h,{placeholder:"Full name",...t,"data-testid":"input-user-name"})}),e.jsx(l,{})]})}),e.jsx(a,{control:r.control,name:"email",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:"Email"}),e.jsx(o,{children:e.jsx(h,{type:"email",placeholder:"[email protected]",...t,"data-testid":"input-user-email"})}),e.jsx(l,{})]})}),e.jsx(a,{control:r.control,name:"bio",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:"Bio / Description"}),e.jsx(o,{children:e.jsx(xe,{placeholder:"Short bio or description about this user...",className:"resize-none",rows:3,...t,"data-testid":"input-user-bio"})}),e.jsx(l,{})]})}),e.jsx(a,{control:r.control,name:"twitterUrl",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:"X (Twitter) Profile URL"}),e.jsx(o,{children:e.jsx(h,{placeholder:"https://x.com/username",...t,"data-testid":"input-user-twitter"})}),e.jsx(l,{})]})}),e.jsx(a,{control:r.control,name:"linkedinUrl",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:"LinkedIn Profile URL"}),e.jsx(o,{children:e.jsx(h,{placeholder:"https://linkedin.com/in/username",...t,"data-testid":"input-user-linkedin"})}),e.jsx(l,{})]})}),e.jsx(a,{control:r.control,name:"password",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:u?"New Password (leave blank to keep current)":"Password"}),e.jsx(o,{children:e.jsx(h,{type:"password",placeholder:"Password",...t,"data-testid":"input-user-password"})}),e.jsx(l,{})]})}),e.jsx(a,{control:r.control,name:"roleId",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:"Role"}),e.jsxs(D,{onValueChange:s=>t.onChange(parseInt(s)),value:String(t.value),children:[e.jsx(o,{children:e.jsx(E,{"data-testid":"select-user-role",children:e.jsx(F,{})})}),e.jsx(A,{children:C?.map(s=>e.jsx(y,{value:String(s.id),children:s.name},s.id))})]}),e.jsx(l,{})]})}),e.jsx(a,{control:r.control,name:"status",render:({field:t})=>e.jsxs(i,{children:[e.jsx(n,{children:"Status"}),e.jsxs(D,{onValueChange:t.onChange,value:t.value,children:[e.jsx(o,{children:e.jsx(E,{"data-testid":"select-user-status",children:e.jsx(F,{})})}),e.jsxs(A,{children:[e.jsx(y,{value:"active",children:"Active"}),e.jsx(y,{value:"inactive",children:"Inactive"})]})]}),e.jsx(l,{})]})}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(d,{type:"button",variant:"outline",onClick:()=>x(!1),children:"Cancel"}),e.jsxs(d,{type:"submit",disabled:v.isPending,"data-testid":"button-save-user",children:[v.isPending&&e.jsx(ge,{className:"h-4 w-4 mr-2 animate-spin"}),u?"Update":"Create"]})]})]})})]})]})}),e.jsx(oe,{children:e.jsx(le,{className:"p-4",children:e.jsx(je,{columns:B,data:q,getRowId:t=>t.id,getRowTestId:t=>`row-user-${t.id}`,isLoading:R,isError:V,onRetry:()=>K(),errorMessage:"Something went wrong while loading users.",selectable:!0,pageSize:10,bulkActions:(t,s)=>e.jsx(I,{title:"Delete selected users",description:`Are you sure you want to delete ${t.length} user${t.length!==1?"s":""}? This action cannot be undone and their articles will become unassigned.`,confirmText:"Delete",destructive:!0,onConfirm:()=>{z.mutate(t),s()},trigger:e.jsxs(d,{variant:"destructive",size:"sm","data-testid":"button-bulk-delete-users",children:[e.jsx(L,{className:"h-4 w-4 mr-2"}),"Delete"]})}),rowActions:t=>e.jsxs(e.Fragment,{children:[e.jsx(d,{variant:"ghost",size:"sm",onClick:()=>O(t),"data-testid":`button-edit-user-${t.id}`,children:"Edit"}),e.jsx(I,{title:"Delete User",description:e.jsxs(e.Fragment,{children:["Are you sure you want to delete ",t.name,"? This action cannot be undone.",t.postCount>0&&e.jsxs("span",{className:"block mt-2 text-yellow-600 dark:text-yellow-500",children:["Warning: This user has ",t.postCount," article",t.postCount!==1?"s":""," that will become unassigned."]})]}),confirmText:"Delete",destructive:!0,onConfirm:()=>M.mutate(t.id),trigger:e.jsx(d,{variant:"ghost",size:"icon",className:"h-8 w-8 text-destructive hover:text-destructive","data-testid":`button-delete-user-${t.id}`,children:e.jsx(L,{className:"h-4 w-4"})})})]}),emptyState:e.jsx(pe,{icon:be,title:"No users yet",description:"Create user accounts to manage content.",action:e.jsxs(d,{onClick:U,"data-testid":"button-create-first-user",children:[e.jsx($,{className:"h-4 w-4 mr-2"}),"Create User"]})})})})})]})})}export{qe 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.