1import{u as ee,r as m,a as ce,b as te,c as le,f as ue,g as me,d as D,e as se,h as V,j as e,A as pe,i as T,C as J,B as P,S as he,U as fe,s as xe,k as _,l as F,m as ge,n as H,o as re,p as X,q as ye,t as we,v as be}from"./index-BR27rmZV.js";import{a as ve}from"./invitationData-BNV87gsi.js";import{l as Ne}from"./invitationApi-jzvI4BCb.js";import{u as je}from"./useSeatManagement-Ckh0mAj2.js";import{R as Ce}from"./refresh-cw-BFKkZVxf.js";import{P as Ie}from"./plus-09Kmmtdb.js";function Z(t){if(t instanceof Error)return t;if(t&&typeof t=="object"){const i=t,n=(Array.isArray(i.errors)?i.errors.map(w=>w==null?void 0:w.message).filter(Boolean).join("; "):void 0)||i.message;if(n)return new Error(n);try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}return new Error(String(t))}const Ae=()=>{const t=ee(),[i,I]=m.useState(!1),[n,w]=m.useState(""),g=ce(),{toast:u}=te(),{isActive:d,loading:v}=le(),{getUsage:E,reconcileSeats:f}=je(),[y,q]=m.useState(null),[M,G]=m.useState(!1),[L,O]=m.useState(!1),[p,j]=m.useState(""),[a,S]=m.useState(""),[b,x]=m.useState(""),[c,o]=m.useState([]),[N,h]=m.useState(!0);m.useEffect(()=>{(async()=>{h(!0);try{const r=await ge();o(r)}catch(r){console.error("Failed to load products:",r)}finally{h(!1)}})()},[]),m.useEffect(()=>{(async()=>{try{const r=await ue();j(r.email??"")}catch{j("")}})()},[]),m.useEffect(()=>{!a||!d||E(a).then(s=>{s&&q(s)})},[a,d]),m.useEffect(()=>{(async()=>{try{const s=await me();S(s.userId??s.username??""),x(s.username??"")}catch{S(""),x("")}})()},[]);const{data:C,isLoading:K}=D({queryKey:["groups"],staleTime:0,gcTime:1e3*60*5,refetchOnMount:"always",refetchOnWindowFocus:!0,queryFn:async()=>(await we({limit:50})).items}),{data:$}=D({queryKey:["userMemberships",a,b,p],enabled:!!(a||p),staleTime:0,gcTime:1e3*60*5,refetchOnMount:"always",refetchOnWindowFocus:!0,queryFn:async()=>{if(!a&&!p)return[];const s=[];return a&&s.push({userId:{eq:a}}),b&&b!==a&&s.push({userId:{eq:b}}),p&&s.push({email:{eq:p.trim().toLowerCase()}}),(await F({filter:{or:s}})).filter(l=>(l.status??"").toUpperCase()!=="LEFT")}}),z=m.useMemo(()=>{if(!C)return[];const s=new Set(($??[]).map(r=>r.groupId));return C.filter(r=>{if(r.deletedAt||r.visibility==="hidden")return!1;if(r.visibility==="private"){const l=r.owner===a||r.owner===b,U=s.has(r.id)||l;return l||U}return!0})},[C,a,b,$]),Y=m.useMemo(()=>{const s=z??[],r=n.trim().toLowerCase();return r?s.filter(l=>(l.displayName??"").toLowerCase().includes(r)):s},[z,n]),ae=(z??[]).length,{data:R,refetch:B}=D({queryKey:["groupInvites",p],enabled:!!p,queryFn:async()=>{const s=p.trim().toLowerCase(),r=await F({filter:{and:[{email:{eq:s}},{status:{eq:"INVITED"}}]}}),l=new Set,U=r.filter(A=>{const k=A.groupId??A.id;return l.has(k)?!1:(l.add(k),!0)});return await Promise.all(U.map(async A=>{const k=A.groupId?await be(A.groupId):null;return{...A,groupName:(k==null?void 0:k.displayName)??null}}))}}),W=se(),{mutateAsync:ne,isPending:ie}=V({mutationFn:async s=>{if(!a)throw new Error("User ID not available. Please refresh and try again.");try{const r=p.trim().toLowerCase(),U=(s.groupId?await Ne(s.groupId):[]).find(Q=>(Q.email??"").trim().toLowerCase()===r&&!!Q.token);if(U&&(await ve(U)).success)return}catch(r){console.warn("Lambda accept path unavailable, falling back to direct update:",r)}await H({id:s.id,status:"ACCEPTED",joinedAt:new Date().toISOString(),userId:a}),await re(s.groupId)},onSuccess:async(s,r)=>{u({title:"Joined group"}),await B(),await W.invalidateQueries({queryKey:["userMemberships",a,b,p]}),await W.invalidateQueries({queryKey:["groups"]}),r!=null&&r.groupId&&t(`/group/${r.groupId}`)},onError:(s,r)=>{const l=Z(s);X(l,{tags:{feature:"group-invite",action:"accept"},extra:{inviteId:r==null?void 0:r.id,groupId:r==null?void 0:r.groupId,userId:a,userEmail:p}}),u({title:"Failed to accept invite",description:l.message,variant:"destructive"})}}),{mutateAsync:oe,isPending:de}=V({mutationFn:async s=>{if(!a)throw new Error("User ID not available. Please refresh and try again.");await H({id:s.id,status:"DECLINED",userId:a})},onSuccess:async()=>{u({title:"Invitation declined"}),await B()},onError:(s,r)=>{const l=Z(s);X(l,{tags:{feature:"group-invite",action:"decline"},extra:{inviteId:r==null?void 0:r.id,userId:a,userEmail:p}}),u({title:"Failed to decline invite",description:l.message,variant:"destructive"})}});return e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx(pe,{collapsed:i,onToggle:()=>I(!i)}),e.jsx("main",{className:T("transition-all duration-300 min-h-screen",!g&&(i?"ml-16":"ml-60")),children:e.jsxs("div",{className:"p-6 max-w-7xl mx-auto",children:[!v&&!d&&e.jsxs("div",{className:"bg-gradient-to-r from-accent/10 to-accent/5 border border-accent/20 rounded-xl p-4 mb-6 flex items-start gap-3",children:[e.jsx(J,{className:"w-5 h-5 text-accent shrink-0 mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-sm font-medium text-foreground mb-1",children:"Viewing Your Groups"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"You can view groups you've been invited to. Upgrade to Premium to create your own groups and invite members."})]}),e.jsx(P,{variant:"outline",size:"sm",onClick:()=>t("/assessments"),children:"Upgrade"})]}),e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"bg-card rounded-xl shadow-soft p-4 mb-6",children:e.jsxs("div",{className:"relative",children:[e.jsx(he,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-muted-foreground"}),e.jsx("input",{type:"text",placeholder:"Search groups...",value:n,onChange:s=>w(s.target.value),className:"w-full h-10 pl-10 pr-4 rounded-lg border border-border bg-background text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-accent/50"})]})}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-4 mb-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 bg-card rounded-lg border border-border",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:d?"Total Groups":"Your Groups"}),e.jsx("span",{className:"text-sm font-semibold text-foreground",children:ae})]}),d&&(y==null?void 0:y.seatLimit)&&e.jsxs("div",{className:T("flex items-center gap-2 px-4 py-2 rounded-lg border text-sm",y.percentage>=90?"bg-red-50 border-red-200 text-red-700":y.percentage>
1=70?"bg-yellow-50 border-yellow-200 text-yellow-700":"bg-card border-border text-foreground"),children:[e.jsx("span",{className:"text-muted-foreground",children:y.productName?y.productName.replace("Premium ",""):"Seats"}),e.jsxs("span",{className:"font-semibold",children:[y.seatsUsed,"/",y.seatLimit]}),e.jsx("button",{disabled:M,onClick:async()=>{if(a){G(!0);try{const s=await f(a);s&&q(s)}finally{G(!1)}}},className:"ml-1 text-muted-foreground hover:text-foreground transition-colors disabled:opacity-40",title:"Sync seat count",children:e.jsx(Ce,{className:T("w-3 h-3",M&&"animate-spin")})})]})]}),v?e.jsx("div",{className:"h-9 w-32 rounded-lg bg-muted animate-pulse"}):d?e.jsxs(P,{variant:"navy",className:"gap-2",onClick:()=>t("/create-group"),children:[e.jsx(Ie,{className:"w-4 h-4"}),"Create Group"]}):e.jsxs(P,{variant:"outline",className:"gap-2",onClick:()=>t("/assessments"),children:[e.jsx(J,{className:"w-4 h-4"}),"Upgrade to Create Groups"]})]}),p&&(R??[]).length>0&&e.jsxs("div",{className:"bg-card rounded-xl shadow-soft border border-border p-4 mb-6",children:[e.jsx("h2",{className:"font-display font-semibold text-foreground mb-3",children:"Your Group Invitations"}),e.jsx("div",{className:"divide-y divide-border",children:(R??[]).map(s=>e.jsxs("div",{className:"py-3 flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-foreground",children:s.groupName??`Group ${s.groupId}`}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Invited as ",s.role??"member"," ⢠",s.email]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(P,{variant:"navy",size:"sm",disabled:ie,onClick:()=>ne({id:s.id,groupId:s.groupId}),children:"Accept"}),e.jsx(P,{variant:"outline",size:"sm",disabled:de,onClick:()=>oe({id:s.id}),children:"Decline"})]})]},s.id))})]}),e.jsxs("div",{className:"bg-card rounded-xl shadow-soft border border-accent/30 p-6 mb-6",children:[e.jsx("h2",{className:"font-display text-lg font-semibold text-foreground mb-3",children:"What is a Thrive Circle?"}),e.jsx("p",{className:"text-sm text-muted-foreground leading-relaxed",children:"A Thrive Circle is a small group (two or more people) who choose to grow together by learning to see one another through the eyes of Christ. It's a place to practice real loveâencountering God's truth, goodness, unity, and beauty in the other personâand to learn how to communicate, relate, and collaborate with grace. In this part of the app, you can invite friends or family to form your circle and start thriving together in your relationship with God, with each other, and in whatever you're building side by side."})]}),e.jsx("h1",{className:"font-display text-2xl font-semibold text-foreground mb-6",children:"Thrive Circles"}),!d&&Y.length===0&&(R??[]).length===0&&e.jsxs("div",{className:"bg-card rounded-xl shadow-soft p-12 text-center space-y-4 mb-6",children:[e.jsx("div",{className:"rounded-full bg-muted/50 w-16 h-16 mx-auto flex items-center justify-center",children:e.jsx(fe,{className:"w-8 h-8 text-muted-foreground"})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("h3",{className:"font-display font-semibold text-foreground",children:"No Groups Yet"}),e.jsx("p",{className:"text-sm text-muted-foreground max-w-md mx-auto",children:"You haven't been invited to any groups yet. Ask a friend to invite you, or upgrade to Premium to create your own groups."})]}),e.jsxs(P,{variant:"navy",onClick:()=>t("/assessments"),children:[e.jsx(J,{className:"w-4 h-4 mr-2"}),"View Premium Plans"]})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6 mb-12",children:K?e.jsx("div",{className:"text-muted-foreground",children:"Loading groups..."}):Y.length===0?e.jsx("div",{className:"text-muted-foreground",children:d?"No groups yet. Create one!":"No groups to display"}):Y.map(s=>e.jsx(qe,{group:s,userId:a,username:b,userEmail:p},s.id))}),!v&&!d&&e.jsxs("div",{className:"mt-12 pt-8 border-t border-border",children:[e.jsxs("div",{className:"text-center mb-6",children:[e.jsx("h2",{className:"font-display text-lg font-semibold text-foreground mb-2",children:"Ready to Create Your Own Group?"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Choose a plan that fits your community size"})]}),N?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Loading plans..."}):c.length>0?e.jsx("div",{className:"overflow-x-auto pb-4",children:e.jsx("div",{className:"flex gap-4 min-w-max mx-auto justify-center",children:c.map(s=>e.jsx(Se,{product:s,subscribing:L,onSubscribe:async r=>{O(!0);try{await xe(r)}catch(l){u({title:"Unable to start checkout",description:l instanceof Error?l.message:"Please try again.",variant:"destructive"}),O(!1)}}},s.id))})}):e.jsx("p",{className:"text-sm text-muted-foreground text-center py-4",children:"No subscription plans available at the moment."})]})]})]})})]})};function Se({product:t,subscribing:i,onSubscribe:I}){var y,q,M,G;const[n,w]=m.useState("year"),g=(y=t.prices)==null?void 0:y.find(L=>L.interval==="month"),u=(q=t.prices)==null?void 0:q.find(L=>
1L.interval==="year"),v=(n==="month"?g:u)||g||u,E=n==="month"?(M=t.trialDays)==null?void 0:M.monthly:(G=t.trialDays)==null?void 0:G.annual,f=g&&u?Math.round((1-u.amount/12/g.amount)*100):0;return e.jsxs("div",{className:"bg-card rounded-lg border border-border p-4 w-64 hover:border-accent/50 transition-colors",children:[e.jsx("h3",{className:"font-semibold text-foreground mb-1",children:t.name}),e.jsx("p",{className:"text-xs text-muted-foreground mb-3 line-clamp-2",children:t.description}),g&&u&&e.jsxs("div",{className:"flex items-center gap-1 mb-3 bg-muted/50 rounded-md p-1",children:[e.jsx("button",{onClick:()=>w("month"),className:T("flex-1 text-xs py-1.5 px-2 rounded transition-colors",n==="month"?"bg-background text-foreground font-medium":"text-muted-foreground hover:text-foreground"),children:"Monthly"}),e.jsxs("button",{onClick:()=>w("year"),className:T("flex-1 text-xs py-1.5 px-2 rounded transition-colors relative",n==="year"?"bg-background text-foreground font-medium":"text-muted-foreground hover:text-foreground"),children:["Annual",f>0&&e.jsxs("span",{className:"ml-1 text-[10px] text-accent",children:["Save ",f,"%"]})]})]}),v&&e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"flex items-baseline gap-1",children:[e.jsxs("span",{className:"text-2xl font-bold text-foreground",children:["$",(v.amount/100).toFixed(2)]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["/",v.interval]})]}),E&&E>0&&e.jsxs("p",{className:"text-xs text-accent mt-1",children:[E,"-day free trial"]})]}),e.jsx(P,{variant:"navy",size:"sm",className:"w-full",disabled:i||!v,onClick:()=>v&&I(v.id),children:"Get Started"})]})}function qe({group:t,userId:i,username:I,userEmail:n}){const w=ee(),g=se(),{toast:u}=te(),{data:d,isLoading:v}=D({queryKey:["ownerProfile",t.owner,t.id],enabled:!!t.owner,queryFn:async()=>{if(!t.owner)return null;const x=await _(t.owner);if(x)return x;const o=(await F({filter:{groupId:{eq:t.id}}})).find(N=>(N.role??"").toLowerCase()==="owner"||N.userId===t.owner);return o!=null&&o.name||o!=null&&o.email?{displayName:o.name??null,email:o.email??null}:null},retry:1}),E=()=>d!=null&&d.displayName?d.displayName.includes("@")?d.displayName.split("@")[0]:d.displayName:d!=null&&d.email?d.email.split("@")[0]:v?"Loading...":t.owner?t.owner.includes("@")?t.owner.split("@")[0]:"Group Owner":"â",{data:f,isLoading:y}=D({queryKey:["groupMembership",t.id,i,I,n],enabled:!!(i||n),staleTime:0,gcTime:1e3*60*5,refetchOnMount:"always",refetchOnWindowFocus:!0,queryFn:async()=>{if(!i&&!n)return null;const x=await F({filter:{groupId:{eq:t.id}}}),c=[];if(x.length>0&&x.forEach(o=>{var K;const N=o.userId===i,h=o.userId===I,C=((K=o.email)==null?void 0:K.trim().toLowerCase())===(n==null?void 0:n.trim().toLowerCase());(N||h||C)&&(o.status??"").toUpperCase()!=="LEFT"&&c.push(o)}),c.length>0){const o=c.find(C=>(C.status??"").toUpperCase()==="ACCEPTED");if(o)return o;const N=c.find(C=>(C.status??"").toUpperCase()==="PENDING");if(N)return N;const h=c.find(C=>(C.status??"").toUpperCase()==="INVITED");return h||c[0]}return null}}),{mutateAsync:q,isPending:M}=V({mutationFn:async()=>{var N;if(!n)throw new Error("Email required to join group");if(t.visibility==="private"||t.joinMethod==="invite")throw new Error("This group requires an invitation. Please ask the group owner to send you an invitation.");if(f)throw new Error("You are already a member of this group");const c=(await F({filter:{and:[{groupId:{eq:t.id}},{or:[...i?[{userId:{eq:i}}]:[],...n?[{email:{eq:n.trim().toLowerCase()}}]:[]]}]}})).filter(h=>(h.status??"").toUpperCase()!=="LEFT");if(c.length>0)throw g.setQueryData(["groupMembership",t.id,i,n],c[0]),new Error("You are already a member of this group");let o="";if(i)try{const h=await _(i);o=(h==null?void 0:h.displayName)||((N=h==null?void 0:h.email)==null?void 0:N.split("@")[0])||""}catch{}await ye({groupId:t.id,groupOwnerId:t.owner||"",name:o||void 0,email:n.trim().toLowerCase(),userId:i||void 0,role:"Member",status:t.joinMethod==="open"?"ACCEPTED":"PENDING",joinedAt:t.joinMethod==="open"?new Date().toISOString():void 0}),t.joinMethod==="open"&&await re(t.id)},onSuccess:async()=>{u({title:t.joinMethod==="open"?"Joined group!":"Join request sent",description:t.joinMethod==="approval"?"Waiting for admin a
1pproval":void 0}),await g.invalidateQueries({queryKey:["groupMembership",t.id,i,I,n]}),await g.invalidateQueries({queryKey:["groupMembership",t.id]}),await g.invalidateQueries({queryKey:["userMemberships",i,I,n]}),t.joinMethod==="open"&&w(`/group/${t.id}`)},onError:x=>{const c=String((x==null?void 0:x.message)||x);console.error("Join group error:",x),c.includes("Unauthorized")||c.includes("Not Authorized")?(u({title:"Unable to join group",description:"Authorization error. You may already be a member or this is a private group. Please refresh the page.",variant:"destructive"}),g.invalidateQueries({queryKey:["groupMembership",t.id]})):c.includes("requires an invitation")?u({title:"Invitation Required",description:"This is a private group. Please ask the group owner to send you an invitation.",variant:"default"}):c.includes("already a member")?(u({title:"Already a member",description:"You are already part of this group.",variant:"default"}),g.invalidateQueries({queryKey:["groupMembership",t.id]})):u({title:"Failed to join group",description:c,variant:"destructive"})}}),G=t.owner===i||t.owner===I,L=((f==null?void 0:f.status)??"").toUpperCase()==="ACCEPTED",O=((f==null?void 0:f.status)??"").toUpperCase()==="PENDING",p=((f==null?void 0:f.status)??"").toUpperCase()==="INVITED";let j="View Group",a=()=>w(`/group/${t.id}`),S="gold",b=!1;return y?(j="Loading...",b=!0):G||L?(j="View Group",S="gold",a=()=>w(`/group/${t.id}`)):O?(j="Request Pending",b=!0,S="outline"):p?(j="View Invitation",S="navy",a=()=>w(`/group/${t.id}`)):(i||n)&&(t.visibility==="private"||t.joinMethod==="invite"?(j="Invitation Required",b=!0,S="outline"):t.joinMethod==="open"?(j="Join Group",a=()=>q(),S="navy"):t.joinMethod==="approval"&&(j="Request to Join",a=()=>q(),S="navy")),e.jsxs("div",{className:"bg-card rounded-xl shadow-soft overflow-hidden animate-fade-in",children:[e.jsxs("div",{className:"flex gap-4 p-4",children:[e.jsx("div",{className:"w-28 h-28 rounded-lg bg-navy shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("h3",{className:"font-display font-semibold text-foreground mb-2 truncate",children:t.displayName??"Untitled Group"}),e.jsxs("div",{className:"space-y-1 text-sm",children:[e.jsxs("p",{className:"text-muted-foreground",children:[e.jsx("span",{className:"font-medium",children:"Group Owner:"})," ",E()]}),e.jsxs("p",{className:"text-muted-foreground",children:[e.jsx("span",{className:"font-medium",children:"Updated:"})," ",t.updatedAt?new Date(t.updatedAt).toLocaleDateString():"â"]}),e.jsxs("p",{className:"text-muted-foreground text-xs",children:["Created"," ",t.createdAt?new Date(t.createdAt).toLocaleDateString():"â"]})]})]})]}),e.jsx("div",{className:"px-4 pb-4",children:e.jsx(P,{variant:S,className:"w-full",onClick:a,disabled:b||M,children:M?"Joining...":j})})]})}export{Ae 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.