PageSourceSearch

https://sense-ai.lovable.app/assets/LeadsRequiringAction-DR5bzzNh.js

js sense-ai.lovable.app collected 2026-10-03 03:44:07 UTC 12,370 bytes, 96 lines download raw bytes

1import{b as le,c as de,r as u,s as r,j as e,Z as q,o as me,$ as ue,T as he,a0 as pe,a1 as xe,C as I,e as M,S as v,f as T,G as _e,n as ge,z as fe,B as h,a2 as we,V as je,a3 as Ne,L as C,P as H,X as P,M as be,a4 as ve,a5 as Ce,a6 as Se,a7 as ye,a8 as Le,a9 as Ee}from"./index-BrgXcWsQ.js";const De=()=>{const{currentSubAccount:d,currentAgency:m,isAgencyView:p}=le(),{toast:S}=de(),[F,y]=u.useState(!0),[w,L]=u.useState([]),[j,z]=u.useState(!0),[O,E]=u.useState("default"),[i,f]=u.useState(null);u.useEffect(()=>{"Notification"in window&&E(Notification.permission)},[]),u.useEffect(()=>{(d!=null&&d.id||p&&(m!=null&&m.id))&&(k(),G())},[d,m,p]);const U=async()=>{if("Notification"in window&&Notification.permission==="default"){const a=await Notification.requestPermission();E(a)}},B=(a,c)=>{"Notification"in window&&Notification.permission==="granted"&&new Notification(a,{body:c,icon:"/favicon.ico",tag:"lead-notification"})},G=()=>{const a=r.channel("lead-score-changes").on("postgres_changes",{event:"*",schema:"public",table:"lead_score_history"},c=>{if(console.log("Lead score changed:",c),k(),c.new&&typeof c.new=="object"&&"new_score"in c.new){const n=c.new.new_score;n>=80&&B("🔥 Hot Lead Alert!",`Lead score jumped to ${n}. Immediate action required.`)}}).subscribe();return()=>{r.removeChannel(a)}},k=async()=>{try{y(!0);const a=new Date,c=new Date(a.getTime()-2*24*60*60*1e3),n=new Date(a.getTime()-7*24*60*60*1e3),Z=new Date(a.getTime()-24*60*60*1e3);let x=[];if(p&&(m!=null&&m.id)){const{data:s,error:t}=await r.from("sub_accounts").select("id").eq("agency_id",m.id);if(t){console.error("Error fetching sub-accounts:",t),S({title:"Error",description:"Failed to fetch sub-accounts",variant:"destructive"});return}x=(s==null?void 0:s.map(l=>l.id))||[]}else d!=null&&d.id&&(x=[d.id]);if(x.length===0){L([]);return}const{data:_}=await r.from("sub_account_users").select("sub_account_id, user_id, role").in("sub_account_id",x).eq("role","admin"),A=(_==null?void 0:_.map(s=>s.user_id))||[],{data:N}=A.length>0?await r.from("profiles").select("user_id, full_name, email, phone").in("user_id",A):{data:null},R=new Map;N==null||N.forEach(s=>{R.set(s.user_id,s)});const b=new Map;_==null||_.forEach(s=>{if(!b.has(s.sub_account_id)){const t=R.get(s.user_id);b.set(s.sub_account_id,{name:t==null?void 0:t.full_name,email:t==null?void 0:t.email,phone:t==null?void 0:t.phone,user_id:s.user_id})}});const{data:K}=await r.from("contacts").select(`
2          id,
3          name,
4          phone,
5          email,
6          lead_score,
7          last_score_update,
8          sub_account_id,
9          sub_accounts!inner(
10            id,
11            name
12          ),
13          communications(created_at)
14        `).in("sub_account_id",x).gte("lead_score",80).order("lead_score",{ascending:!1}).limit(10),Q=new Date(a.getTime()+2*24*60*60*1e3),{data:W}=await r.from("appointments").select(`
15          id,
16          title,
17          scheduled_at,
18          contact_id,
19          contacts!inner(
20            id, 
21            name, 
22            phone, 
23            email, 
24            lead_score,
25            sub_account_id,
26            sub_accounts!inner(
27              id,
28              name
29            )
30          )
31        `).eq("status","scheduled").gte("scheduled_at",a.toISOString()).lte("scheduled_at",Q.toISOString()).order("scheduled_at",{ascending:!0}).limit(10),{data:Y}=await r.from("opportunities").select(`
32          id,
33          name,
34          updated_at,
35          contact_id,
36          contacts!inner(
37            id, 
38            name, 
39            phone, 
40            email, 
41            lead_score,
42            sub_account_id,
43            sub_accounts!inner(
44              id,
45              name
46            )
47          ),
48          pipeline_stages(name)
49        `).eq("pipeline_stages.name","Revived").gte("updated_at",n.toISOString()).order("updated_at",{ascending:!1}).limit(10),{data:ee}=await r.from("lead_score_history").select(`
50          contact_id,
51          score_change,
52          reason,
53          created_at,
54          contacts!inner(
55            id, 
56            name, 
57            phone, 
58            email, 
59            lead_score,
60            sub_account_id,
61            sub_accounts!inner(
62              id,
63              name
64            )
65          )
66        `).gte("score_change",20).gte("created_at",c.toISOString()).order("score_change",{ascending:!1}).limit(10),{data:se}=await r.from("opportunities").select(`
67          id,
68          name,
69          contact_id,
70          contacts!inner(
71            id, 
72            name, 
73            phone, 
74            email, 
75            lead_score, 
76            last_score_update,
77            sub_account_id,
78            sub_accounts!inner(
79              id,
80              name
81            )
82          ),
83          pipeline_stages(name)
84        `).eq("pipeline_stages.name","Appointment Booked").lte("contacts.lead_score",50).limit(20),{data:ae}=await r.from("contacts").select(`
85          id, 
86          name, 
87          phone, 
88          email, 
89          lead_score, 
90          last_score_update,
91          sub_account_id,
92          sub_accounts!inner(
93            id,
94            name
95          )
96        `).in("sub_account_id",x).gte("lead_score",100).order("lead_score",{ascending:!1}).limit(10),g=s=>{var $;const t=s.sub_account_id,l=($=s.sub_accounts)==null?void 0:$.name,o=b.get(t);return{id:s.id,name:s.name,phone:s.phone,email:s.email,lead_score:s.lead_score||0,last_score_update:s.last_score_update,sub_account_id:t,sub_account_name:l,admin_name:o==null?void 0:o.name,admin_email:o==null?void 0:o.email,admin_phone:o==null?void 0:o.phone,admin_user_id:o==null?void 0:o.user_id}},te=(K||[]).filter(s=>{var l,o;const t=(o=(l=s.communications)==null?void 0:l[0])==null?void 0:o.created_at;return t?new Date(t)<Z:!0}).map(s=>({...g(s),reason:"No contact in 24 hours"})),ne=(W||[]).map(s=>({...g(s.contacts),stage:s.title,reason:`Appointment: ${new Date(s.scheduled_at).toLocaleDateString()}`})),ie=(Y||[]).map(s=>({...g(s.contacts),reason:"Revived from Cold"})),oe=(ee||[]).filter(s=>s.contacts).map(s=>({...g(s.contacts),reason:`+${s.score_change} points: ${s.reason}`})),ce=(se||[]).filter(s=>s.contacts).sort((s,t)=>{var l,o;return(((l=s.contacts)==null?void 0:l.lead_score)||0)-(((o=t.contacts)==null?void 0:o.lead_score)||0)}).slice(0,10).map(s=>{var t;return{...g(s.contacts),stage:(t=s.pipeline_stages)==null?void 0:t.name,reason:`Score dropped to ${s.contacts.lead_score}`}}),re=(ae||[]).map(s=>({...g(s),reason:`🚀 Score: ${s.lead_score}`}));L([{title:"🔥 Hot Leads - Need Follow-up",icon:e.jsx(q,{className:"w-4 h-4"}),color:"border-orange-500 bg-orange-500/10",leads:te,priority:1},{title:"📅 Appointments Next 48 Hours",icon:e.jsx(me,{className:"w-4 h-4"}),color:"border-blue-500 bg-blue-500/10",leads:ne,priority:2},{title:"💫 Just Revived",icon:e.jsx(ue,{className:"w-4 h-4"}),color:"border-purple-500 bg-purple-500/10",leads:ie,priority:3},{title:"📈 Score Jumped Significantly",icon:e.jsx(he,{className:"w-4 h-4"}),color:"border-green-500 bg-green-500/10",leads:oe,priority:4},{title:"⚠️ At Risk",icon:e.jsx(pe,{className:"w-4 h-4"}),color:"border-yellow-500 bg-yellow-500/10",leads:ce,priority:5},{title:"🚀 On Fire (Score 100+)",icon:e.jsx(xe,{className:"w-4 h-4"}),color:"border-red-500 bg-red-500/10",leads:re,priority:0}].filter(s=>s.leads.length>0).sort((s,t)=>s.priority-t.priority))}catch(a){console.error("Error fetching leads:",a),S({title:"Error",description:"Failed to load urgent leads",variant:"destructive"})}finally{y(!1)}},J=a=>{a&&(window.location.href=`tel:${a}`)},V=a=>{a&&(window.location.href=`mailto:${a}`)},X=a=>{a&&(window.location.href=`sms:${a}`)};if(F)return e.jsxs(I,{className:"border-primary/20",children:[e.jsxs(M,{children:[e.jsx(v,{className:"h-6 w-64"}),e.jsx(v,{className:"h-4 w-96"})]}),e.jsx(T,{children:e.jsx("div",{className:"space-y-4",children:[...Array(3)].map((a,c)=>e.jsx(v,{className:"h-20 w-full"},c))})})]});if(w.length===0)return null;const D=w.reduce((a,c)=>a+c.leads.length,0);return e.jsxs(e.Fragment,{children:[e.jsxs(I,{className:"border-primary/30 bg-gradient-to-br from-primary/5 to-primary/10",children:[e.jsx(M,{className:"cursor-pointer",onClick:()=>z(!j),children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(_e,{icon:e.jsx(q,{className:"w-5 h-5 text-white"})}),e.jsxs("div",{children:[e.jsx(ge,{className:"text-lg",children:"Leads Requiring Immediate Action"}),e.jsxs(fe,{children:[D," lead",D!==1?"s":""," need your attention now"]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[O!=="granted"&&e.jsx(h,{size:"sm",variant:"outline",onClick:a=>{a.stopPropagation(),U()},children:"Enable Notifications"}),j?e.jsx(we,{className:"w-5 h-5"}):e.jsx(je,{className:"w-5 h-5"})]})]})}),j&&e.jsx(T,{className:"space-y-6",children:w.map((a,c)=>e.jsxs("div",{className:Ne("rounded-lg border p-4",a.color),children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[a.icon,e.jsx("h3",{className:"font-semibold",children:a.title}),e.jsx(C,{variant:"secondary",children:a.leads.length})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3",children:[a.leads.slice(0,8).map(n=>e.jsxs("div",{className:"flex flex-col gap-2 p-2.5 bg-background/50 rounded-lg hover:bg-background/80 transition-colors border border-border/50",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[e.jsx("p",{className:"font-medium text-sm leading-tight",children:n.name}),e.jsx(C,{variant:"outline",className:"text-xs h-5",children:n.lead_score})]}),p&&n.sub_account_name&&e.jsx(C,{variant:"secondary",className:"text-xs h-5 w-fit",children:n.sub_account_name}),e.jsx("p",{className:"text-xs text-muted-foreground line-clamp-2",children:n.reason}),p&&e.jsx("p",{className:"text-xs text-muted-foreground truncate",children:n.admin_name||"No admin"})]}),e.jsxs("div",{className:"flex items-center gap-1 flex-wrap pt-1",children:[n.phone&&e.jsxs(h,{size:"sm",variant:"ghost",onClick:()=>J(n.phone),title:"Call",className:"h-7 px-2 text-xs",children:[e.jsx(H,{className:"w-3 h-3 mr-1"}),"Call"]}),n.email&&e.jsxs(h,{size:"sm",variant:"ghost",onClick:()=>V(n.email),title:"Email",className:"h-7 px-2 text-xs",children:[e.jsx(P,{className:"w-3 h-3 mr-1"}),"Email"]}),n.phone&&e.jsxs(h,{size:"sm",variant:"ghost",onClick:()=>X(n.phone),title:"SMS",className:"h-7 px-2 text-xs",children:[e.jsx(be,{className:"w-3 h-3 mr-1"}),"SMS"]}),p&&(n.admin_name||n.admin_email)&&e.jsxs(h,{size:"sm",variant:"ghost",onClick:()=>f({name:n.admin_name,email:n.admin_email,phone:n.admin_phone}),title:"Contact Admin",className:"h-7 px-2 text-xs",children:[e.jsx(ve,{className:"w-3 h-3 mr-1"}),"Admin"]})]})]},n.id)),a.leads.length>8&&e.jsxs("p",{className:"text-xs text-muted-foreground text-center pt-2 col-span-full",children:["+",a.leads.length-8," more leads in this category"]})]})]},c))})]}),e.jsx(Ce,{open:!!i,onOpenChange:()=>f(null),children:e.jsxs(Se,{children:[e.jsxs(ye,{children:[e.jsx(Le,{children:"Contact Sub-Account Admin"}),e.jsx(Ee,{children:"Get in touch with the admin responsible for this lead"})]}),e.jsxs("div",{className:"space-y-4",children:[(i==null?void 0:i.name)&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Name"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:i.name})]}),(i==null?void 0:i.email)&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Email"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:i.email})]}),(i==null?void 0:i.phone)&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Phone"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:i.phone})]}),e.jsxs("div",{className:"flex gap-2 pt-4",children:[(i==null?void 0:i.email)&&e.jsxs(h,{onClick:()=>{window.location.href=`mailto:${i.email}`,f(null)},className:"flex-1",children:[e.jsx(P,{className:"h-4 w-4 mr-2"}),"Email Admin"]}),(i==null?void 0:i.phone)&&e.jsxs(h,{onClick:()=>{window.location.href=`tel:${i.phone}`,f(null)},className:"flex-1",variant:"outline",children:[e.jsx(H,{className:"h-4 w-4 mr-2"}),"Call Admin"]})]})]})]})})]})};export{De as LeadsRequiringAction};

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.