PageSourceSearch

https://app.gfxtoolz.ai/assets/AdminMemberships-CaGP1qif.js

js gfxtoolz.ai collected 2026-10-05 14:00:46 UTC 19,196 bytes, 1 lines download raw bytes

1import{b as je,l as ve,d as k,t as x,j as e,as as se,aG as E}from"./index-BwS8jYOZ.js";import{a as n,aM as Se,ad as te,a2 as Ne,a8 as we,P as Ce,l as ze,bY as ne,L as Ae,T as Pe,a3 as ke}from"./lucide-icons-B2YBELY1.js";import{A as De}from"./AdminPageHeader-BYu0XUQ5.js";import{A as Ie}from"./AdminFilters-C-VJwNq-.js";import{A as Me,R as Ee}from"./AdminDataTable-CtA6xzd2.js";import{A as Re}from"./AdminPagination-CvrsTY4C.js";import{A as Te,u as Ue,m as $e}from"./adminList-CFeeJ70A.js";import{A as le}from"./AdminStatusBadge-CcEkn5kM.js";import{A as q,M as H}from"./AdminModal-DY_ezMzk.js";import{A as Fe,a as Le}from"./AdminDateRange-SfNM5WSu.js";import{T as W}from"./textarea-Dr4InPZW.js";import"./table-B_yY44Md.js";import"./badge-DGk7VUGA.js";import"./dialog-CrBno7fo.js";import"./adminPeriod-CJ4Vosx8.js";const U=l=>new Date(l).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),Oe=(l,i)=>{const b=parseFloat(l);return Number.isFinite(b)?new Intl.NumberFormat(i==="USD"?"en-US":"en-IN",{style:"currency",currency:i||"INR",maximumFractionDigits:2}).format(b):"—"},_e={payment_gateway:{label:"Payment",className:"bg-blue-50 text-blue-700"},admin_manual:{label:"Admin",className:"bg-purple-50 text-purple-700"},admin_grant:{label:"Admin",className:"bg-purple-50 text-purple-700"},admin:{label:"Admin",className:"bg-purple-50 text-purple-700"},migration:{label:"Migrated",className:"bg-amber-50 text-amber-700"},auto_signup:{label:"Auto (free)",className:"bg-zinc-100 text-zinc-600"}},re=l=>Ue({userId:l.userId,tab:"memberships",focus:$e(l.status),highlight:l.id}),na=()=>{const l=je(),[i,b]=ve(),[t,o]=n.useState([]),[f,g]=n.useState([]),[j,d]=n.useState(!0),[c,v]=n.useState(""),[s,S]=n.useState(()=>({planType:i.get("planType")||"paid",status:i.get("status")||"",planId:i.get("planId")||"",source:i.get("source")||"",currency:i.get("currency")||"",renewal:i.get("atRisk")?"atRisk":i.get("autopay")?"autopay":i.get("expiringDays")?`exp${i.get("expiringDays")}`:""})),[C,h]=n.useState(1),[D,$]=n.useState(Te),[F,r]=n.useState(1),[m,y]=n.useState(0),[N,X]=n.useState(""),[A,Y]=n.useState(""),[L,ie]=n.useState("createdAt"),[O,oe]=n.useState("DESC"),[J,Q]=n.useState(null),[ce,ee]=n.useState(!1),[de,_]=n.useState(!1),[ue,B]=n.useState(!1),[me,K]=n.useState(!1),[pe,G]=n.useState(!1),[he,V]=n.useState(!1),[w,R]=n.useState(null);n.useEffect(()=>{xe()},[]),n.useEffect(()=>{z()},[C,D,s,c,N,A,L,O]);const P=(a,p)=>{S(T=>({...T,[a]:p})),h(1)},z=async()=>{var a,p,T,ae;d(!0);try{const M=new URLSearchParams({page:C.toString(),limit:D.toString(),planType:s.planType,sortBy:L,sortOrder:O,...c&&{search:c},...s.status&&{status:s.status},...s.planId&&{planId:s.planId},...s.source&&{source:s.source},...s.currency&&{currency:s.currency},...s.renewal==="atRisk"&&{atRisk:"true"},...s.renewal==="autopay"&&{autopay:"true"},...s.renewal.startsWith("exp")&&{expiringDays:s.renewal.slice(3)},...N&&{dateFrom:N},...A&&{dateTo:`${A}T23:59:59.999Z`}}),{data:u}=await k.get(`/admin/memberships?${M.toString()}`);o((u==null?void 0:u.data)??[]),r(((a=u==null?void 0:u.pagination)==null?void 0:a.totalPages)||1),y(((p=u==null?void 0:u.pagination)==null?void 0:p.total)||0),Q(null)}catch(M){const u=((ae=(T=M==null?void 0:M.response)==null?void 0:T.data)==null?void 0:ae.message)||"Failed to load memberships";Q(Array.isArray(u)?u.join(", "):u),o([]),y(0),r(1),x.error(Array.isArray(u)?u.join(", "):u)}finally{d(!1)}},xe=async()=>{try{const{data:a}=await k.get("/admin/plans?limit=100"),p=(a==null?void 0:a.items)||(a==null?void 0:a.data)||(Array.isArray(a)?a:[]);g(p),ee(!1)}catch{g([]),ee(!0),x.error("Couldn’t load plans — the Plan filter is unavailable")}},I="p-2 rounded-lg text-zinc-500 transition-colors hover:bg-zinc-200 hover:text-zinc-900",be=[{key:"user",label:"User",sortKey:"userEmail",render:a=>e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate font-medium text-zinc-900",children:a.userName||"Unnamed"}),e.jsx("p",{className:"truncate text-sm text-zinc-500",children:a.userEmail})]})},{key:"plan",label:"Plan",sortKey:"planName",render:a=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(te,{className:"h-4 w-4 shrink-0 text-amber-500"}),e.jsx("span",{className:"font-medium text-zinc-900",children:a.planName})]})},{key:"status",label:"Status",sortKey:"status",render:a=>e.jsx(le,{status:a.status})},{key:"autopay",label:"Autopay",render:a=>a.autopay?e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:a.autopay.enabled?"font-medium text-violet-700":"text-amber-700",children:a.autopay.enabled?a.autopay.gateway:"off"}),a.autopay.enabled&&a.autopay.nextChargeAt&&e.jsxs("p",{className:"text-zinc-500",children:["charges ",U(a.autopay.nextChargeAt)
1]})]}):e.jsx("span",{className:"text-sm text-zinc-400",children:"—"})},{key:"period",label:"Period",sortKey:"currentPeriodEnd",render:a=>e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"text-zinc-700",children:U(a.currentPeriodStart)}),e.jsxs("p",{className:"text-zinc-500",children:["to ",U(a.currentPeriodEnd)]})]})},{key:"amount",label:"Amount",sortKey:"amountPaid",headerClassName:"text-right",className:"text-right",render:a=>e.jsx("span",{className:"whitespace-nowrap font-medium text-zinc-900",children:Oe(a.amountPaid,a.currency)})},{key:"source",label:"Source",render:a=>{const p=_e[a.source]??{label:a.source||"Unknown",className:"bg-zinc-100 text-zinc-600"};return e.jsx("span",{className:`inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2 py-0.5 text-xs ${p.className}`,children:p.label})}},{key:"actions",label:"Actions",headerClassName:"text-right",className:"text-right",render:a=>e.jsxs(Ee,{children:[e.jsx("button",{onClick:()=>l(re(a)),className:I,title:"View user",children:e.jsx(Ne,{size:16})}),e.jsx("button",{onClick:()=>{R(a),V(!0)},className:I,title:"Edit dates",children:e.jsx(we,{size:16})}),a.status==="active"?e.jsx("button",{onClick:()=>{R(a),B(!0)},className:`${I} hover:text-yellow-700`,title:"Pause",children:e.jsx(Ce,{size:16})}):a.status==="paused"?e.jsx("button",{onClick:()=>{R(a),K(!0)},className:`${I} hover:text-emerald-700`,title:"Resume",children:e.jsx(ze,{size:16})}):null,(a.status==="active"||a.status==="paused")&&e.jsx("button",{onClick:()=>{R(a),G(!0)},className:`${I} hover:text-red-700`,title:"Cancel",children:e.jsx(ne,{size:16})})]})}],ge=[{value:"",label:ce?"Plans unavailable":"All Plans"},...Array.isArray(f)?f.map(a=>({value:a.id,label:a.name})):[]],ye=(s.planType!=="paid"?1:0)+[s.status,s.planId,s.source,s.currency,s.renewal].filter(Boolean).length+(N||A?1:0)+(c?1:0),fe=()=>{S({planType:"paid",status:"",planId:"",source:"",currency:"",renewal:""}),v(""),X(""),Y(""),h(1),b(new URLSearchParams,{replace:!0})};return e.jsxs("div",{className:"space-y-6",children:[e.jsx(De,{title:"Membership Management",description:s.planType==="paid"?`${m.toLocaleString()} paid membership${m===1?"":"s"} · free auto-signup plans hidden`:s.planType==="free"?`${m.toLocaleString()} free auto-signup subscription${m===1?"":"s"}`:`${m.toLocaleString()} subscription${m===1?"":"s"}, paid and free`,actions:e.jsxs(e.Fragment,{children:[e.jsx(Fe,{dateFrom:N,dateTo:A,onChange:(a,p)=>{X(a),Y(p),h(1)}}),e.jsx(Le,{endpoint:"/admin/memberships/export",filename:"memberships_export",filters:{planType:s.planType,status:s.status,planId:s.planId,source:s.source,search:c},dateFrom:N,dateTo:A}),e.jsxs(se,{onClick:()=>_(!0),className:"bg-violet-600 text-white hover:bg-violet-700",children:[e.jsx(Se,{className:"mr-2 h-4 w-4"}),"Create Membership"]})]})}),e.jsx(Ie,{searchValue:c,onSearchChange:a=>{v(a),h(1)},searchPlaceholder:"Search by user email or plan...",debounceMs:350,onClearAll:fe,activeCount:ye,filters:[{key:"planType",label:"Plan scope",value:s.planType,onChange:a=>P("planType",a),options:[{value:"paid",label:"Paid plans"},{value:"free",label:"Free (auto-signup)"},{value:"all",label:"All plans"}]},{key:"status",label:"Status",value:s.status,onChange:a=>P("status",a),options:[{value:"",label:"All Status"},{value:"active",label:"Active"},{value:"paused",label:"Paused"},{value:"past_due",label:"Past due"},{value:"cancelled",label:"Cancelled"},{value:"expired",label:"Expired"}]},{key:"planId",label:"Plan",value:s.planId,onChange:a=>P("planId",a),options:ge},{key:"source",label:"Source",value:s.source,onChange:a=>P("source",a),options:[{value:"",label:"All Sources"},{value:"payment_gateway",label:"Payment gateway"},{value:"admin_manual",label:"Admin assigned"},{value:"migration",label:"Migrated"},{value:"auto_signup",label:"Auto signup"}]},{key:"currency",label:"Currency",value:s.currency,onChange:a=>P("currency",a),options:[{value:"",label:"Any currency"},{value:"INR",label:"INR"},{value:"USD",label:"USD"}]},{key:"renewal",label:"Renewal",value:s.renewal,onChange:a=>P("renewal",a),options:[{value:"",label:"Any renewal"},{value:"exp7",label:"Expiring in 7 days"},{value:"exp14",label:"Expiring in 14 days"},{value:"exp30",label:"Expiring in 30 days"},{value:"atRisk",label:"At risk (no auto-renew)"},{value:"autopay",label:"Autopay on (mandate)"}]}]}),J&&e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-xl border border-rose-200 bg-rose-50 px-4 py-3",children:[e.jsx("p",{className:"text-[13px] text-rose-700",children:J}),e.jsx(se,{size:"sm",variant:"outline",onClick:z,className:"h-8 border-rose-300 text-[12px] text-rose-700 hover:bg-rose-100",children:"Retry"})]}),e.jsxs("div",{children:[e.jsx(Me,{data:t,columns:be,isLoading:j,emptyMessage:s.planType==="paid"?"No paid memberships match these filters. Switch Plan scope to “All plans” to include free auto-signup subscriptions.":"No memberships found matching your criteria.",emptyIcon:e.jsx(te,{size:48,className:"opacity-30"}),keyExtractor:a=>a.id,rowLink:re,sortBy:L,sortOrder:O,onSortChange:(a,p)=>{ie(a),oe(p),h(1)}}),e.jsx(Re,{page:C,totalPages:F,total:m,itemName:"memberships",onPageChange:h,pageSize:D,onPageSizeChange:a=>{$(a),h(1)},variant:"detached"})]}),de&&e.jsx(Be,{plans:f,onClose:()=>_(!1),onSuccess:()=>{_(!1),z()}}),ue&&w&&e.jsx(Z,{membership:w,action:"pause",onClose:()=>B(!1),onSuccess:()=>{B(!1),z()}}),me&&w&&e.jsx(Z,{membership:w,action:"resume",onClose:()=>K(!1),onSuccess:()=>{K(!1),z()}}),pe&&w&&e.jsx(Z,{membership:w,action:"cancel",onClose:()=>G(!1),onSuccess:()=>{G(!1),z()}}),he&&w&&e.jsx(Ke,{membership:w,onClose:()=>V(!1),onSuccess:()=>{V(!1),z()}})]})},Be=({plans:l,onClose:i,onSuccess:b})=>
1{const[t,o]=n.useState({userId:"",planId:"",startDate:new Date().toISOString().split("T")[0],endDate:new Date(Date.now()+31536e6).toISOString().split("T")[0],autoRenew:!1,overrideOverlap:!1,reason:""}),[f,g]=n.useState(""),[j,d]=n.useState([]),[c,v]=n.useState(null),[s,S]=n.useState(!1),[C,h]=n.useState(!1),D=async r=>{if(r.length<2){d([]);return}S(!0);try{const{data:m}=await k.get(`/admin/users?search=${encodeURIComponent(r)}&limit=10`);d((m.items||[]).map(y=>({id:y.id,email:y.email,name:y.profile?`${y.profile.firstName} ${y.profile.lastName}`:"Unnamed"})))}catch(m){console.error("User search failed",m)}finally{S(!1)}},$=r=>{v(r),o({...t,userId:r.id}),d([]),g("")},F=async()=>{var r,m;if(!t.userId||!t.planId||!t.reason){x.error("User, plan, and reason are required");return}if(t.reason.length<10){x.error("Reason must be at least 10 characters");return}h(!0);try{await k.post("/admin/memberships",t),x.success("Membership created successfully"),b()}catch(y){const N=((m=(r=y.response)==null?void 0:r.data)==null?void 0:m.message)||"Failed to create membership";x.error(N)}finally{h(!1)}};return e.jsx(q,{isOpen:!0,onClose:i,title:"Create Membership",description:"Manually assign a plan to a user without payment",footer:e.jsx(H,{onCancel:i,onSubmit:F,submitLabel:"Create Membership",isSubmitting:C,submitDisabled:!t.userId||
1!t.planId||t.reason.length<10}),children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500 mb-1",children:"User *"}),c?e.jsxs("div",{className:"flex items-center justify-between p-3 bg-zinc-100 rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium text-zinc-900",children:c.name}),e.jsx("p",{className:"text-sm text-zinc-500",children:c.email})]}),e.jsx("button",{onClick:()=>{v(null),o({...t,userId:""})},className:"text-zinc-500 hover:text-zinc-700",children:e.jsx(ne,{size:18})})]}):e.jsxs("div",{className:"relative",children:[e.jsx(E,{placeholder:"Search by email...",value:f,onChange:r=>{g(r.target.value),D(r.target.value)}}),s&&e.jsx(Ae,{className:"absolute right-3 top-2.5 w-4 h-4 animate-spin text-zinc-400"}),j.length>0&&e.jsx("div",{className:"absolute z-10 mt-1 w-full bg-white border border-zinc-200 rounded-lg shadow-lg max-h-48 overflow-auto",children:j.map(r=>e.jsxs("button",{onClick:()=>$(r),className:"w-full text-left px-3 py-2 hover:bg-zinc-100 transition-colors",children:[e.jsx("p",{className:"font-medium text-zinc-900",children:r.name}),e.jsx("p",{className:"text-sm text-zinc-500",children:r.email})]},r.id))})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500 mb-1",children:"Plan *"}),e.jsxs("select",{className:"w-full h-9 px-3 py-2 rounded-lg border border-zinc-200 bg-white text-sm outline-none focus:ring-2 focus:ring-purple-500/20 focus:border-purple-500",value:t.planId,onChange:r=>o({...t,planId:r.target.value}),children:[e.jsx("option",{value:"",children:"Select a plan"}),l.map(r=>e.jsx("option",{value:r.id,children:r.name},r.id))]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500 mb-1",children:"Start Date *"}),e.jsx(E,{type:"date",value:t.startDate,onChange:r=>o({...t,startDate:r.target.value})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500 mb-1",children:"End Date *"}),e.jsx(E,{type:"date",value:t.endDate,onChange:r=>o({...t,endDate:r.target.value})})]})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:t.autoRenew,onChange:r=>o({...t,autoRenew:r.target.checked}),className:"rounded border-zinc-300 text-purple-600 focus:ring-purple-500"}),e.jsx("span",{className:"text-sm text-zinc-700",children:"Auto-renew"})]}),e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:t.overrideOverlap,onChange:r=>o({...t,overrideOverlap:r.target.checked}),className:"rounded border-zinc-300 text-orange-600 focus:ring-orange-500"}),e.jsx("span",{className:"text-sm text-zinc-700",children:"Override existing"})]})]}),t.overrideOverlap&&e.jsx("div",{className:"p-3 bg-orange-50  border border-orange-200  rounded-lg",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(Pe,{className:"w-4 h-4 text-orange-600 mt-0.5"}),e.jsx("p",{className:"text-sm text-orange-700",children:"This will cancel any existing active membership for this user."})]})}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500  mb-1",children:"Reason * (min 10 chars)"}),e.jsx(W,{placeholder:"e.g., Customer support request, promotional offer...",value:t.reason,onChange:r=>o({...t,reason:r.target.value}),rows:3})]})]})})},Z=({membership:l,action:i,onClose:b,onSuccess:t})=>{const[o,f]=n.useState(""),[g,j]=n.useState(!1),c={pause:{label:"Pause Membership",endpoint:"pause",color:"yellow"},resume:{label:"Resume Membership",endpoint:"resume",color:"emerald"},cancel:{label:"Cancel Membership",endpoint:"cancel",color:"red"}}[i],v=async()=>{var s,S;if(o.length<10){x.error("Reason must be at least 10 characters");return}j(!0);try{await k.post(`/admin/memberships/${l.id}/${c.endpoint}`,{reason:o}),x.success(`Membership ${i}d successfully`),t()}catch(C){const h=((S=(s=C.response)==null?void 0:s.data)==null?void 0:S.message)||`Failed to ${i} membership`;x.error(h)}finally{j(!1)}};return e.jsx(q,{isOpen:!0,onClose:b,title:c.label,description:`${c.label} for ${l.userEmail}`,footer:e.jsx(H,{onCancel:b,onSubmit:v,submitLabel:c.label,isSubmitting:g,submitDisabled:o.length<10}),children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"p-3 bg-zinc-100 rounded-lg",children:e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-zinc-500",children:"User"}),e.jsx("p",{className:"font-medium text-zinc-900",children:l.userEmail})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-zinc-500",children:"Plan"}),e.jsx("p",{className:"font-medium text-zinc-900",children:l.planName})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-zinc-500",children:"Current Status"}),e.jsx(le,{status:l.status})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-zinc-500",children:"Ends"}),e.jsx("p",{className:"font-medium text-zinc-900",children:U(l.currentPeriodEnd)})]})]})}),i==="resume"&&e.jsx("div",{className:"p-3 bg-emerald-50  border border-emerald-200  rounded-lg",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(ke,{className:"w-4 h-4 text-emerald-600 mt-0.5"}),e.jsx("p",{className:"text-sm text-emerald-700",children:"The end date will be extended by the paused duration."})]})}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500  mb-1",children:"Reason * (min 10 chars)"}),e.jsx(W,{placeholder:"Provide a reason for this action...",value:o,onChange:s=>
1f(s.target.value),rows:3})]})]})})},Ke=({membership:l,onClose:i,onSuccess:b})=>{const[t,o]=n.useState({startDate:l.currentPeriodStart.split("T")[0],endDate:l.currentPeriodEnd.split("T")[0],reason:""}),[f,g]=n.useState(!1),j=async()=>{var d,c;if(t.reason.length<10){x.error("Reason must be at least 10 characters");return}g(!0);try{await k.put(`/admin/memberships/${l.id}/dates`,t),x.success("Dates updated successfully"),b()}catch(v){const s=((c=(d=v.response)==null?void 0:d.data)==null?void 0:c.message)||"Failed to update dates";x.error(s)}finally{g(!1)}};return e.jsx(q,{isOpen:!0,onClose:i,title:"Edit Membership Dates",description:`Update dates for ${l.userEmail}'s membership`,footer:e.jsx(H,{onCancel:i,onSubmit:j,submitLabel:"Save Changes",isSubmitting:f,submitDisabled:t.reason.length<10}),children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500 mb-1",children:"Start Date"}),e.jsx(E,{type:"date",value:t.startDate,onChange:d=>o({...t,startDate:d.target.value})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500 mb-1",children:"End Date"}),e.jsx(E,{type:"date",value:t.endDate,onChange:d=>o({...t,endDate:d.target.value})})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-zinc-500 mb-1",children:"Reason * (min 10 chars)"}),e.jsx(W,{placeholder:"Provide a reason for this date change...",value:t.reason,onChange:d=>o({...t,reason:d.target.value}),rows:3})]})]})})};export{na as AdminMemberships};

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.