// Meta Ads Center screen.
(() => {
const { Card, Badge, Avatar, ProgressBar } = window.TechyFuelOSDesignSystem_be0222;
const CAMP_STATUS = {
active: { tone: 'success', label: 'Active' },
review: { tone: 'warning', label: 'In review' },
paused: { tone: 'neutral', label: 'Paused' },
ended: { tone: 'neutral', label: 'Ended' },
draft: { tone: 'neutral', label: 'Draft' },
};
function fmtSpend(n) {
if (!n && n !== 0) return '$0';
if (n >= 1000) return '$' + (n / 1000).toFixed(1) + 'K';
return '$' + Math.round(n);
}
function budgetPace(spent, budgetDaily) {
if (!budgetDaily || budgetDaily === 0) return 0;
return Math.min(100, Math.round((spent / (budgetDaily * 30)) * 100));
}
function AdStat({ label, value, sub, color }) {
return (
{label}
{value}
{sub}
);
}
function MetaAds() {
useLucide();
const [campaigns, setCampaigns] = React.useState([]);
const [loading, setLoading] = React.useState(true);
const [clients, setClients] = React.useState([]);
const [modalOpen, setModalOpen] = React.useState(false);
const [saving, setSaving] = React.useState(false);
const [form, setForm] = React.useState({ name: '', client_id: '', platform: 'meta', budget_daily: '', status: 'draft' });
function set(k, v) { setForm(f => ({ ...f, [k]: v })); }
React.useEffect(() => {
if (!window.API) { setLoading(false); return; }
(async () => {
try {
const r = await window.API.getAdCampaigns();
if (r.data) setCampaigns(r.data);
} catch {}
try {
const r = await window.API.getClients();
if (r.data) setClients(r.data);
} catch {}
setLoading(false);
})();
}, []);
async function handleStatusChange(id, newStatus) {
if (!window.API) return;
try {
await window.API.updateCampaign(id, { status: newStatus });
setCampaigns(prev => prev.map(c => c.id === id ? { ...c, status: newStatus } : c));
} catch {}
}
async function handleNewCampaign() {
if (!form.name.trim()) return;
setSaving(true);
try {
const payload = { name: form.name, platform: form.platform, status: form.status, spent: 0, impressions: 0, clicks: 0, conversions: 0 };
if (form.client_id) payload.client_id = form.client_id;
if (form.budget_daily) payload.budget_daily = Number(form.budget_daily);
if (window.API) {
const { data } = await window.API.createCampaign(payload);
if (data) {
const clientObj = clients.find(c => c.id === form.client_id);
setCampaigns(prev => [{ ...data, clients: clientObj ? { name: clientObj.company || clientObj.name } : null }, ...prev]);
}
}
setModalOpen(false);
setForm({ name: '', client_id: '', platform: 'meta', budget_daily: '', status: 'draft' });
} finally { setSaving(false); }
}
const totalSpend = campaigns.reduce((s, c) => s + (c.spent || 0), 0);
const totalImpr = campaigns.reduce((s, c) => s + (c.impressions || 0), 0);
const totalLeads = campaigns.reduce((s, c) => s + (c.conversions || 0), 0);
const avgCPL = totalLeads > 0 ? '$' + (totalSpend / totalLeads).toFixed(2) : '—';
const activeCnt = campaigns.filter(c => c.status === 'active').length;
return (
Meta Ads Center
{campaigns.length} campaign{campaigns.length !== 1 ? 's' : ''} · {activeCnt} active
Campaigns by client
{loading && (
Loading…
)}
{!loading && campaigns.length === 0 && (
No campaigns yet
Create your first campaign using the button above
)}
{!loading && campaigns.length > 0 && (
{['Campaign', 'Status', 'Spend', 'Impressions', 'Clicks', 'Conversions', 'Budget pace'].map((h, i) => (
| 1 && i < 6 ? 'right' : 'left', padding: '10px 18px', fontSize: 'var(--text-2xs)', fontWeight: 'var(--fw-bold)', letterSpacing: 'var(--tracking-wide)', textTransform: 'uppercase', color: 'var(--text-subtle)' }}>{h} |
))}
{campaigns.map((c, i) => {
const s = CAMP_STATUS[c.status] || CAMP_STATUS.paused;
const pace = budgetPace(c.spent, c.budget_daily);
const clientName = c.clients ? c.clients.name : '—';
return (
|
|
|
{fmtSpend(c.spent)} |
{(c.impressions || 0).toLocaleString()} |
{(c.clicks || 0).toLocaleString()} |
{c.conversions || 0} |
85 ? 'warning' : 'brand'} size="sm" />
|
);
})}
)}
setModalOpen(false)} title="New campaign" onSubmit={handleNewCampaign} loading={saving} submitLabel="Create">
set('name', e.target.value)} />
set('budget_daily', e.target.value)} />
);
}
Object.assign(window, { MetaAds });
})();