← back to Marketing Command Center
clients panel: merged ★ All Prospects group (search/sort/filter/export across all ~5.9k firms; each tagged by city)
d544ba18faeec32c10959aa6b2c9c15c3f25e857 · 2026-07-16 11:58:51 -0700 · steve
Files touched
M public/panels/clients.js
Diff
commit d544ba18faeec32c10959aa6b2c9c15c3f25e857
Author: steve <steve@designerwallcoverings.com>
Date: Thu Jul 16 11:58:51 2026 -0700
clients panel: merged ★ All Prospects group (search/sort/filter/export across all ~5.9k firms; each tagged by city)
---
public/panels/clients.js | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/public/panels/clients.js b/public/panels/clients.js
index 92da8f5..6046c59 100644
--- a/public/panels/clients.js
+++ b/public/panels/clients.js
@@ -19,7 +19,7 @@ window.MCC_PANELS['clients'] = {
// Normalize a record from either a "clients" (FM) or "prospects" (CSV) dataset.
function norm(rec, kind) {
if (kind === 'prospects') {
- return { id: (rec.website || rec.title || '').toLowerCase(), label: rec.title || '(business)', sub: [rec.city].filter(Boolean).join(' · '),
+ return { id: (rec.website || rec.title || '').toLowerCase(), label: rec.title || '(business)', sub: [rec.city, rec._group].filter(Boolean).join(' · '),
email: rec.email || '', website: rec.website || '', phone: rec.phone || '', q: [rec.title, rec.city].filter(Boolean).join(' '),
_raw: rec, _all: Object.values(rec).filter(v => v && typeof v === 'string').join(' ').toLowerCase() };
}
@@ -41,6 +41,17 @@ window.MCC_PANELS['clients'] = {
} catch { $('#cl-banner').textContent = 'No client datasets staged yet (data/clients-manifest.json missing).'; return; }
if (!MANIFEST.length) { $('#cl-banner').textContent = 'No client datasets staged yet.'; return; }
+ // Synthetic "All Prospects" group = every prospect city merged into one list.
+ const prospectDs = MANIFEST.filter(x => x.kind === 'prospects');
+ if (prospectDs.length > 1) {
+ const fmIdx = MANIFEST.findIndex(x => x.id === 'fm-clients');
+ MANIFEST.splice(fmIdx >= 0 ? fmIdx + 1 : 0, 0, {
+ id: 'all-prospects', label: '★ All Prospects', kind: 'prospects',
+ files: prospectDs.map(x => x.file), labels: prospectDs.map(x => x.label),
+ count: prospectDs.reduce((n, x) => n + (x.count || 0), 0),
+ });
+ }
+
$('#cl-banner').hidden = true;
$('#cl-groupcount').textContent = MANIFEST.length + ' groups';
$('#cl-tabs').innerHTML = MANIFEST.map(d =>
@@ -55,7 +66,14 @@ window.MCC_PANELS['clients'] = {
$('#cl-grouptitle').textContent = d.label;
$('#cl-list').innerHTML = '<div class="loading">Loading…</div>';
let data;
- try { data = await jget('/data/' + d.file); } catch { $('#cl-list').innerHTML = '<div class="card muted">Could not load ' + esc(d.file) + '.</div>'; return; }
+ if (d.files) { // merged "All Prospects" — load every group, tag each with its city
+ const parts = await Promise.all(d.files.map(f => jget('/data/' + f).catch(() => null)));
+ const businesses = [];
+ parts.forEach((p, i) => { if (p) (p.businesses || []).forEach(b => businesses.push(Object.assign({ _group: d.labels[i] }, b))); });
+ data = { businesses, source: 'all prospect groups merged', with_email: businesses.filter(b => b.email).length };
+ } else {
+ try { data = await jget('/data/' + d.file); } catch { $('#cl-list').innerHTML = '<div class="card muted">Could not load ' + esc(d.file) + '.</div>'; return; }
+ }
const arr = data.clients || data.businesses || [];
RECS = arr.map(r => norm(r, d.kind));
const nEmail = RECS.filter(r => r.email).length, nIg = RECS.filter(r => r._raw.instagram).length, nLi = RECS.filter(r => r._raw.linkedin).length;
@@ -147,7 +165,7 @@ window.MCC_PANELS['clients'] = {
const blob = new Blob(['' + csv], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
- a.href = url; a.download = d.file.replace(/\.json$/, '') + '.csv';
+ a.href = url; a.download = (d.file || ('prospects-' + d.id + '.json')).replace(/\.json$/, '') + '.csv';
document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
}
← 63885bc clients panel: quick filters (email/IG/LinkedIn/uncontacted)
·
back to Marketing Command Center
·
clients panel: dedup + field-merge in All Prospects (LA grou b1d1fc7 →