1import{q as ke,b3 as Ae,r as y,z as Se,b5 as c,b6 as r,b7 as s,b9 as l,b8 as a,bd as u,a6 as f,bx as G,bw as F,bG as xe,ac as E,bc as d,bN as he,A as w,bb as _,ba as C,bI as Te,aL as j,bA as ae,bM as Ue,b1 as Qe,bO as qe,aZ as Be,a_ as Ne,N as g,J as P,e as B,f as k,aN as $,C as Z,B as H,D as K,F as W,Q as I}from"./index-ZTZX6O4r.js";import{Q as R}from"./QSelect-LJn4rxVI.js";import{Q as b}from"./QTd-CfsMlHO6.js";import{Q as v}from"./QBadge-iDo7tbmS.js";import{Q as X}from"./QTooltip-BNRCDlL_.js";import{Q as h,a as p}from"./QItem-Cmm75ClS.js";import{Q as Le}from"./QItemLabel-DJJTFmpY.js";import{Q as De}from"./QList-DnIjH5wq.js";import{Q as Ve}from"./QMenu-DeogY-KU.js";import{Q as Fe}from"./QTable-CBiO25T1.js";import{Q as Ee}from"./QBanner-CePDC9UD.js";import{Q as Pe}from"./QPage-OM5JgPVG.js";import{C as A}from"./ClosePopup-7_Yx9rfi.js";import{f as $e}from"./formatDistanceToNow-DTeh1iPw.js";import{_ as Ie}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./QChip-QkbYP07w.js";import"./format-DyQxkAtJ.js";import"./position-engine-BaRtYBUc.js";import"./selection-DUEPnI6d.js";import"./QMarkupTable-CiCrTXHQ.js";import"./QLinearProgress-UY9rcHYn.js";import"./normalizeDates-CacZHBiA.js";import"./en-US-3LvP7pCn.js";const Re={class:"q-pa-md"},Me={class:"page-header q-mb-lg"},ze={class:"text-h4 q-mt-none q-mb-sm"},Oe={class:"row q-col-gutter-md"},Je={class:"col-12 col-md-4"},Ge={class:"col-12 col-sm-6 col-md-2"},je={class:"col-12 col-sm-6 col-md-2"},Ze={class:"col-12 col-sm-6 col-md-2"},He={class:"col-12 col-md-2"},Ke={class:"col-12 col-md-auto"},We={class:"text-h6 q-mb-md"},Xe={class:"row items-center no-wrap"},Ye={class:"text-weight-medium"},et={class:"text-caption te-text-secondary"},tt={class:"row items-center q-gutter-xs"},ot={key:1,class:"text-grey-6"},at={key:2,class:"text-grey-6"},st={key:0,class:"text-weight-medium"},lt={key:0,class:"text-caption te-text-secondary"},it={key:1,class:"text-grey-6"},rt={key:1,class:"q-ml-md"},nt={class:"text-body2"},ct={class:"text-body2"},ut={class:"text-body1"},dt=ke({__name:"UserManagementPage",setup(mt){const Y=Ae(),M=y(!1),N=y(""),L=y("All"),U=y("All"),S=y("All"),T=y("All Time"),se=["All","Active","Inactive"],le=["All","Admin","Trader","Mentor","Mentee"],ie=["All","Early Adopter","Premium","Pro","Pro (Trial)","Core","Free"],re=["All Time","Last 7 days","Last 30 days","Last 90 days"],Q=y([]),z=y([]),D=y(!1),q=y(null),O=y(!1),ne=y({rowsPerPage:25}),ce=[{name:"displayName",label:"User",field:"displayName",align:"left",sortable:!0},{name:"role",label:"Role",field:"role",align:"left",sortable:!0},{name:"subscription",label:"Subscription",field:"subscription",align:"left",sortable:!0},{name:"status",label:"Status",field:"isActive",align:"left",sortable:!0},{name:"createdAt",label:"Joined",field:"createdAt",align:"left",sortable:!0,sort:(o,e)=>o.getTime()-e.getTime()},{name:"source",label:"Source",field:o=>o.referredBy?`ref:${o.referredBy}`:o.acquisitionSource?.utmSource??"",align:"left",sortable:!0},{name:"discord",label:"Discord",field:"discordDisplayName",align:"left",sortable:!0},{name:"lastLoginAt",label:"Last Active",field:"lastLoginAt",align:"left",sortable:!0,sort:(o,e)=>o.getTime()-e.getTime()},{name:"actions",label:"Actions",field:"actions",align:"center"}],ue=o=>{const e=o.split(" ").filter(t=>t.length>0);return e.length>=2&&e[0]&&e[1]?`${e[0][0]}${e[1][0]}`.toUpperCase():o.substring(0,2).toUpperCase()},ee=o=>$e(o,{addSuffix:!0}),te=async()=>{M.value=!0;try{const e=await Be(Ne,"listAllUsers")({});if(!e.data.success)throw new Error("Failed to load users");const t=new Date(Date.now()-720*60*60*1e3),m=e.data.users.map(i=>{const J=new Date(i.createdAt.seconds*1e3),V=i.lastLoginAt?new Date(i.lastLoginAt.seconds*1e3):new Date(0),n={uid:i.uid,email:i.email,displayName:i.displayName,role:i.role,isAdmin:i.isAdmin,isActive:V>=t,subscription:i.subscription,subscriptionStatus:i.subscriptionStatus??null,createdAt:J,lastLoginAt:V};return i.brokerConnectionsCount!==void 0&&(n.brokerConnectionsCount=i.brokerConnectionsCount),i.hasRealtimeCapture!==void 0&&(n.hasRealtimeCapture=i.hasRealtimeCapture),i.features&&(n.features=i.features),i.permissions&&(n.permissions=i.permissions),i.discordUsername&&(n.discordUsername=i.discordUsername),i.discordDisplayName&&(n.discordDisplayName=i.discordDisplayName),i.acquisitionSource&&(n.acquisitionSource=i.acquisitionSource),i.referredBy&&(n.referredBy=i.referredBy),n});Q.value=m,x()}catch(o){console.error("Error loading users:",o),g.create({type:"negative",message:"Failed to load users",position:"top"})}finally{M.value=!1}},x=()=>{let o=[...Q.value];if(N.value){const e=N.value.toLowerCase();o=o.filter(t=>t.displayName.toLowerCase().includes(e)||t.email.toLowerCase().includes(e)||t.uid.toLowerCase().includes(e))}if(L.value!=="All"){const e=L.value==="Active";o=o.filter(t=>t.isActive===e)}if(U.value!=="All")if(U.value==="Admin")o=o.filter(e=>e.isAdmin);else{const e=U.value.toLowerCase();o=o.filter(t=>t.role===e)}if(S.value!=="All")if(S.value==="Free")o=o.filter(e=>!e.subscription);else if(S.value==="Early Adopter")o=o.filter(e=>e.subscription==="early_adopter");else if(S.value==="Pro (Trial)")o=o.filter(e=>e.subscription==="pro"&&e.subscriptionStatus==="trialing");else{const e=S.value.toLowerCase();o=o.filter(t=>t.subscription===e)}if(T.value!=="All Time"){const e=new Date;let t=0;T.value==="Last 7 days"?t=7:T.value==="Last 30 days"?t=30:T.value==="Last 90 days"&&(t=90);const m=new Date(e.getTime()-t*24*60*60*1e3);o=o.filter(i=>i.createdAt>=m)}z.value=o},oe=o=>{Y.push(`/admin/users/${o}`)},de=(o,e)=>{e.stopPropagation()},me=async o=>{try{const e=!o.isActive;await P(B(k,"users",o.uid),{isActive:e}),o.isActive=e,g.create({type:"positive",message:`User ${e?"reactivated":"suspended"} successfully`,position:"top"})}catch(e){console.error("Error updating user status:",e),g.create({type:"negative",message:"Failed to update user status",position:"top"})}},fe=async o=>{try{const e=!(o.features?.copyTrading??!1),t={"features.copyTrading":e,updatedAt:$.now()};e&&!o.features?.copyTrading&&(t.copyTradingEnabledAt=$.now()),await P(B(k,"users",o.uid),t),o.features??={},o.features.copyTrading=e,g.create({type:"positive",message:`Copy Trading ${e?"enabled":"disabled"} for ${o.displayName}`,position:"top"})}catch(e){console.error("Error toggling copy trading:",e),g.create({type:"negative",message:"Failed to update copy trading permission",position:"top"})}},pe=async o=>{try{const e=!(o.features?.canBeCopySource??!1);await P(B(k,"users",o.uid),{"features.canBeCopySource":e,updatedAt:$.now()}),o.features??={},o.features.canBeCopySource=e,g.create({type:"positive",message:`Copy Source (Mentor) ${e?"enabled":"disabled"} for ${o.displayName}`,position:"top"})}catch(e){console.error("Error toggling copy source:",e),g.create({type:"negative",message:"Failed to update copy source permission",position:"top"})}},ye=async o=>{try{const e=!(o.features?.canBeCopyDestination??!1);await P(B(k,"users",o.uid),{"features.canBeCopyDestination":e,updatedAt:$.now()}),o.features??={},o.features.canBeCopyDestination=e,g.create({type:"positive",message:`Copy Destination (Student) ${e?"enabled":"disabled"} for ${o.displayName}`,position:"top"})}catch(e){console.error("Error toggling copy destination:",e),g.create({type:"negative",message:"Failed to update copy destination permission",position:"top"})}},ge=o=>{q.value=o,D.value=!0},be=async()=>
1{if(q.value){O.value=!0;try{const o=q.value.uid,e=Z(H(k,"trades"),K("userId","==",o)),t=await W(e);await Promise.all(t.docs.map(n=>I(n.ref)));const m=Z(H(k,"plans"),K("userId","==",o)),i=await W(m);await Promise.all(i.docs.map(n=>I(n.ref)));const J=Z(H(k,"accounts"),K("userId","==",o)),V=await W(J);await Promise.all(V.docs.map(n=>I(n.ref))),await I(B(k,"users",o)),Q.value=Q.value.filter(n=>n.uid!==o),x(),g.create({type:"positive",message:"User deleted successfully",position:"top"}),D.value=!1,q.value=null}catch(o){console.error("Error deleting user:",o),g.create({type:"negative",message:"Failed to delete user",position:"top"})}finally{O.value=!1}}},ve=o=>{const e=o.toLowerCase();return e==="instagram"?"pink-5":e==="reddit"?"deep-orange":e==="youtube"?"red":e==="x"||e==="twitter"?"grey-4":e==="discord"?"indigo-4":e==="google"?"blue":e==="facebook"?"blue-7":e==="tiktok"?"cyan":e==="linkedin"?"blue-8":"grey-6"},we=o=>{const e=o.toLowerCase();return e==="instagram"?"photo_camera":e==="reddit"?"forum":e==="youtube"?"smart_display":e==="x"||e==="twitter"?"tag":e==="discord"?"headset_mic":e==="google"?"search":e==="facebook"?"people":e==="tiktok"?"music_note":e==="linkedin"?"work":"language"},_e=o=>{switch(o){case"early_adopter":return"purple";case"premium":return"secondary";case"pro":return"primary";case"core":return"positive";default:return"grey-6"}},Ce=o=>{switch(o){case"early_adopter":return"Early Adopter";case"premium":return"Premium";case"pro":return"Pro";case"core":return"Core";default:return"Free"}};return Se(()=>{te()}),(o,e)=>(r(),c(Pe,{class:"user-management-page"},{default:s(()=>[l("div",Re,[l("div",Me,[l("h4",ze,[a(f,{name:"people",color:"primary",size:"md",class:"q-mr-sm"}),e[7]||(e[7]=u(" User Management ",-1))]),e[8]||(e[8]=l("p",{class:"text-subtitle1 te-text-secondary"},"Search, filter, and manage user accounts",-1))]),a(G,{class:"te-card q-mb-md"},{default:s(()=>[a(F,null,{default:s(()=>[l("div",Oe,[l("div",Je,[a(xe,{modelValue:N.value,"onUpdate:modelValue":[e[0]||(e[0]=t=>N.value=t),x],placeholder:"Search by name, email, or ID...",outlined:"",dense:"",clearable:""},{prepend:s(()=>[a(f,{name:"search"})]),_:1},8,["modelValue"])]),l("div",Ge,[a(R,{modelValue:L.value,"onUpdate:modelValue":[e[1]||(e[1]=t=>L.value=t),x],options:se,label:"Status",outlined:"",dense:""},null,8,["modelValue"])]),l("div",je,[a(R,{modelValue:U.value,"onUpdate:modelValue":[e[2]||(e[2]=t=>U.value=t),x],options:le,label:"Role",outlined:"",dense:""},null,8,["modelValue"])]),l("div",Ze,[a(R,{modelValue:S.value,"onUpdate:modelValue":[e[3]||(e[3]=t=>S.value=t),x],options:ie,label:"Subscription",outlined:"",dense:""},null,8,["modelValue"])]),l("div",He,[a(R,{modelValue:T.value,"onUpdate:modelValue":[e[4]||(e[4]=t=>T.value=t),x],options:re,label:"Joined",outlined:"",dense:""},null,8,["modelValue"])]),l("div",Ke,[a(E,{outline:"",color:"primary",label:"Refresh",icon:"refresh",onClick:te,loading:M.value,class:"full-width"},null,8,["loading"])])])]),_:1})]),_:1}),a(G,{class:"te-card"},{default:s(()=>[a(F,null,{default:s(()=>[l("div",We," Users ("+d(z.value.length)+" of "+d(Q.value.length)+") ",1),a(Fe,{rows:z.value,columns:ce,"row-key":"uid","rows-per-page-options":[10,25,50,100],pagination:ne.value,flat:"",onRowClick:e[5]||(e[5]=(t,m)=>oe(m.uid)),class:"cursor-pointer"},{"body-cell-displayName":s(t=>[a(b,{props:t},{default:s(()=>[l("div",Xe,[a(Ue,{size:"32px",color:"primary","text-color":"white",class:"q-mr-sm"},{default:s(()=>[u(d(ue(t.row.displayName)),1)]),_:2},1024),l("div",null,[l("div",Ye,d(t.row.displayName),1),l("div",et,d(t.row.email),1)])])]),_:2},1032,["props"])]),"body-cell-role":s(t=>[a(b,{props:t},{default:s(()=>[l("div",tt,[t.row.isAdmin?(r(),c(v,{key:0,color:"orange",label:"Admin"})):(r(),c(v,{key:1,color:"grey-6",label:t.row.role},null,8,["label"])),t.row.hasRealtimeCapture?(r(),c(f,{key:2,name:"wifi",color:"positive",size:"xs"},{default:s(()=>[a(X,null,{default:s(()=>[...e[9]||(e[9]=[u("Real-Time Trade Capture Enabled",-1)])]),_:1})]),_:1})):_("",!0),t.row.features?.copyTrading?(r(),c(f,{key:3,name:"content_copy",color:"accent",size:"xs"},{default:s(()=>[a(X,null,{default:s(()=>[...e[10]||(e[10]=[u("Copy Trading Enabled",-1)])]),_:1})]),_:1})):_("",!0)])]),_:2},1032,["props"])]),"body-cell-status":s(t=>[a(b,{props:t},{default:s(()=>[a(v,{color:t.row.isActive?"positive":"grey-6",label:t.row.isActive?"Active":"Inactive"},null,8,["color","label"])]),_:2},1032,["props"])]),"body-cell-subscription":s(t=>[a(b,{props:t},{default:s(()=>[t.row.subscription&&t.row.subscription!=="free"?(r(),C(ae,{key:0},[a(v,{color:_e(t.row.subscription),label:Ce(t.row.subscription)},null,8,["color","label"]),t.row.subscriptionStatus==="trialing"?(r(),c(v,{key:0,color:"orange",label:"Trial",class:"q-ml-xs"})):t.row.subscriptionStatus==="canceled"||t.row.subscriptionStatus==="past_due"?(r(),c(v,{key:1,color:t.row.subscriptionStatus==="past_due"?"warning":"negative",label:t.row.subscriptionStatus==="past_due"?"Past Due":"Canceled",class:"q-ml-xs"},null,8,["color","label"])):_("",!0)],64)):(r(),C("span",ot,"Free"))]),_:2},1032,["props"])]),"body-cell-source":s(t=>[a(b,{props:t},{default:s(()=>[t.row.referredBy?(r(),c(v,{key:0,color:"purple",outline:""},{default:s(()=>[a(f,{name:"share",size:"12px",class:"q-mr-xs"}),u(" "+d(t.row.referredBy),1)]),_:2},1024)):t.row.acquisitionSource?.utmSource?(r(),C(ae,{key:1},[a(v,{color:ve(t.row.acquisitionSource.utmSource),outline:""},{default:s(()=>[a(f,{name:we(t.row.acquisitionSource.utmSource),size:"12px",class:"q-mr-xs"},null,8,["name"]),u(" "+d(t.row.acquisitionSource.utmSource),1)]),_:2},1032,["color"]),t.row.acquisitionSource.utmCampaign?(r(),c(X,{key:0},{default:s(()=>[u(" Campaign: "+d(t.row.acquisitionSource.utmCampaign),1)]),_:2},1024)):_("",!0)],64)):(r(),C("span",at,"â"))]),_:2},1032,["props"])]),"body-cell-discord":s(t=>[a(b,{props:t},{default:s(()=>[t.row.discordDisplayName?(r(),C("span",st,[u(d(t.row.discordDisplayName)+" ",1),t.row.discordUsername&&t.row.discordUsername!==t.row.discordDisplayName?(r(),C("span",lt," @"+d(t.row.discordUsername),1)):_("",!0)])):(r(),
1C("span",it,"â"))]),_:2},1032,["props"])]),"body-cell-createdAt":s(t=>[a(b,{props:t},{default:s(()=>[u(d(ee(t.row.createdAt)),1)]),_:2},1032,["props"])]),"body-cell-lastLoginAt":s(t=>[a(b,{props:t},{default:s(()=>[u(d(ee(t.row.lastLoginAt)),1)]),_:2},1032,["props"])]),"body-cell-actions":s(t=>[a(b,{props:t},{default:s(()=>[a(E,{flat:"",dense:"",round:"",icon:"more_vert",onClick:he(m=>de(t.row,m),["stop"])},{default:s(()=>[a(Ve,null,{default:s(()=>[a(De,{dense:""},{default:s(()=>[w((r(),c(h,{clickable:"",onClick:m=>oe(t.row.uid)},{default:s(()=>[a(p,{avatar:""},{default:s(()=>[a(f,{name:"visibility",color:"primary"})]),_:1}),a(p,null,{default:s(()=>[...e[11]||(e[11]=[u("View Details",-1)])]),_:1})]),_:1},8,["onClick"])),[[A]]),t.row.brokerConnectionsCount&&t.row.brokerConnectionsCount>0?w((r(),c(h,{key:0,clickable:"",onClick:()=>void Te(Y).push({path:"/admin/broker-connections",query:{userId:t.row.uid}})},{default:s(()=>[a(p,{avatar:""},{default:s(()=>[a(f,{name:"wifi",color:"accent"})]),_:1}),a(p,null,{default:s(()=>[e[12]||(e[12]=u(" Manage Broker Connections ",-1)),t.row.hasRealtimeCapture?(r(),c(v,{key:0,color:"positive",label:"Active",class:"q-ml-xs"})):_("",!0)]),_:2},1024)]),_:2},1032,["onClick"])),[[A]]):_("",!0),a(j),a(Le,{header:""},{default:s(()=>[...e[13]||(e[13]=[u("Copy Trading Features",-1)])]),_:1}),w((r(),c(h,{clickable:"",onClick:m=>fe(t.row)},{default:s(()=>[a(p,{avatar:""},{default:s(()=>[a(f,{name:t.row.features?.copyTrading?"check_circle":"radio_button_unchecked",color:t.row.features?.copyTrading?"positive":"grey"},null,8,["name","color"])]),_:2},1024),a(p,null,{default:s(()=>[l("div",null,d(t.row.features?.copyTrading?"Disable":"Enable")+" Copy Trading ",1),e[14]||(e[14]=l("div",{class:"text-caption text-grey"}," Grant access to copy trading features ",-1))]),_:2},1024)]),_:2},1032,["onClick"])),[[A]]),t.row.features?.copyTrading?(r(),C("div",rt,[w((r(),c(h,{clickable:"",onClick:m=>pe(t.row)},{default:s(()=>[a(p,{avatar:""},{default:s(()=>[a(f,{name:t.row.features?.canBeCopySource?"check_circle":"radio_button_unchecked",color:t.row.features?.canBeCopySource?"positive":"grey",size:"sm"},null,8,["name","color"])]),_:2},1024),a(p,null,{default:s(()=>[l("div",nt,d(t.row.features?.canBeCopySource?"Disable":"Enable")+" Copy Source (Mentor) ",1),e[15]||(e[15]=l("div",{class:"text-caption text-grey"},"Others can copy FROM this user",-1))]),_:2},1024)]),_:2},1032,["onClick"])),[[A]]),w((r(),c(h,{clickable:"",onClick:m=>ye(t.row)},{default:s(()=>[a(p,{avatar:""},{default:s(()=>[a(f,{name:t.row.features?.canBeCopyDestination?"check_circle":"radio_button_unchecked",color:t.row.features?.canBeCopyDestination?"positive":"grey",size:"sm"},null,8,["name","color"])]),_:2},1024),a(p,null,{default:s(()=>[l("div",ct,d(t.row.features?.canBeCopyDestination?"Disable":"Enable")+" Copy Destination (Student) ",1),e[16]||(e[16]=l("div",{class:"text-caption text-grey"}," This user can copy TO their accounts ",-1))]),_:2},1024)]),_:2},1032,["onClick"])),[[A]])])):_("",!0),a(j),w((r(),c(h,{clickable:"",onClick:m=>me(t.row)},{default:s(()=>[a(p,{avatar:""},{default:s(()=>[a(f,{name:t.row.isActive?"block":"check_circle",color:t.row.isActive?"warning":"positive"},null,8,["name","color"])]),_:2},1024),a(p,null,{default:s(()=>[u(d(t.row.isActive?"Suspend Account":"Reactivate Account"),1)]),_:2},1024)]),_:2},1032,["onClick"])),[[A]]),a(j),w((r(),c(h,{clickable:"",onClick:m=>ge(t.row)},{default:s(()=>[a(p,{avatar:""},{default:s(()=>[a(f,{name:"delete",color:"negative"})]),_:1}),a(p,{class:"text-negative"},{default:s(()=>[...e[17]||(e[17]=[u("Delete User",-1)])]),_:1})]),_:1},8,["onClick"])),[[A]])]),_:2},1024)]),_:2},1024)]),_:2},1032,["onClick"])]),_:2},1032,["props"])]),_:1},8,["rows","pagination"])]),_:1})]),_:1})]),a(Qe,{modelValue:D.value,"onUpdate:modelValue":e[6]||(e[6]=t=>D.value=t)},{default:s(()=>[a(G,{class:"te-card",style:{"min-width":"400px"}},{default:s(()=>[a(F,null,{default:s(()=>[...e[18]||(e[18]=[l("div",{class:"text-h6"},"Delete User",-1)])]),_:1}),a(F,null,{default:s(()=>[l("p",ut,[e[19]||(e[19]=u(" Are you sure you want to delete ",-1)),l("strong",null,d(q.value?.displayName),1),e[20]||(e[20]=u("? ",-1))]),e[22]||(e[22]=l("p",{class:"text-body2 te-text-secondary"},"This will permanently delete:",-1)),e[23]||(e[23]=l("ul",{class:"text-body2 te-text-secondary"},[l("li",null,"User profile and authentication"),l("li",null,"All trades and journal entries"),l("li",null,"All trading plans"),l("li",null,"All accounts and relationships")],-1)),a(Ee,{roun
1ded:"",class:"bg-negative text-white q-mt-md"},{avatar:s(()=>[a(f,{name:"warning"})]),default:s(()=>[e[21]||(e[21]=l("strong",null,"This action cannot be undone!",-1))]),_:1})]),_:1}),a(qe,{align:"right"},{default:s(()=>[w(a(E,{flat:"",label:"Cancel"},null,512),[[A]]),a(E,{label:"Delete User",color:"negative",onClick:be,loading:O.value},null,8,["loading"])]),_:1})]),_:1})]),_:1},8,["modelValue"])]),_:1}))}}),Ft=Ie(dt,[["__scopeId","data-v-4dcbd4b1"]]);export{Ft 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.