feat: integrate facebook marketing roi on ecommerce dashboard
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"/></svg>
|
||||
</div>
|
||||
<h3 class="text-lg font-bold text-slate-300 mb-2">E-Commerce Settings</h3>
|
||||
<p class="text-sm text-slate-500">Configure WooCommerce API credentials and integration parameters for the online store dashboard.</p>
|
||||
<p class="text-sm text-slate-500">Configure WooCommerce API and Facebook Business credentials for the marketing dashboard.</p>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -182,6 +182,87 @@
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Marketing & Growth Row -->
|
||||
<h2 class="text-xl font-bold text-white mb-4 mt-8 flex items-center gap-2">
|
||||
<svg class="w-5 h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/></svg>
|
||||
Marketing & Growth (Meta Ads)
|
||||
</h2>
|
||||
|
||||
<div id="marketing-unconfigured" class="glass rounded-2xl p-8 flex flex-col items-center justify-center text-center mb-8 hidden">
|
||||
<svg class="w-12 h-12 text-slate-500 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
<h3 class="text-lg font-bold text-white mb-2">Connect Facebook Business</h3>
|
||||
<p class="text-sm text-slate-400 max-w-md">Unlock powerful Return on Ad Spend (ROAS) analytics by configuring your Facebook Graph API credentials in the Admin Panel.</p>
|
||||
<a href="/admin/settings/ecommerce" class="mt-4 px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white text-sm font-medium rounded-lg transition-colors">Configure Now</a>
|
||||
</div>
|
||||
|
||||
<div id="marketing-dashboard" class="mb-8 hidden">
|
||||
<!-- Marketing KPIs -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
||||
<!-- Ad Spend -->
|
||||
<div class="glass p-5 rounded-2xl relative overflow-hidden group">
|
||||
<div class="absolute inset-0 bg-blue-500/5 group-hover:bg-blue-500/10 transition-colors"></div>
|
||||
<div class="relative z-10">
|
||||
<p class="text-sm font-medium text-slate-400 tracking-wide uppercase mb-1">Ad Spend</p>
|
||||
<p class="text-2xl font-bold text-white" id="mkt-spend"><div class="h-8 w-24 rounded loading-shimmer mkt-loading"></div></p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ROAS -->
|
||||
<div class="glass p-5 rounded-2xl relative overflow-hidden group">
|
||||
<div class="absolute inset-0 bg-purple-500/5 group-hover:bg-purple-500/10 transition-colors"></div>
|
||||
<div class="relative z-10">
|
||||
<p class="text-sm font-medium text-slate-400 tracking-wide uppercase mb-1">ROAS</p>
|
||||
<p class="text-2xl font-bold text-emerald-400" id="mkt-roas"><div class="h-8 w-24 rounded loading-shimmer mkt-loading"></div></p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CPC -->
|
||||
<div class="glass p-5 rounded-2xl relative overflow-hidden group">
|
||||
<div class="absolute inset-0 bg-rose-500/5 group-hover:bg-rose-500/10 transition-colors"></div>
|
||||
<div class="relative z-10">
|
||||
<p class="text-sm font-medium text-slate-400 tracking-wide uppercase mb-1">Cost Per Click</p>
|
||||
<p class="text-2xl font-bold text-white" id="mkt-cpc"><div class="h-8 w-24 rounded loading-shimmer mkt-loading"></div></p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Clicks -->
|
||||
<div class="glass p-5 rounded-2xl relative overflow-hidden group">
|
||||
<div class="absolute inset-0 bg-orange-500/5 group-hover:bg-orange-500/10 transition-colors"></div>
|
||||
<div class="relative z-10">
|
||||
<p class="text-sm font-medium text-slate-400 tracking-wide uppercase mb-1">Link Clicks</p>
|
||||
<p class="text-2xl font-bold text-white" id="mkt-clicks"><div class="h-8 w-24 rounded loading-shimmer mkt-loading"></div></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Top Campaigns Table -->
|
||||
<div class="glass rounded-2xl flex flex-col overflow-hidden">
|
||||
<div class="p-5 border-b border-white/5 flex items-center justify-between bg-white/5">
|
||||
<h3 class="font-bold text-white tracking-tight flex items-center gap-2">
|
||||
<svg class="w-4 h-4 text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z"/></svg>
|
||||
Top Performing Campaigns
|
||||
</h3>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="bg-black/20 text-xs text-slate-400 uppercase tracking-wider">
|
||||
<th class="p-3 font-medium">Campaign Name</th>
|
||||
<th class="p-3 font-medium text-right">Spend</th>
|
||||
<th class="p-3 font-medium text-right">Clicks</th>
|
||||
<th class="p-3 font-medium text-right">CPC</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-campaigns" class="text-sm divide-y divide-white/5">
|
||||
<!-- Populated via JS -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-bold text-white mb-4 mt-8 flex items-center gap-2">
|
||||
<svg class="w-5 h-5 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>
|
||||
Advanced Custom Analytics
|
||||
</h2>
|
||||
|
||||
<!-- Advanced Analytics Charts Row -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
|
||||
@@ -489,12 +570,53 @@ function setKpisLoading() {
|
||||
} catch(e) { console.error(e); }
|
||||
}
|
||||
|
||||
async function loadMarketing() {
|
||||
document.querySelectorAll('.mkt-loading').forEach(el => el.classList.remove('hidden'));
|
||||
|
||||
const tb = document.getElementById('table-campaigns');
|
||||
if (tb) tb.innerHTML = Array(5).fill('<tr><td colspan="4" class="p-3"><div class="h-4 w-full rounded loading-shimmer"></div></td></tr>').join('');
|
||||
|
||||
try {
|
||||
const data = await fetchJson('/api/ecommerce/marketing');
|
||||
if (!data.configured) {
|
||||
document.getElementById('marketing-unconfigured').classList.remove('hidden');
|
||||
document.getElementById('marketing-dashboard').classList.add('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('marketing-unconfigured').classList.add('hidden');
|
||||
document.getElementById('marketing-dashboard').classList.remove('hidden');
|
||||
|
||||
document.getElementById('mkt-spend').textContent = fmt(data.spend);
|
||||
document.getElementById('mkt-roas').textContent = data.roas.toFixed(2) + 'x';
|
||||
document.getElementById('mkt-cpc').textContent = fmt(data.cpc);
|
||||
document.getElementById('mkt-clicks').textContent = fmtNum(data.clicks);
|
||||
|
||||
if (!data.campaigns || data.campaigns.length === 0) {
|
||||
tb.innerHTML = '<tr><td colspan="4" class="p-4 text-center text-slate-500">No active campaigns found in this period.</td></tr>';
|
||||
} else {
|
||||
tb.innerHTML = data.campaigns.map(c => `
|
||||
<tr class="hover:bg-white/5 transition-colors">
|
||||
<td class="p-3 font-medium text-white max-w-[200px] truncate" title="${c.name}">${c.name}</td>
|
||||
<td class="p-3 text-right font-medium text-blue-400">${fmt(c.spend)}</td>
|
||||
<td class="p-3 text-right text-slate-300">${fmtNum(c.clicks)}</td>
|
||||
<td class="p-3 text-right text-slate-300">${fmt(c.clicks > 0 ? (c.spend / c.clicks) : 0)}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
function loadAllData() {
|
||||
updateFilterStatus();
|
||||
loadSummary();
|
||||
loadTopProducts();
|
||||
loadAnalytics();
|
||||
loadInsights();
|
||||
loadMarketing();
|
||||
|
||||
const now = new Date();
|
||||
document.getElementById('last-updated').textContent = 'Updated ' + now.getHours() + ':' + String(now.getMinutes()).padStart(2, '0');
|
||||
|
||||
Reference in New Issue
Block a user