1import{j as e}from"./vendor-framer-e_lHCn70.js";import{r as n,L as K}from"./vendor-react-KJNI7MOv.js";import{u as oe}from"./useAdminAuthGuard-VEOdfgr6.js";import{d as ce,s as _,u as d,L as k,B as c,ac as de}from"./index-CIR6ZFuo.js";import{C as m,d as x,a as U,b as $}from"./card-TqmYSDqK.js";import{B as N}from"./badge-DUmO4yhr.js";import{A as S,a as A,b as C}from"./alert-Og1lKi-8.js";import{A as me}from"./arrow-left-AE5oGNQ4.js";import{R as xe}from"./refresh-cw-DnKcZzoP.js";import{T as he}from"./triangle-alert-BVx1w2wU.js";import{B as V}from"./bell-off-C6PDw-yu.js";import{C as W}from"./circle-alert-DHyIN4z5.js";import{ResponsiveContainer as fe,BarChart as ue,CartesianGrid as ge,XAxis as pe,YAxis as je,Tooltip as we,Legend as ke,Bar as Y}from"./vendor-charts-BDAdqkMp.js";import{S as Ne}from"./send-BZygGeEg.js";import{C as ve}from"./circle-check-DwXrdmPW.js";import{a as q,f as T}from"./vendor-date-Cl6Zci4u.js";import"./vendor-radix-core-Dl2pI1uY.js";import"./vendor-utils-MBSoW7Mz.js";import"./vendor-query-B0dKBn0F.js";import"./vendor-supabase-DEDxcdm9.js";import"./vendor-radix-extended-hypInIJy.js";/** 2 * @license lucide-react v0.462.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const X=ce("Beaker",[["path",{d:"M4.5 3h15",key:"c7n0jr"}],["path",{d:"M6 3v16a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V3",key:"m1uhx7"}],["path",{d:"M6 14h12",key:"4cwo0f"}]]),D="vetano:google-ads-leads:alert-dismissed-until",R=2,Ue=()=>{const[v,J]=n.useState(!1);oe({onAuthenticated:()=>J(!0)});const[i,Q]=n.useState([]),[Z,z]=n.useState(!0),[L,B]=n.useState(null),[f,E]=n.useState(!1),[F,O]=n.useState(()=>{const s=typeof window<"u"?window.localStorage.getItem(D):null;return s&&Number(s)||0}),G=n.useRef({}),u=n.useCallback(async()=>{z(!0);try{const{data:s,error:t}=await _.from("employer_leads").select("id, name, email, company, is_test, lead_score, engagement_level, slack_status, slack_error, slack_sent_at, slack_channel, utm_campaign, gclid, created_at").eq("source_page","google-ads").order("created_at",{ascending:!1}).limit(100);if(t)throw t;Q(s??[])}catch(s){console.error(s),d.error("Failed to load Google Ads leads")}finally{z(!1)}},[]);n.useEffect(()=>
6{document.title="Google Ads Leads. Vetano Admin",v&&u()},[v,u]);const ee=async s=>{B(s);try{const{data:t,error:a}=await _.functions.invoke("resend-google-lead-slack",{body:{lead_id:s}});if(a){const l=a.context;let h=a.message||"Resend failed";if(l?.json)try{const P=await l.json();P?.error&&(h=P.error)}catch{}throw new Error(h)}const r=t;if(!r?.ok)throw new Error(r?.error??"Resend failed");d.success("Posted to #google-leads"),await u()}catch(t){console.error(t),d.error(t instanceof Error?t.message:"Resend failed")}finally{B(null)}},M=async()=>{E(!0);try{const{data:s,error:t}=await _.functions.invoke("test-slack-delivery",{body:{}});if(t){const r=t.context;let l=t.message||"Test failed";if(r?.json)try{const h=await r.json();h?.error&&(l=h.error)}catch{}throw new Error(l)}const a=s;if(!a?.ok)throw new Error(a?.error??"Test failed");d.success(`Test message delivered to ${a.channel??"#google-leads"}`)}catch(s){console.error(s),d.error(s instanceof Error?`Slack test failed: ${s.message}`:"Slack test failed")}finally{E(!1)}},se=s=>{const t=G.current[s];t&&(t.scrollIntoView({behavior:"smooth",block:"center"}),t.classList.add("ring-2","ring-destructive"),setTimeout(()=>t.classList.remove("ring-2","ring-destructive"),2e3))},te=()=>{const s=Date.now()+R*60*60*1e3;window.localStorage.setItem(D,String(s)),O(s),d.message(`Alert snoozed for ${R}h`)},ae=s=>s.slack_status==="sent"?e.jsxs(N,{className:"bg-green-500/15 text-green-500 border-green-500/30",children:[e.jsx(ve,{className:"w-3 h-3 mr-1"})," Sent"]}):s.slack_status==="failed"?e.jsxs(N,{variant:"destructive",children:[e.jsx(W,{className:"w-3 h-3 mr-1"})," Failed"]}):e.jsx(N,{variant:"secondary",children:"Pending"}),g=Date.now(),re=g-24*60*60*1e3,b=i.filter(s=>new Date(s.created_at).getTime()>=re),le=b.filter(s=>s.slack_status==="sent").length,o=b.filter(s=>s.slack_status==="failed").length,p=le+o,H=p>0?o/p:0,y=o>=3||o>=2&&H>=.3,j=b.filter(s=>s.slack_status==="failed"),I=F>g,ne=y&&!I,ie=n.useMemo(()=>{const s=[],t=new Date(g-828e5);t.setMinutes(0,0,0);for(let a=0;a<24;a++){const r=new Date(t.getTime()+a*60*60*1e3);s.push({hour:r.getTime(),label:q(r,"HH:00"),attempts:0,failed:0})}for(const a of i){if(a.slack_status!=="sent"&&a.slack_status!=="failed")continue;const r=new Date(a.created_at).getTime();if(r<s[0].hour)continue;const l=Math.floor((r-s[0].hour)/(60*60*1e3));l<0||l>=s.length||(s[l].attempts+=1,a.slack_status==="failed"&&(s[l].failed+=1))}return s},[i,g]);if(!v||Z)return e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-background",children:e.jsx(k,{className:"w-5 h-5 animate-spin text-muted-foreground"})});const w={total:i.length,sent:i.filter(s=>s.slack_status==="sent").length,failed:i.filter(s=>s.slack_status==="failed").length,tests:i.filter(s=>s.is_test).length};return e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx("div",{className:"border-b border-border/50 bg-card/30 backdrop-blur-sm",children:e.jsxs("div",{className:"container mx-auto px-6 py-4 flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx(c,{variant:"ghost",size:"sm",asChild:!0,children:e.jsxs(K,{to:"/admin/dashboard",children:[e.jsx(me,{className:"w-4 h-4 mr-1"}),"Dashboard"]})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-bold text-foreground",children:"Google Ads Leads"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Routing to ",e.jsx("code",{className:"font-mono",children:"#google-leads"})," via Slack connector"]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(c,{variant:"outline",size:"sm",onClick:M,disabled:f,children:[f?e.jsx(k,{className:"w-4 h-4 mr-1 animate-spin"}):e.jsx(X,{className:"w-4 h-4 mr-1"}),"Test Slack delivery"]}),e.jsxs(c,{variant:"outline",size:"sm",onClick:u,children:[e.jsx(xe,{className:"w-4 h-4 mr-1"})," Refresh"]})]})]})}),e.jsxs("main",{className:"container mx-auto px-6 py-8 space-y-6",children:[ne&&e.jsxs(S,{variant:"destructive",children:[e.jsx(he,{className:"w-4 h-4"}),e.jsx(A,{children:"Slack delivery failures detected"}),e.jsxs(C,{className:"flex flex-col gap-3",children:[e.jsxs("span",{children:[o," failed delivery",o===1?"":"ies"," in the last 24h",p>0&&e.jsxs(e.Fragment,{children:[" (",Math.round(H*100),"% failure rate across ",p," attempts)"]}),"."]}),j.length>0&&e.jsxs("div",{className:"flex flex-wrap gap-2",children:[j.slice(0,5).map(s=>e.jsxs(c,{size:"sm",variant:"outline",className:"h-7 text-xs",onClick:()=>se(s.id),children:[s.company||s.email,e.jsx(de,{className:"w-3 h-3 ml-1"})]},s.id)),j.length>5&&e.jsxs("span",{className:"text-xs opacity-80 self-center",children:["+",j.length-5," more below"]})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs(c,{size:"sm",variant:"secondary",onClick:te,children:[e.jsx(V,{className:"w-3 h-3 mr-1"}),"Snooze ",R,"h"]}),e.jsxs(c,{size:"sm",variant:"secondary",onClick:M,disabled:f,children:[f?e.jsx(k,{className:"w-3 h-3 mr-1 animate-spin"}):e.jsx(X,{className:"w-3 h-3 mr-1"}),"Run Slack test"]})]})]})]}),y&&I&&e.jsxs(S,{children:[e.jsx(V,{className:"w-4 h-4"}),e.jsx(A,{children:"Failure alert snoozed"}),e.jsxs(C,{className:"flex items-center justify-between gap-2 flex-wrap",children:[e.jsxs("span",{children:["Active failure spike, banner re-appears ",T(new Date(F),{addSuffix:!0}),"."]}),e.jsx(c,{size:"sm",variant:"ghost",onClick:()=>{window.localStorage.removeItem(D),O(0)},children:"Un-snooze"})]})]}),!y&&o>0&&e.jsxs(S,{children:[e.jsx(W,{className:"w-4 h-4"}),e.jsxs(A,{children:[o," Slack failure",o===1?"":"s"," in last 24h"]}),e.jsx(C,{children:"Below alert threshold, resend manually from the affected leads if needed."})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsx(m,{children:e.jsxs(x,{className:"pt-6",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Total leads"}),e.jsx("p",{className:"text-2xl font-bold",children:w.total})]})}),e.jsx(m,{children:e.jsxs(x,{className:"pt-6",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Slack sent"}),e.jsx("p",{className:"text-2xl font-bold text-green-500",children:w.sent})]})}),e.jsx(m,{children:e.jsxs(x,{className:"pt-6",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Slack failed"}),e.jsx("p",{className:"text-2xl font-bold text-destructive",children:w.failed})]})}),e.jsx(m,{children:e.jsxs(x,{className:"pt-6",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Test leads"}),e.jsx("p",{className:"text-2xl font-bold text-amber-500",children:w.tests})]})})]}),e.jsxs(m,{children:[e.jsx(U,{children:e.jsx($,{className:"text-base",children:"Slack delivery, last 24h"})}),e.jsx(x,{children:e.jsx("div",{className:"h-48 w-full",children:e.jsx(fe,{width:"100%",height:"100%",children:e.jsxs(ue,{data:ie,margin:{top:8,right:8,left:-16,bottom:0},children:[e.jsx(ge,{strokeDasharray:"3 3",stroke:"hsl(var(--border))",opacity:.4}),e.jsx(pe,{dataKey:"label",tick:{fontSize:10,fill:"hsl(var(--muted-foreground))"},interval:2}),e.jsx(je,{allowDecimals:!1,tick:{fontSize:10,fill:"hsl(var(--muted-foreground))"}}
6),e.jsx(we,{contentStyle:{background:"hsl(var(--popover))",border:"1px solid hsl(var(--border))",borderRadius:8,fontSize:12},labelStyle:{color:"hsl(var(--foreground))"}}),e.jsx(ke,{wrapperStyle:{fontSize:11}}),e.jsx(Y,{dataKey:"attempts",name:"Attempts",fill:"hsl(var(--muted-foreground))",radius:[2,2,0,0]}),e.jsx(Y,{dataKey:"failed",name:"Failed",fill:"hsl(var(--destructive))",radius:[2,2,0,0]})]})})})})]}),e.jsxs(m,{children:[e.jsx(U,{children:e.jsx($,{children:"Recent leads (last 100)"})}),e.jsx(x,{children:i.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No Google Ads leads yet."}):e.jsx("div",{className:"space-y-3",children:i.map(s=>e.jsxs("div",{ref:t=>{G.current[s.id]=t},className:"flex flex-wrap items-start gap-4 p-4 rounded-lg border border-border/60 bg-card/30 transition-shadow",children:[e.jsxs("div",{className:"flex-1 min-w-[240px]",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("p",{className:"font-semibold text-foreground",children:s.company}),s.is_test&&e.jsx(N,{className:"bg-amber-500/15 text-amber-500 border-amber-500/30",children:"𧪠TEST"}),ae(s)]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[s.name," · ",s.email]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Score ",s.lead_score??0,"/100 · ",q(new Date(s.created_at),"PPp")," (",T(new Date(s.created_at),{addSuffix:!0}),")"]}),(s.utm_campaign||s.gclid)&&e.jsxs("p",{className:"text-[11px] text-muted-foreground mt-1 font-mono break-all",children:[s.utm_campaign&&e.jsxs(e.Fragment,{children:["campaign: ",s.utm_campaign," · "]}),s.gclid&&e.jsxs(e.Fragment,{children:["gclid: ",s.gclid.slice(0,24),"â¦"]})]}),s.slack_status==="sent"&&s.slack_sent_at&&e.jsxs("p",{className:"text-[11px] text-green-500 mt-1",children:["Posted to ",s.slack_channel," ",T(new Date(s.slack_sent_at),{addSuffix:!0})]}),s.slack_status==="failed"&&s.slack_error&&e.jsxs("p",{className:"text-[11px] text-destructive mt-1 font-mono break-all",children:["Error: ",s.slack_error]})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs(c,{size:"sm",variant:"outline",onClick:()=>ee(s.id),disabled:L===s.id,children:[L===s.id?e.jsx(k,{className:"w-3 h-3 mr-1 animate-spin"}):e.jsx(Ne,{className:"w-3 h-3 mr-1"}),"Resend Slack"]}),e.jsx(c,{size:"sm",variant:"ghost",asChild:!0,children:e.jsx(K,{to:`/admin/employer-leads/${s.id}`,children:"Details"})})]})]},s.id))})})]})]})]})};export{Ue 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.