PageSourceSearch

https://www.reelyapp.ai/assets/EmailMetricsPage-DSkh1zJK.js

js reelyapp.ai collected 2026-10-05 15:18:20 UTC 6,437 bytes, 1 lines download raw bytes

1import{j as e}from"./motion-CfSk9feW.js";import{r as x}from"./react-vendor-C6lPD-9k.js";import{a as q,B as R,b as E,am as C,au as L,M,s as S}from"./index-BYNfNKW0.js";import{I as B}from"./AdminUI-4yUKSY-L.js";import{S as A}from"./send-CSucnf12.js";import{M as P}from"./mouse-pointer-click-CmPePvdE.js";import"./charts-RdecN8yt.js";import"./query-GhzdTI6D.js";import"./supabase-D2XPrbcR.js";import"./i18n-D-f7nUbg.js";import"./info-CyrYbJLT.js";const k=30;function J(){const{toast:f}=q(),[o,g]=x.useState([]),[n,c]=x.useState({sent:0,opens:0,clicks:0,failed:0}),[j,b]=x.useState(!0),v=async()=>{b(!0);try{const a=new Date(Date.now()-k*24*60*60*1e3).toISOString(),[{data:m,error:N},{data:y,error:_}]=await Promise.all([S.from("email_send_log").select("template_name,status,message_id,created_at").gte("created_at",a).limit(5e4),S.from("email_events").select("template_name,event_type,message_id,occurred_at").gte("occurred_at",a).limit(1e5)]);if(N)throw N;if(_)throw _;const i=new Map,w=t=>(i.has(t)||i.set(t,{template:t,sent:0,opens:0,clicks:0,unique_opens:0,unique_clicks:0,failed:0}),i.get(t)),u=new Map,p=new Map;(m||[]).forEach(t=>{const s=w(t.template_name||"unknown");t.status==="sent"?s.sent++:(t.status==="failed"||t.status==="dlq")&&s.failed++}),(y||[]).forEach(t=>{const s=t.template_name||"unknown",l=w(s);t.event_type==="open"?(l.opens++,u.has(s)||u.set(s,new Set),u.get(s).add(t.message_id)):t.event_type==="click"&&(l.clicks++,p.has(s)||p.set(s,new Set),p.get(s).add(t.message_id))}
1),i.forEach(t=>{var s,l;t.unique_opens=((s=u.get(t.template))==null?void 0:s.size)??0,t.unique_clicks=((l=p.get(t.template))==null?void 0:l.size)??0});const r=Array.from(i.values()).sort((t,s)=>s.sent-t.sent);g(r),c({sent:r.reduce((t,s)=>t+s.sent,0),opens:r.reduce((t,s)=>t+s.opens,0),clicks:r.reduce((t,s)=>t+s.clicks,0),failed:r.reduce((t,s)=>t+s.failed,0)})}catch(a){f({title:"Erro",description:(a==null?void 0:a.message)||String(a),variant:"destructive"})}finally{b(!1)}};x.useEffect(()=>{v()},[]);const d=(a,m)=>m>0?`${(a/m*100).toFixed(1)}%`:"—";return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-foreground",children:"Métricas de e-mail"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Últimos ",k," dias · aberturas e cliques por campanha"]})]}),e.jsxs(R,{variant:"outline",size:"sm",onClick:v,disabled:j,className:"gap-2",children:[j?e.jsx(E,{className:"h-4 w-4 animate-spin"}):e.jsx(C,{className:"h-4 w-4"}),"Atualizar"]})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsx(h,{icon:A,label:"Enviados",value:n.sent.toLocaleString("pt-BR"),info:"Total de e-mails com status = sent em email_send_log nos últimos 30 dias. Cada disparo do email-lifecycle-cron ou template transacional registra uma linha aqui."}),e.jsx(h,{icon:L,label:"Aberturas",value:n.opens.toLocaleString("pt-BR"),sub:`Open rate ${d(n.opens,n.sent)}`,info:"Eventos event_type = open em email_events. Detectados via pixel transparente embutido. Open rate = aberturas ÷ enviados. Apple Mail Privacy pode inflar/distorcer."}),e.jsx(h,{icon:P,label:"Cliques",value:n.clicks.toLocaleString("pt-BR"),sub:`CTR ${d(n.clicks,n.sent)}`,info:"Eventos event_type = click em email_events. Rastreados via redirect — refletem intenção real. CTR = cliques ÷ enviados."}),e.jsx(h,{icon:M,label:"Falhas",value:n.failed.toLocaleString("pt-BR"),info:"Linhas com status = failed ou dlq em email_send_log. Indica bounces hard, rejeição do Resend ou erros na função transacional."})]}),e.jsx("div",{className:"rounded-xl border border-border bg-card overflow-hidden",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{className:"bg-muted/30 text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left p-3 font-semibold",children:"Campanha"}),e.jsx("th",{className:"text-right p-3 font-semibold",children:"Enviados"}),e.jsx("th",{className:"text-right p-3 font-semibold",children:"Aberturas (únicas)"}),e.jsx("th",{className:"text-right p-3 font-semibold",children:"Open rate"}),e.jsx("th",{className:"text-right p-3 font-semibold",children:"Cliques (únicos)"}),e.jsx("th",{className:"text-right p-3 font-semibold",children:"CTR"}),e.jsx("th",{className:"text-right p-3 font-semibold",children:"Falhas"})]})}),e.jsxs("tbody",{children:[o.map(a=>e.jsxs("tr",{className:"border-t border-border hover:bg-muted/20",children:[e.jsx("td",{className:"p-3 font-medium text-foreground",children:a.template}),e.jsx("td",{className:"p-3 text-right tabular-nums",children:a.sent.toLocaleString("pt-BR")}),e.jsxs("td",{className:"p-3 text-right tabular-nums",children:[a.opens.toLocaleString("pt-BR")," ",e.jsxs("span",{className:"text-muted-foreground",children:["(",a.unique_opens,")"]})]}),e.jsx("td",{className:"p-3 text-right tabular-nums",children:d(a.unique_opens,a.sent)}),e.jsxs("td",{className:"p-3 text-right tabular-nums",children:[a.clicks.toLocaleString("pt-BR")," ",e.jsxs("span",{className:"text-muted-foreground",children:["(",a.unique_clicks,")"]})]}),e.jsx("td",{className:"p-3 text-right tabular-nums",children:d(a.unique_clicks,a.sent)}),e.jsx("td",{className:"p-3 text-right tabular-nums text-muted-foreground",children:a.failed.toLocaleString("pt-BR")})]},a.template)),o.length===0&&!j&&e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:"p-6 text-center text-muted-foreground",children:"Nenhum e-mail enviado no período."})})]})]})}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Aberturas usam pixel transparente (alguns clientes como Apple Mail Privacy podem inflar/silenciar a métrica). Cliques são rastreados via redirect e refletem intenção real."})]})}function h({icon:f,label:o,value:g,sub:n,info:c}){return e.jsxs("div",{className:"rounded-xl border border-border bg-card p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 text-xs text-muted-foreground mb-2",children:[e.jsxs("span",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(f,{className:"h-3.5 w-3.5 shrink-0"}),e.jsx("span",{className:"truncate",children:o})]}),c&&e.jsx(B,{text:c})]}),e.jsx("div",{className:"text-2xl font-bold text-foreground tabular-nums",children:g}),n&&e.jsx("div",{className:"text-[11px] text-muted-foreground mt-1",children:n})]})}export{J 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.