← back to Marketing Command Center
public/dw-accounts.js
51 lines
// Shared canonical DW-owned Instagram accounts helper. Every social/account panel
// uses this so all owned accounts render everywhere (not just where a surface has
// data for them). Loaded once from index.html; the fetch is memoized so panels
// re-init cheaply.
//
// const accts = await window.MCC_ACCOUNTS.load(); // [{handle, name, ig_user_id}]
// window.MCC_ACCOUNTS.handles(); // ['asseeninhotels', ...] (after load)
// window.MCC_ACCOUNTS.byHandle('linenwallpaper'); // {handle,name,...} | undefined
//
// merge(dynamicRows, keyFn) unions the canonical accounts with a panel's dynamic
// data keyed by handle: every canonical account appears, annotated with its dynamic
// row when one exists (else null) — the one pattern every panel repeats.
(function () {
// Always hit the bare origin — a page opened with embedded URL creds would make
// a relative fetch throw "URL that includes credentials" (see app.js).
const ORIGIN = location.origin;
let cache = null; // resolved [{handle,name,ig_user_id}]
let inflight = null; // de-dupe concurrent loads
async function load() {
if (cache) return cache;
if (inflight) return inflight;
inflight = fetch(ORIGIN + '/api/dw-accounts', { credentials: 'same-origin' })
.then(r => r.ok ? r.json() : { accounts: [] })
.then(d => { cache = (d && d.accounts) || []; inflight = null; return cache; })
.catch(() => { inflight = null; return cache || []; });
return inflight;
}
function handles() { return (cache || []).map(a => a.handle); }
function byHandle(h) { return (cache || []).find(a => a.handle === h); }
// Union canonical accounts with a panel's dynamic rows. keyFn(row) → handle.
// Returns [{ ...account, data: <matching row | null> }] in canonical (sorted) order,
// then any dynamic rows whose handle isn't a known canonical account (rare).
function merge(rows, keyFn) {
const list = cache || [];
const byKey = new Map();
(rows || []).forEach(r => { const k = keyFn ? keyFn(r) : r.handle; if (k != null) byKey.set(String(k), r); });
const out = list.map(a => ({ ...a, data: byKey.get(a.handle) || null }));
const known = new Set(list.map(a => a.handle));
(rows || []).forEach(r => {
const k = String(keyFn ? keyFn(r) : r.handle);
if (k && !known.has(k)) out.push({ handle: k, name: k, ig_user_id: null, data: r });
});
return out;
}
window.MCC_ACCOUNTS = { load, handles, byHandle, merge };
})();