PageSourceSearch

https://www.salga.org.za/_nuxt/C8hkrb3M.js

js salga.org.za collected 2026-10-02 11:29:18 UTC 10,428 bytes, 1 lines download raw bytes

1import{I as R,k as f,g as q,c as n,a as s,t as m,q as S,x as O,l as x,J as L,F as U,r as E,i as V,o as l,j as B,d as P,y as z}from"./RiE-zTCK.js";import{u as H}from"./CJ9_H1Pq.js";function J(){const i=R().public.apiBase,T=f([]),F=f([]),$=f(null),{success:b,error:p}=H(),d=()=>{const e=localStorage.getItem("access_token");return e?{Authorization:`Bearer ${e}`}:{}},_=async()=>{try{const e=await fetch(`${i}/users/users/`,{headers:d()});if(!e.ok)throw new Error("Failed to fetch users");const o=await e.json();return T.value=o,o}catch(e){return p("Failed to fetch users"),console.error("Fetch Users Error:",e),[]}},h=async()=>{try{const e=await fetch(`${i}/users/groups/`,{headers:d()});if(!e.ok)throw new Error("Failed to fetch groups");const o=await e.json();return F.value=o,console.log("Fetched groups:",o),o}catch(e){return p("Failed to fetch groups"),console.error("Fetch Groups Error:",e),[]}},w=async e=>{try{const o=e.id?"PUT":"POST",y=e.id?`${i}/users/users/${e.id}/`:`${i}/users/users/`,v={username:e.username,email:e.email,...e.password?{password:e.password}:{}},g=await fetch(y,{method:o,headers:{"Content-Type":"application/json",...d()},body:JSON.stringify(v)});if(!g.ok)throw new Error("Failed to save user");const C=await g.json();return e.groups&&e.groups.length&&await A(C.id,e.groups),b(`User ${o==="POST"?"created":"updated"} successfully!`),C}catch(o){p("Failed to save user"),console.error("Save User Error:",o)}},c=async(e,o)=>{const y=e.groups.map(g=>g.id),v=y.includes(o.id)?y.filter(g=>g!==o.id):[...y,o.id];try{await fetch(`${i}/users/users/${e.id}/set_groups/`,{method:"POST",headers:{"Content-Type":"application/json",...d()},body:JSON.stringify({groups:v})}),e.groups=F.value.filter(g=>v.includes(g.id))}catch(g){console.error("Failed to update user groups:",g)}},j=async e=>{try{if(!(await fetch(`${i}/users/users/${e}/`,{method:"DELETE",headers:d()})).ok)throw new Error("Failed to delete user");b("User deleted successfully")}catch(o){p("Failed to delete user"),console.error("Delete User Error:",o)}},k=async e=>{try{const o=await fetch(`${i}/users/${e}/`,{headers:d()});if(!o.ok)throw new Error("Failed to fetch user");$.value=await o.json()}catch(o){p("Failed to fetch user"),console.error("Fetch User Error:",o)}},A=async(e,o)=>{try{const y=await fetch(`${i}/users/users/${e}/set_groups/`,{method:"POST",headers:{"Content-Type":"application/json",...d()},body:JSON.stringify({groups:o})});if(!y.ok)throw new Error("Failed to update groups");const v=await y.json();b("User groups updated successfully!"),$.value=v}catch(y){p("Failed to update user groups"),console.error("Update Groups Error:",y)}};return{users:T,selectedUser:$,groups:F,fetchGroups:h,saveUser:w,deleteUser:j,fetchUserById:k,fetchUsers:_,fetchUserById:k,updateUserGroups:A,saveGroup:async e=>{try{const o=e.id?"PUT":"POST",y=e.id?`${i}/users/groups/${e.id}/`:`${i}/users/groups/`,v=await fetch(y,{method:o,headers:{"Content-Type":"application/json",...d()},body:JSON.stringify(e)});if(!v.ok)throw new Error("Failed to save group");const g=await v.json();return b(`Group ${o==="POST"?"created":"updated"} successfully`),g}catch(o){p("Failed to save group"),console.error("Save Group Error:",o)}},deleteGroup:async e=>{try{if(!(await fetch(`${i}/users/groups/${e}/`,{method:"DELETE",headers:d()})).ok)throw new Error("Failed to delete group");b("Group deleted successfully")}catch(o){p("Failed to delete group"),console.error("Delete Group Error:",o)}},toggleUserGroup:c}}const K={class:"p-8 font-foco space-y-10 max-w-6xl mx-auto"},Q={class:"flex justify-between items-center"},W={key:0,class:"bg-white rounded-xl shadow-md border border-gray-200 p-6 space-y-6"},X={class:"text-xl font-semibold text-gray-800"},Y=["value"],Z={key:1,class:"space-y-6"},D=["onClick"],ee={class:"text-lg font-semibold text-gray-900"},se={class:"text-sm text-gray-500"},te={class:"flex flex-wrap gap-2 mt-1"},oe={class:"text-xl text-gray-400"},re={key:0,class:"px-6 py-4 border-t space-y-6 text-gray-700"},ae={class:"flex gap-4 border-b pb-2"},ne=["onClick"],le={key:0,class:"space-y-3"},de={class:"flex gap-3 mt-4"},ie=["onClick"],ue=["onClick"],ce={key:1,class:"space-y-4"},pe={class:"text-gray-800 font-medium"},ye=["onClick"],ge={key:0,class:"text-sm text-gray-500 italic"},me={key:2,class:"text-center text-gray-500 py-10"},ve={class:"bg-white rounded-2xl shadow-lg border border-gray-100 p-6 space-y-6"},fe={class:"space-y-3"},he={class:"text-gray-800 font-medium"},xe=["onClick"],ke={__name:"users",setup(M){const i=f({name:""}),{saveGroup:T,deleteGroup:F}
1=J(),$=async()=>{i.value.name.trim()&&(await T({name:i.value.name}),i.value.name="",d.value=await k())},b=async a=>{confirm("Are you sure you want to delete this group?")&&(await F(a),d.value=await k())},p=f([]),d=f([]),_=f(!1),h=f([]),w=f({}),c=f({id:null,username:"",email:"",password:"",groups:[]}),{fetchUsers:j,fetchGroups:k,saveUser:A,deleteUser:N,toggleUserGroup:I}=J(),e=a=>{h.value.includes(a)?h.value=h.value.filter(r=>r!==a):(h.value.push(a),w.value[a]="Info")},o=()=>{c.value={id:null,username:"",email:"",password:"",groups:[]},_.value=!1},y=a=>{c.value={id:a.id,username:a.username,email:a.email,password:"",groups:a.groups.map(r=>r.id)},_.value=!0},v=async()=>{await A(c.value),await C(),o()},g=async a=>{confirm("Are you sure you want to delete this user?")&&(await N(a),await C())},C=async()=>{p.value=await j(),d.value=await k()};return q(async()=>{j().then(a=>{p.value=a,console.log("Fetched users:",a)}),k().then(a=>{d.value=a,console.log("Fetched groups:",a)})}),(a,r)=>(l(),n("div",K,[s("div",Q,[r[6]||(r[6]=s("h1",{class:"text-3xl font-bold text-gray-900"},"Manage Users",-1)),s("button",{onClick:r[0]||(r[0]=t=>_.value=!0),class:"bg-primary hover:bg-primary-dark text-white font-semibold py-2 px-5 rounded-lg shadow-md transition"}," + Add User ")]),_.value?(l(),n("section",W,[s("h2",X,m(c.value.id?"Edit User":"Add User"),1),s("form",{onSubmit:V(v,["prevent"]),class:"space-y-6"},[S(s("input",{"onUpdate:modelValue":r[1]||(r[1]=t=>c.value.username=t),type:"text",placeholder:"Username",class:"w-full rounded-lg border border-gray-300 px-4 py-3",required:""},null,512),[[O,c.value.username]]),S(s("input",{"onUpdate:modelValue":r[2]||(r[2]=t=>c.value.email=t),type:"email",placeholder:"Email",class:"w-full rounded-lg border border-gray-300 px-4 py-3",required:""},null,512),[[O,c.value.email]]),c.value.id?x("",!0):S((l(),n("input",{key:0,"onUpdate:modelValue":r[3]||(r[3]=t=>c.value.password=t),type:"password",placeholder:"Password",class:"w-full rounded-lg border border-gray-300 px-4 py-3",required:""},null,512)),[[O,c.value.password]]),r[8]||(r[8]=s("label",{class:"block font-semibold"},"Roles (Groups):",-1)),S(s("select",{"onUpdate:modelValue":r[4]||(r[4]=t=>c.value.groups=t),multiple:"",class:"w-full border border-gray-300 rounded-lg px-4 py-3"},[(l(!0),n(U,null,E(d.value,t=>(l(),n("option",{key:t.id,value:t.id},m(t.name),9,Y))),128))],512),[[L,c.value.groups]]),s("div",{class:"flex justify-end gap-4"},[r[7]||(r[7]=s("button",{type:"submit",class:"bg-primary hover:bg-primary-dark text-white font-semibold py-2 px-6 rounded-lg shadow-md"}," Save ",-1)),s("button",{onClick:o,type:"button",class:"text-red-600 font-semibold py-2 px-6 rounded hover:bg-red-100 transition"}," Cancel ")])],32)])):x("",!0),p.value.length?(l(),n("section",Z,[(l(!0),n(U,null,E(p.value,t=>(l(),n("div",{key:t.id,class:"bg-white border border-gray-200 rounded-xl shadow-md"},[s("div",{onClick:u=>e(t.id),class:"flex justify-between items-center px-6 py-4 cursor-pointer hover:bg-gray-50 transition"},[s("div",null,[s("h3",ee,m(t.username),1),s("p",se,m(t.email),1),s("div",te,[(l(!0),n(U,null,E(t.groups,u=>(l(),n("span",{key:u.id,class:"text-xs inline-flex items-center px-2 py-0.5 rounded-full bg-blue-100 text-blue-800 font-medium"},m(u.name),1))),128))])]),s("span",oe,m(h.value.includes(t.id)?"▲":"▼"),1)],8,D),h.value.includes(t.id)?(l(),n("div",re,[s("div",ae,[(l(),n(U,null,E(["Info","Roles"],u=>s("button",{key:u,onClick:G=>w.value[t.id]=u,class:B(["px-4 py-1.5 text-sm font-semibold rounded-md",w.value[t.id]===u?"bg-primary text-white":"text-gray-600 hover:bg-gray-100"])},m(u),11,ne)),64))]),w.value[t.id]==="Info"?(l(),n("div",le,[s("p",null,[r[9]||(r[9]=s("strong",null,"Username:",-1)),P(" "+m(t.username),1)]),s("p",null,[r[10]||(r[10]=s("strong",null,"Email:",-1)),P(" "+m(t.email),1)]),s("p",null,[r[11]||(r[11]=s("strong",null,"Joined:",-1)),P(" "+m(new Date(t.date_joined).toLocaleDateString()),1)]),s("div",de,[s("button",{onClick:u=>y(t),class:"text-yellow-600 border border-yellow-400 px-4 py-2 rounded hover:bg-yellow-50"}," Edit ",8,ie),s("button",{onClick:u=>g(t.id),class:"text-red-600 border border-red-400 px-4 py-2 rounded hover:bg-red-50"}," Delete ",8,ue)])])):x("",!0),w.value[t.id]==="Roles"?(l(),n("div",ce,[(l(!0),n(U,null,E(d.value,u=>(l(),n("div",{key:u.id,class:"flex items-center justify-between border rounded-lg px-4 py-2"}
1,[s("div",pe,m(u.name),1),s("button",{onClick:G=>z(I)(t,u),class:B(["text-sm px-3 py-1 rounded-md font-semibold transition",t.groups.some(G=>G.id===u.id)?"bg-red-100 text-red-700 hover:bg-red-200":"bg-green-100 text-green-700 hover:bg-green-200"])},m(t.groups.some(G=>G.id===u.id)?"Remove":"Add"),11,ye)]))),128)),d.value.length?x("",!0):(l(),n("p",ge," No groups available "))])):x("",!0)])):x("",!0)]))),128))])):x("",!0),p.value.length===0?(l(),n("div",me," No users found. ")):x("",!0),s("section",ve,[r[13]||(r[13]=s("h2",{class:"text-2xl font-semibold text-gray-900 tracking-tight"},"Manage Groups",-1)),s("form",{onSubmit:V($,["prevent"]),class:"flex flex-col sm:flex-row gap-4"},[S(s("input",{"onUpdate:modelValue":r[5]||(r[5]=t=>i.value.name=t),type:"text",placeholder:"Enter new group name",class:"flex-1 border border-gray-300 focus:ring-2 focus:ring-primary-light focus:outline-none rounded-lg px-4 py-2 text-gray-800 placeholder-gray-400"},null,512),[[O,i.value.name]]),r[12]||(r[12]=s("button",{type:"submit",class:"bg-primary hover:bg-primary-dark text-white font-semibold px-5 py-2.5 rounded-lg transition-colors"}," Save ",-1))],32),s("div",fe,[(l(!0),n(U,null,E(d.value,t=>(l(),n("div",{key:t.id,class:"flex justify-between items-center px-4 py-3 bg-gray-50 hover:bg-gray-100 rounded-lg transition"},[s("span",he,m(t.name),1),s("button",{onClick:u=>b(t.id),class:"text-red-500 hover:text-red-600 text-sm font-semibold"}," Delete ",8,xe)]))),128))])])]))}};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.