/* Automations Drawer ================================================= */
const SCOPES = [
{ id:'overview', label:'All platforms' },
{ id:'meta', label:'Meta' },
{ id:'google', label:'Google Ads' },
{ id:'tiktok', label:'TikTok' },
{ id:'snapchat', label:'Snapchat' },
{ id:'x', label:'X' },
];
const OBJECTS = [
{ id:'campaign', label:'Campaign' },
{ id:'adset', label:'Ad set' },
{ id:'keyword', label:'Keyword' },
];
const METRICS = [
{ id:'cpa', label:'CPA', unit:'$', format:'currency2' },
{ id:'roas', label:'ROAS', unit:'×', format:'x' },
{ id:'spend', label:'Spend (24h)', unit:'$', format:'currency' },
{ id:'ctr', label:'CTR', unit:'%', format:'pct' },
{ id:'cpc', label:'CPC', unit:'$', format:'currency2' },
{ id:'freq', label:'Frequency', unit:'x', format:'x' },
];
const OPS_RULE = ['>', '<', '≥', '≤', '='];
const ACTIONS = [
{ id:'pause', label:'Pause it', tone:'rose' },
{ id:'enable', label:'Enable it', tone:'emerald'},
{ id:'reduce_budget', label:'Reduce budget 25%', tone:'amber' },
{ id:'increase_budget',label:'Increase budget 20%',tone:'sky' },
{ id:'notify', label:'Notify on Slack', tone:'accent' },
];
function Seg({ value, onChange, opts, small }){
return (
{opts.map(o => (
))}
);
}
function RuleCard({ rule, onChange, onDelete }){
const r = rule;
const upd = (patch) => onChange({ ...r, ...patch });
const actionTone = (ACTIONS.find(a=>a.id===r.action)?.tone) || 'neutral';
return (
upd({enabled:v})} size="sm"/>
{r.enabled?'Active':'Paused'}
{ACTIONS.find(a=>a.id===r.action)?.label}
{/* Logic strip */}
);
}
function AutomationsDrawer({ open, onClose, rules, setRules }){
const updateRule = (id, next) => setRules(arr => arr.map(r=> r.id===id ? next : r));
const removeRule = (id) => setRules(arr => arr.filter(r => r.id !== id));
const addRule = () => setRules(arr => [
...arr,
{ id:'r'+Date.now(), enabled:true, scope:'overview', obj:'campaign', metric:'cpa', op:'>', value:40, action:'pause', note:'New rule — describe what it does here.' }
]);
const enabledCount = rules.filter(r=>r.enabled).length;
return (
Automations
{enabledCount} active
>
}
footer={
<>
Done
New rule
>
}>
How rules run
Conditions evaluate every 15 minutes against your MCP data feed. Actions log to Activity and notify your selected channels.
{rules.map(r => (
updateRule(r.id, n)} onDelete={()=>removeRule(r.id)}/>
))}
{rules.length === 0 && (
No automations yet. Click New rule to add one.
)}
);
}
Object.assign(window, { AutomationsDrawer });