PageSourceSearch

https://www.ecomdroptv.com/assets/WhatsAppAlertsPage-BUjIFjEq.js

js ecomdroptv.com collected 2026-09-24 14:42:16 UTC 15,196 bytes, 1 lines download raw bytes

1import{u as _,j as e,W as k,f as $,a as N,c as H}from"./index-C6-4kgOT.js";import{r as i}from"./vendor-react--UDKce57.js";import{u as F}from"./RulesPanel-CPqDkdcB.js";import"./useMetaApi-BpBGKXr2.js";import"./useAutoRefresh-DKHwRdiF.js";import"./planAccounts-jrtXKEQ1.js";import"./anti-flash-ssm2_jN6.js";import"./coDates-BxYjNlB-.js";import"./meta-SIn-uAlU.js";const W={cpa:"CPA",roas:"ROAS",cpm:"CPM",ctr:"CTR",spend:"Gasto",cpc:"CPC",purchases:"Compras",revenue:"Ingresos",clicks:"Clicks",impressions:"Impresiones",cvr:"CVR (% conversión)"},M={cpa:"Costo por compra en la moneda de la cuenta publicitaria. Pon el límite que todavía te deja margen.",roas:"Retorno por unidad monetaria gastada. Si pones 1.5, por cada unidad gastada entran 1.5.",cpm:"Costo por mil impresiones en la moneda de la cuenta publicitaria.",ctr:"Click-through rate (%). Saludable > 1%. Si pones 1.5 = 1.5% de gente que ve hace click.",spend:"Gasto total acumulado en el período, en la moneda de la cuenta.",cpc:"Costo por click en la moneda de la cuenta. Si sube mucho, el creativo puede estar fatigado.",purchases:"Total de compras en el período. Si pones 0, puedes detectar ausencia de ventas.",revenue:"Ingresos por compras en la moneda de la cuenta. Útil para detectar caídas grandes.",clicks:"Total de clicks en la ventana.",impressions:"Total de impresiones (veces que se mostró el anuncio).",cvr:"Conversion rate (%): qué % de los que clickean compran. Saludable > 2-3%."};function R(t,s){return t==="cpa"||t==="cpm"||t==="spend"||t==="cpc"||t==="revenue"?$(s):t==="roas"?`${s}x`:t==="ctr"||t==="cvr"?`${s}%`:t==="purchases"||t==="clicks"||t==="impressions"?s.toLocaleString("es-CO"):String(s)}function q(t){const s=t.operator==="gt"?"sube por encima de":"cae por debajo de",c=Math.max(1,Math.ceil(Number(t.window_hours||24)/24)),p=c===1?"hoy":`en los últimos ${c} días calendario`;return`Cuando ${W[t.metric]} ${s} ${R(t.metric,t.threshold)} ${p}, te aviso por WhatsApp`}function Z(){const t=_(),[s,c]=i.useState([]),[p,g]=i.useState([]),[C,v]=i.useState(!0),[f,u]=i.useState(!1),n=i.useCallback(async()=>{v(!0);try{const[o,l]=await Promise.all([t("/api/rules").then(a=>a.json()),t("/api/rules/executions?limit=30").then(a=>a.json())]);c((o.rules||[]).filter(a=>a.action_type==="notify_whatsapp"));const d=new Set((o.rules||[]).filter(a=>a.action_type==="notify_whatsapp").map(a=>a.id));g((l.executions||[]).filter(a=>d.has(a.rule_id)))}finally{v(!1)}},[t]);i.useEffect(()=>{n()},[n]);const S=async(o,l)=>{c(d=>d.map(a=>a.id===o?{...a,enabled:l?1:0}:a));try{if(!(await t(`/api/rules/${o}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:l})})).ok)throw new Error("failed")}catch{c(d=>d.map(a=>a.id===o?{...a,enabled:l?0:1}:a))}},j=async o=>{confirm("¿Borrar este aviso? No se puede deshacer.")&&(await t(`/api/rules/${o}`,{method:"DELETE"}),n())};return e.jsxs("div",{style:{padding:"20px 24px",maxWidth:1100,margin:"0 auto"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:16,gap:12,flexWrap:"wrap"},children:[e.jsxs("div",{children:[e.jsxs("h1",{style:{fontSize:22,fontWeight:800,margin:0,color:"var(--text-primary)",display:"flex",alignItems:"center",gap:8},children:[e.jsx(k,{size:26}),"Avisos por WhatsApp"]}),e.jsxs("div",{style:{fontSize:13,color:"var(--text-muted)",marginTop:4,lineHeight:1.5},children:["Configura alertas custom para que te avisemos por WhatsApp cuando una métrica cruce un umbral.",e.jsx("b",{children:" No tocamos tus campañas"})," — solo te avisamos."]})]}),e.jsx("button",{onClick:()=>u(!0),style:{background:"linear-gradient(135deg, #6366F1, #A855F7)",color:"#fff",border:"none",padding:"10px 18px",borderRadius:10,fontSize:13.5,fontWeight:700,cursor:"pointer",whiteSpace:"nowrap"},children:"+ Crear aviso"})]}),e.jsxs("div",{style:{background:"rgba(37,211,102,0.06)",border:"1px solid rgba(37,211,102,0.30)",borderRadius:12,padding:"14px 16px",marginBottom:18,display:"flex",gap:12,alignItems:"flex-start"},children:[e.jsx("span",{style:{fontSize:22,flexShrink:0},children:"💡"}),e.jsxs("div",{style:{fontSize:12.5,color:"var(--text-secondary)",lineHeight:1.55},children:["Los avisos llegan a tu WhatsApp configurado en tu perfil. Respetan el cooldown que pongas para no fastidiarte. Si quieres que el sistema actúe automáticamente (pausar, subir/bajar presupuesto), usa ",e.jsx("b",{children:"Reglas"})," en cada plataforma."]})]}),C?e.jsx("div",{style:{textAlign:"center",padding:40,color:"var(--text-muted)"},children:"Cargando avisos..."}):s.length===0?e.jsxs("div",{style:{background:"var(--bg-card)",border:"1px dashed var(--border)",borderRadius:14,padding:40,textAlign:"center"},children:[e.jsx("div",{style:{marginBottom:8,display:"flex",justifyContent:"center"},children:e.jsx(k,{size:44})}),e.jsx("div",{style:{fontSize:16,fontWeight:800,color:"var(--text-primary)",marginBottom:6},children:"Aún no tienes avisos configurados"}),e.jsxs("div",{style:{fontSize:13,color:"var(--text-muted)",marginBottom:16,maxWidth:420,margin:"0 auto 16px"},children:["Crea uno para que te avisemos por WhatsApp cuando algo importante pase con tus campañas. Por ejemplo: ",e.jsx("i",{children:'"Avísame si el CPA de mi campaña principal supera $15.000 COP"'}),"."]}),e.jsx("button",{onClick:()=>u(!0),style:{background:"linear-gradient(135deg, #6366F1, #A855F7)",color:"#fff",border:"none",padding:"10px 22px",borderRadius:10,fontSize:13.5,fontWeight:700,cursor:"pointer"},children:"Crear mi primer aviso"})]}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:s.map(o=>e.jsx(O,{alert:o,onToggle:l=>S(o.id,l),onRemove:()=>j(o.id)},o.id))}),p.length>0&&e.jsxs("div",{style:{marginTop:32},children:[e.jsx("h2",{style:{fontSize:15,fontWeight:800,color:"var(--text-primary)",marginBottom:10},children:"Últimas alertas enviadas"}),e.jsx("div",{style:{background:"var(--bg-card)",border:"1px solid var(--border)",borderRadius:12,overflow:"hidden"},children:p.slice(0,10).map((o,l)=>{const d=s.find(a=>a.id===o.rule_id);return e.jsxs("div",{style:{padding:"10px 14px",borderBottom:l<p.slice(0,10).length-1?"1px solid var(--border)":"none",display:"flex",justifyContent:"space-between",alignItems:"center",gap:10,fontSize:12.5},children:[e.jsxs("div",{children:[e.jsx("span",{style:{color:"var(--text-primary)",fontWeight:700},children:d?`${W[d.metric]} ${d.operator==="gt"?">":"<"} ${R(d.metric,d.threshold)}`:`Aviso #${o.rule_id}`}),o.evaluated_value!=null&&e.jsxs("span",{style:{color:"var(--text-muted)",marginLeft:8},children:["— valor: ",o.evaluated_value.toFixed(2)]})]}),e.jsx("div",{style:{color:"var(--text-muted)",fontSize:11.5}
1,children:new Date(o.fired_at).toLocaleString("es-CO",{dateStyle:"short",timeStyle:"short"})})]},o.id)})})]}),f&&e.jsx(L,{onClose:()=>u(!1),onCreated:()=>{u(!1),n()}})]})}function O({alert:t,onToggle:s,onRemove:c}){return e.jsxs("div",{style:{background:"var(--bg-card)",border:"1px solid var(--border)",borderRadius:12,padding:"14px 16px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:12,flexWrap:"wrap",opacity:t.enabled?1:.55},children:[e.jsxs("div",{style:{flex:1,minWidth:220},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:4,flexWrap:"wrap"},children:[e.jsx("span",{style:{fontSize:11,fontWeight:700,color:t.platform==="meta"?"#1877F2":"#FE2C55",background:t.platform==="meta"?"rgba(24,119,242,0.10)":"rgba(254,44,85,0.10)",padding:"2px 8px",borderRadius:999,textTransform:"uppercase",letterSpacing:"0.06em"},children:t.platform==="meta"?"Meta":"TikTok"}),e.jsx("span",{style:{fontSize:13,fontWeight:700,color:"var(--text-primary)"},children:t.entity_name||`${t.entity_level} ${t.entity_id}`})]}),e.jsx("div",{style:{fontSize:13,color:"var(--text-secondary)",lineHeight:1.5},children:q(t)}),e.jsxs("div",{style:{fontSize:11,color:"var(--text-muted)",marginTop:4},children:["Cooldown: ",t.cooldown_hours,"h · ",t.last_fired_at?`Última alerta: ${new Date(t.last_fired_at).toLocaleDateString("es-CO",{dateStyle:"short"})}`:"Aún no se disparó"]})]}),e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:6,cursor:"pointer",fontSize:12,color:"var(--text-secondary)"},children:[e.jsx("input",{type:"checkbox",checked:!!t.enabled,onChange:p=>s(p.target.checked)}),t.enabled?"Activo":"Pausado"]}),e.jsx("button",{onClick:c,title:"Borrar",style:{background:"transparent",border:"1px solid var(--border)",color:"var(--text-muted)",padding:"6px 10px",borderRadius:8,cursor:"pointer",fontSize:12},children:"🗑️"})]})]})}function L({onClose:t,onCreated:s}){const c=_(),{isHidden:p}=N(),[g,C]=i.useState("meta"),{campaigns:v}=F(g,{excludeSmartPlus:!1}),[f,u]=i.useState(""),[n,S]=i.useState("cpa"),[j,o]=i.useState("gt"),[l,d]=i.useState("15000"),[a,I]=i.useState("24"),[w,E]=i.useState("4"),[m,A]=i.useState(!1),[z,b]=i.useState(null);i.useEffect(()=>{u("")},[g]);const y=v.find(r=>r.id===f),P=i.useMemo(()=>n==="cpa"?"15000":n==="cpm"?"10000":n==="cpc"?"1000":n==="spend"?"50000":n==="revenue"?"100000":n==="roas"?"1.5":n==="ctr"?"1.0":n==="cvr"?"2.5":n==="purchases"?"0":n==="clicks"?"100":n==="impressions"?"5000":"",[n]),B=async()=>{if(b(null),!f){b("Selecciona una campaña");return}if(!l||isNaN(Number(l))){b("El umbral tiene que ser un número");return}A(!0);try{const r=await c("/api/rules",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({platform:g,entity_level:"campaign",entity_id:f,entity_name:(y==null?void 0:y.name)||null,integration_account_id:y==null?void 0:y.integrationAccountId,metric:n,operator:j,threshold:Number(l),window_hours:Number(a)||24,action_type:"notify_whatsapp",action_value:0,cooldown_hours:Number(w)||4,enabled:!0})});if(!r.ok){const T=await r.json().catch(()=>({}));throw new Error(T.message||T.error||"No se pudo crear el aviso")}s()}catch(r){b(r.message)}finally{A(!1)}},h={width:"100%",padding:"9px 12px",background:"var(--bg-card)",border:"1px solid var(--border)",borderRadius:8,fontSize:13,color:"var(--text-primary)",fontFamily:"inherit"};return e.jsx("div",{onClick:()=>!m&&t(),style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999,padding:16},children:e.jsxs("div",{onClick:r=>r.stopPropagation(),style:{background:"var(--bg-card)",border:"1px solid var(--border)",borderRadius:16,padding:24,maxWidth:520,width:"100%",maxHeight:"90vh",overflowY:"auto",boxShadow:"0 20px 60px rgba(0,0,0,0.30)"},children:[e.jsxs("div",{style:{fontSize:18,fontWeight:800,marginBottom:4,color:"var(--text-primary)",display:"flex",alignItems:"center",gap:8},children:[e.jsx(k,{size:22}),"Nuevo aviso por WhatsApp"]}),e.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:18,lineHeight:1.5},children:"Te avisamos cuando se cumpla la condición. No tocamos la campaña."}),e.jsx(x,{label:"Plataforma",children:e.jsxs("select",{value:g,onChange:r=>C(r.target.value),style:h,children:[e.jsx("option",{value:"meta",children:"Meta Ads"}),e.jsx("option",{value:"tiktok",children:"TikTok Ads"})]})}),e.jsxs(x,{label:"Campaña",children:[e.jsxs("select",{value:f,onChange:r=>u(r.target.value),style:h,children:[e.jsx("option",{value:"",children:"Elige una campaña"}),v.map(r=>
1e.jsx("option",{value:r.id,children:H(r.name,p)},r.id))]}),v.length===0&&e.jsx("div",{style:{fontSize:11,color:"var(--text-muted)",marginTop:4},children:"Cargando campañas de la cuenta seleccionada..."})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:10,marginBottom:4},children:[e.jsx(x,{label:"Métrica",children:e.jsxs("select",{value:n,onChange:r=>S(r.target.value),style:h,children:[e.jsxs("optgroup",{label:"Costos",children:[e.jsx("option",{value:"cpa",children:"CPA, costo por compra"}),e.jsx("option",{value:"cpc",children:"CPC, costo por click"}),e.jsx("option",{value:"cpm",children:"CPM, costo por 1.000 impresiones"}),e.jsx("option",{value:"spend",children:"Gasto total"})]}),e.jsxs("optgroup",{label:"Resultados",children:[e.jsx("option",{value:"roas",children:"ROAS, retorno sobre la inversión"}),e.jsx("option",{value:"purchases",children:"Compras totales"}),e.jsx("option",{value:"revenue",children:"Ingresos"}),e.jsx("option",{value:"cvr",children:"CVR, porcentaje de conversión"})]}),e.jsxs("optgroup",{label:"Tráfico",children:[e.jsx("option",{value:"ctr",children:"CTR, porcentaje de clicks por impresión"}),e.jsx("option",{value:"clicks",children:"Clicks totales"}),e.jsx("option",{value:"impressions",children:"Impresiones totales"})]})]})}),e.jsx(x,{label:"Cuando",children:e.jsxs("select",{value:j,onChange:r=>o(r.target.value),style:h,children:[e.jsx("option",{value:"gt",children:"Sube por encima de"}),e.jsx("option",{value:"lt",children:"Cae por debajo de"})]})}),e.jsx(x,{label:"Umbral",children:e.jsx("input",{type:"number",value:l,onChange:r=>d(r.target.value),placeholder:P,style:h})})]}),e.jsx("div",{style:{fontSize:11,color:"var(--text-muted)",marginBottom:14,lineHeight:1.4},children:M[n]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10,marginBottom:14},children:[e.jsx(x,{label:"Período de evaluación",children:e.jsxs("select",{value:a,onChange:r=>I(r.target.value),style:h,children:[e.jsx("option",{value:"24",children:"Hoy"}),e.jsx("option",{value:"48",children:"Últimos 2 días calendario"}),e.jsx("option",{value:"72",children:"Últimos 3 días calendario"}),e.jsx("option",{value:"168",children:"Últimos 7 días calendario"})]})}),e.jsxs(x,{label:"Cooldown entre avisos",children:[e.jsxs("select",{value:w,onChange:r=>E(r.target.value),style:h,children:[e.jsx("option",{value:"2",children:"2 horas"}),e.jsx("option",{value:"4",children:"4 horas"}),e.jsx("option",{value:"12",children:"12 horas"}),e.jsx("option",{value:"24",children:"24 horas (1 vez al día)"})]}),e.jsx("div",{style:{fontSize:11,color:"var(--text-muted)",marginTop:4,lineHeight:1.5},children:"Tiempo mínimo entre dos avisos iguales. Evita repetirlo cada vez que el sistema revisa la condición."})]})]}),z&&e.jsx("div",{style:{background:"rgba(239,68,68,0.10)",color:"#EF4444",padding:10,borderRadius:8,fontSize:12,marginBottom:12},children:z}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:8},children:[e.jsx("button",{onClick:t,disabled:m,style:{background:"transparent",border:"1px solid var(--border)",color:"var(--text-primary)",padding:"10px 18px",borderRadius:10,fontSize:13,fontWeight:700,cursor:m?"not-allowed":"pointer"},children:"Cancelar"}),e.jsx("button",{onClick:B,disabled:m,style:{background:"linear-gradient(135deg, #6366F1, #A855F7)",color:"#fff",border:"none",padding:"10px 18px",borderRadius:10,fontSize:13,fontWeight:700,cursor:m?"not-allowed":"pointer",opacity:m?.7:1},children:m?"Guardando...":"Crear aviso"})]})]})})}function x({label:t,children:s}){return e.jsxs("label",{style:{display:"block",marginBottom:12},children:[e.jsx("div",{style:{fontSize:11.5,fontWeight:700,color:"var(--text-muted)",textTransform:"uppercase",letterSpacing:"0.06em",marginBottom:6},children:t}),s]})}export{Z as WhatsAppAlertsPage};

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.