PageSourceSearch

https://fasttrackapp.biz/assets/AdminMessagesPage-ad03e4bc.js

js fasttrackapp.biz collected 2026-10-02 16:01:19 UTC 11,148 bytes, 1 lines download raw bytes

1import{r,j as a,L as I}from"./react-vendor-2456d756.js";import{U as C}from"./UserAvatar-1e3e8539.js";import{a as N,S as A,E as T,B as $,P as G}from"./AdminShared-23669f86.js";import{D as Y}from"./DeletedBadge-c9f9b485.js";import{A as L}from"./AppVersionBadge-6f11298e.js";import{e as g,h as P,bB as Z}from"./index-109ef59a.js";import{aH as J,o as W,bO as K,A as Q,H as X,aJ as ee,aS as ae,am as te}from"./lucide-a6f07388.js";import"./NameBadges-da81af1c.js";import"./dynamicBadgeIcons-d6336a9f.js";import"./utils-e0408a98.js";import"./adminEntityUrl-385ecbe6.js";import"./sentry-2cabdd57.js";import"./supabase-e274f090.js";(function(){try{var t=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};t.SENTRY_RELEASE={id:"84e0629e1e011ac8c99cdc99289c0cc630b75609"};var i=new t.Error().stack;i&&(t._sentryDebugIds=t._sentryDebugIds||{},t._sentryDebugIds[i]="e6300141-6990-4146-a4ea-8e3810a16d10",t._sentryDebugIdIdentifier="sentry-dbid-e6300141-6990-4146-a4ea-8e3810a16d10")}catch{}})();const se=20;async function re(){const t=new Date,i=new Date(t.getFullYear(),t.getMonth(),t.getDate()).toISOString(),x=new Date(t.getTime()-7*24*60*60*1e3).toISOString(),[{count:d},{count:f},{count:p},{count:m}]=await Promise.all([g.from("conversations").select("*",{count:"exact",head:!0}),g.from("messages").select("*",{count:"exact",head:!0}),g.from("messages").select("*",{count:"exact",head:!0}).gte("created_at",i),g.from("conversations").select("*",{count:"exact",head:!0}).gte("last_message_at",x)]);return{totalConversations:d||0,totalMessages:f||0,messagesToday:p||0,activeConversations:m||0}}async function ie(t=0,i=se,x=""){let d=null;if(x.trim()){const s=x.replace(/[,().%_\\]/g,"");if(!s.trim())return{conversations:[],total:0};const j=`%${s}%`,{data:c,error:v}=await g.from("conversation_participants").select("conversation_id, profile:profiles!conversation_participants_user_id_fkey_profiles(display_name, username)").or(`profile.display_name.ilike.${j},profile.username.ilike.${j}`).not("profile","is",null);if(v)throw v;if(d=[...new Set((c||[]).map(b=>b.conversation_id))],d.length===0)return{conversations:[],total:0}}let f=g.from("conversations").select("*",{count:"exact"}).order("last_message_at",{ascending:!1,nullsFirst:!1}).range(t,t+i-1);d&&(f=f.in("id",d));const{data:p,count:m,error:l}=await f;if(l)throw l;if(!p||p.length===0)return{conversations:[],total:m||0};const u=p.map(s=>s.id),{data:S,error:y}=await g.from("conversation_participants").select("conversation_id, user_id, role, joined_at, left_at, profile:profiles!conversation_participants_user_id_fkey_profiles(id, display_name, username, avatar_url, is_verified, app_version, last_active_at, last_login_at)").in("conversation_id",u);if(y)throw y;const _={};return(S||[]).forEach(s=>{_[s.conversation_id]||(_[s.conversation_id]=[]),_[s.conversation_id].push(s)}),{conversations:p.map(s=>({...s,participants:_[s.id]||[]})),total:m||0}}async function ne(t,i=0,x=50){const{data:d,error:f}=await g.from("messages").select("id, conversation_id, sender_id, content, image_url, is_deleted, created_at, updated_at, reply_to_id, sender:profiles!messages_sender_id_fkey_profiles(id, display_name, username, avatar_url, is_verified, app_version, last_active_at, last_login_at)").eq("conversation_id",t).order("created_at",{ascending:!0}).range(i,i+x-1);if(f)throw f;const p=(d||[]).map(l=>l.id);let m={};if(p.length>0){const{data:l}=await g.from("hidden_messages").select("message_id, user_id, profile:profiles!hidden_messages_user_id_fkey(display_name, username)").in("message_id",p);(l||[]).forEach(u=>{m[u.message_id]||(m[u.message_id]=[]),m[u.message_id].push(u.profile?.display_name||u.profile?.username||"Unknown")})}return(d||[]).map(l=>({...l,hidden_by:m[l.id]||[]}))}async function oe(t){const{error:i}=await g.from("messages").update({is_deleted:!0,updated_at:new Date().toISOString()}).eq("id",t);if(i)throw i}const k=20,je=()=>{const[t,i]=r.useState(null),[x,d]=r.useState([]),[f,p]=r.useState(0),[m,l]=r.useState(!0),[u,S]=r.useState(""),[y,_]=r.useState(""),[s,j]=r.useState(0),[c,v]=r.useState(null),[b,w]=r.useState([]),[z,D]=r.useState(!1),[B,F]=r.useState(null);r.useEffect(()=>{re().then(i).catch(e=>console.error("Stats load error:",e))},[]);const E=r.useCallback(async()=>
1{l(!0);try{const{conversations:e,total:n}=await ie(s*k,k,u);d(e),p(n)}catch(e){console.error("Conversations load error:",e)}l(!1)},[s,u]);r.useEffect(()=>{E()},[E]);const H=r.useCallback(async e=>{D(!0);try{const n=await ne(e);w(n)}catch(n){console.error("Messages load error:",n)}D(!1)},[]),q=e=>{v(e),H(e.id)},U=()=>{v(null),w([])},O=e=>{e.preventDefault(),S(y),j(0),v(null),w([])},R=async e=>{if(confirm("Delete this message? It will be soft-deleted and hidden from users.")){F(e);try{await oe(e),w(n=>n.filter(h=>h.id!==e))}catch{alert("Failed to delete message")}F(null)}},V=Math.ceil(f/k),M=e=>{if(e.name)return e.name;const n=(e.participants||[]).filter(o=>!o.left_at).map(o=>o.profile?.display_name||o.profile?.username||"Unknown").slice(0,3);if(n.length===0)return"Empty conversation";const h=n.join(", ");return(e.participants||[]).filter(o=>!o.left_at).length>3?`${h} +${(e.participants||[]).filter(o=>!o.left_at).length-3}`:h};return a.jsxs("div",{children:[t&&a.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6",children:[a.jsx(N,{icon:J,label:"Conversations",value:t.totalConversations}),a.jsx(N,{icon:W,label:"Total Messages",value:t.totalMessages,color:"#2DD4BF"}),a.jsx(N,{icon:K,label:"Messages Today",value:t.messagesToday}),a.jsx(N,{icon:Q,label:"Active This Week",value:t.activeConversations,color:"#2DD4BF"})]}),a.jsxs("div",{className:"flex gap-4",style:{minHeight:"500px"},children:[a.jsxs("div",{className:`${c?"hidden lg:flex":"flex"} flex-col w-full lg:w-[380px] lg:min-w-[380px] bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl overflow-hidden`,children:[a.jsx("form",{onSubmit:O,className:"p-3 border-b border-[#2a2a2a]",children:a.jsxs("div",{className:"relative",children:[a.jsx(X,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"}),a.jsx("input",{type:"text",value:y,onChange:e=>_(e.target.value),placeholder:"Search by participant name...",className:"w-full bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg pl-9 pr-3 py-2 text-sm text-gray-300 placeholder:text-gray-600 focus:outline-none focus:border-[#00FF7F]/40"})]})}),a.jsx("div",{className:"flex-1 overflow-y-auto",style:{maxHeight:"520px"},children:m?a.jsx(A,{}):x.length===0?a.jsx(T,{text:"No conversations found"}):a.jsx("div",{children:x.map(e=>{const n=c?.id===e.id,h=(e.participants||[]).filter(o=>!o.left_at);return a.jsxs("button",{onClick:()=>q(e),className:`w-full text-left p-3 border-b border-[#2a2a2a] transition-colors hover:bg-[#0a0a0a] ${n?"bg-[#0a0a0a] border-l-2 border-l-[#00FF7F]":""}`,children:[a.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[a.jsx("div",{className:"flex -space-x-2",children:h.slice(0,3).map(o=>a.jsx("div",{className:"w-6 h-6",children:a.jsx(C,{profile:o.profile,size:"xs"})},o.user_id))}),a.jsx("span",{className:"text-white text-sm font-medium truncate flex-1",children:M(e)}),e.type&&a.jsx($,{children:e.type})]}),e.last_message_text&&a.jsx("p",{className:"text-gray-500 text-xs truncate mb-1",children:e.last_message_text}),a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsxs("span",{className:"text-gray-600 text-[10px]",children:[h.length," participant",h.length!==1?"s":""]}),a.jsx("span",{className:"text-gray-600 text-[10px]",children:e.last_message_at?P(e.last_message_at):P(e.created_at)})]})]},e.id)})})}),a.jsx(G,{page:s+1,totalPages:V,onPageChange:e=>j(e-1)})]}),a.jsx("div",{className:`${c?"flex":"hidden lg:flex"} flex-col flex-1 bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl overflow-hidden`,children:c?a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"flex items-center gap-3 p-4 border-b border-[#2a2a2a]",children:[a.jsx("button",{onClick:U,className:"lg:hidden p-1 text-gray-400 hover:text-white transition-colors",children:a.jsx(ee,{size:18})}),a.jsx("div",{className:"flex -space-x-2",children:(c.participants||[]).filter(e=>!e.left_at).slice(0,4).map(e=>a.jsx("div",{className:"w-7 h-7",children:a.jsx(C,{profile:e.profile,size:"xs"})},e.user_id))}),a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsx("h3",{className:"text-white text-sm font-medium truncate",children:M(c)}),a.jsxs("p",{className:"text-gray-500 text-xs",children:[(c.participants||[]).filter(e=>!e.left_at).length," participants",c.type?` · ${c.type}`:""]})]})]}),a.jsx("div",{className:"flex flex-wrap gap-2 px-4 py-2 border-b border-[#2a2a2a]",children:(c.participants||[]).filter(e=>!e.left_at).map(e=>a.jsxs("span",{className:"inline-flex items-center gap-1",children:[a.jsxs(I,{to:`/admin/users/${e.user_id}`,className:"text-[11px] text-gray-400 hover:text-[#00FF7F] transition-colors",children:["@",e.profile?.username||e.profile?.display_name||"unknown"]}),e.profile&&a.jsx(L,{version:e.profile.app_version})]},e.user_id))}),a.jsx("div",{className:"flex-1 overflow-y-auto p-4 space-y-3",style:{maxHeight:"440px"},children:z?a.jsx(A,{}):b.length===0?a.jsx(T,{text:"No messages in this conversation"}):b.map(e=>a.jsxs("div",{className:"group flex items-start gap-3",children:[a.jsx("div",{className:"w-7 h-7 flex-shrink-0 mt-0.5",children:a.jsx(C,{profile:e.sender,size:"xs"})}),a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsxs("div",{className:"flex items-center gap-2 mb-0.5 flex-wrap",children:[a.jsx(I,{to:`/admin/users/${e.sender_id}`,className:"text-white text-xs font-medium hover:text-[#00FF7F] transition-colors",children:e.sender?.display_name||e.sender?.username||"Unknown"}),e.sender&&a.jsx(L,{version:e.sender.app_version}),e.sender?.is_verified&&a.jsx($,{color:"#00FF7F",children:"Verified"}),a.jsx("span",{className:"text-gray-600 text-[10px]",children:Z(e.created_at)})]}),e.content&&a.jsx("p",{className:"text-gray-300 text-sm break-words",children:e.content}),e.image_url&&a.jsxs("div",{className:"flex items-center gap-1 mt-1",children:[a.jsx(ae,{size:12,className:"text-gray-500"}),a.jsx("a",{href:e.image_url,target:"_blank",rel:"noopener noreferrer",className:"text-[#00FF7F] text-xs hover:underline",children:"View image"})]}),e.hidden_by?.length>0&&a.jsx("div",{className:"flex items-center gap-1 mt-1",children:a.jsxs("span",{className:"text-[10px] px-1.5 py-0.5 rounded bg-yellow-500/10 text-yellow-400 border border-yellow-500/20",children:["Hidden by ",e.hidden_by.join(", ")
1]})}),e.is_deleted&&a.jsx("div",{className:"flex items-center gap-1 mt-1",children:a.jsx(Y,{when:e.updated_at})})]}),a.jsx("button",{onClick:()=>R(e.id),disabled:B===e.id,className:"opacity-0 group-hover:opacity-100 flex-shrink-0 p-1.5 rounded-lg text-gray-600 hover:text-accent2 hover:bg-accent2/10 transition-all disabled:opacity-50",title:"Delete message",children:a.jsx(te,{size:13})})]},e.id))})]}):a.jsx("div",{className:"flex-1 flex items-center justify-center",children:a.jsx("p",{className:"text-gray-600 text-sm",children:"Select a conversation to view messages"})})})]})]})};export{je 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.