← back to Ads Dashboard
Cycle 3: real acquisition panel from Shopify order referrers (/api/acquisition, DW-only, 10-min cache)
d0226041cfaa038f2232cefb7a08b827417a32c0 · 2026-08-02 18:48:26 -0700 · Steve Abrams
Files touched
Diff
commit d0226041cfaa038f2232cefb7a08b827417a32c0
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Aug 2 18:48:26 2026 -0700
Cycle 3: real acquisition panel from Shopify order referrers (/api/acquisition, DW-only, 10-min cache)
---
public/index.html | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/public/index.html b/public/index.html
index 9e1a835..ac7d959 100644
--- a/public/index.html
+++ b/public/index.html
@@ -68,6 +68,14 @@
<div class="empty" id="campEmpty" hidden>No campaigns wired yet — /yoloforever will populate this. Data source: /api/campaigns</div>
</div>
+ <div class="section-h">Acquisition — where orders come from <span style="text-transform:none;font-weight:400">(real, from Shopify order referrers)</span></div>
+ <div class="card">
+ <table id="acqTable"><thead><tr>
+ <th>Channel</th><th>Orders</th><th>Revenue</th>
+ </tr></thead><tbody id="acqBody"></tbody></table>
+ <div class="empty" id="acqEmpty" hidden></div>
+ </div>
+
<div class="section-h">Competitor Ad Signals</div>
<div class="card">
<div id="signals"></div>
@@ -113,6 +121,21 @@ async function boot(){
$('signals').innerHTML = items.length
? items.map(s=>`<div><a href="${s.url||'#'}">${s.advertiser||s.title||'signal'}</a> <span class="badge">${s.platform||'—'}</span> <span class="when">🕓 ${fmtDate(s.seen_at||s.created_at)}</span></div>`).join('')
: `<div class="empty">No competitor ad signals captured yet — feeds from the advertising-signals skill. Source: /api/signals</div>`;
+
+ // acquisition — real Shopify order referrers
+ const acq = await fetch('/api/acquisition').then(r=>r.json()).catch(()=>({present:false,reason:'fetch failed'}));
+ if (acq.present && (acq.channels||[]).length) {
+ $('acqEmpty').hidden = true;
+ $('acqBody').innerHTML = acq.channels.map(c=>`<tr>
+ <td><a href="/api/acquisition">${c.channel}</a></td>
+ <td>${c.orders}</td>
+ <td>$${c.revenue.toLocaleString()}</td>
+ </tr>`).join('') + `<tr style="font-weight:650"><td>Total (${acq.window})</td><td>${acq.totals.orders}</td><td>$${acq.totals.revenue.toLocaleString()}</td></tr>`;
+ } else {
+ $('acqBody').innerHTML = '';
+ $('acqEmpty').hidden = false;
+ $('acqEmpty').textContent = 'Acquisition data unavailable: ' + (acq.reason||'no data') + ' (source: /api/acquisition)';
+ }
}
let sortKey='newest';
← 370f723 auto-save: 2026-08-02T18:47:17 (1 files) — server.js
·
back to Ads Dashboard
·
Cycle 4: real UTM campaign attribution in /api/acquisition + ceae088 →