← back to Rentv

mockups/admin/admin-core.js

42 lines

/* RENTV admin core — shared across the 10 back-office layouts (A01..A10).
   Owns: the real click-out action URLs (LinkedIn/website/Maps/firm/CA-DRE),
   the broker/firm/owner data loader, and the inline action-button block.
   Each A##.html supplies only its unique layout + render(). */
window.ADM = (function () {
  const enc = encodeURIComponent, esc = s => String(s == null ? '' : s).replace(/[&<>"]/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]));
  // ── real, functional click-outs ──
  const LI_P = (n, f) => `https://www.linkedin.com/search/results/people/?keywords=${enc([n, f].filter(Boolean).join(' '))}`;
  const LI_C = f => `https://www.linkedin.com/search/results/companies/?keywords=${enc(f)}`;
  const WEB = f => `https://www.google.com/search?q=${enc('"' + f + '" real estate official website')}`;
  const MAPS = q => `https://www.google.com/maps/search/?api=1&query=${enc(q)}`;
  const DRE = lic => `https://www2.dre.ca.gov/PublicASP/pplinfo.asp?License_id=${enc(lic)}`;
  const GOOG = q => `https://www.google.com/search?q=${enc(q)}`;
  const ASSR = ain => `https://portal.assessor.lacounty.gov/parceldetail/${enc(ain)}`;
  const loc = x => [x.city || x.hq_city, x.state_code || x.hq_state].filter(Boolean).join(', ');

  const A = (href, icon, label) => `<a class="act" href="${href}" target="_blank" rel="noopener" onclick="event.stopPropagation()"><span class="i">${icon}</span>${label}</a>`;
  // the inline action set for any record kind — the "like CRCP" click-outs
  function actions(kind, x) {
    if (kind === 'firms') return [A(LI_C(x.name), '🏢', 'LinkedIn'), A(WEB(x.name), '🌐', 'Website'), A(MAPS(x.name + ' ' + loc(x)), '📍', 'HQ / Map'), x.license_no ? A(DRE(x.license_no), '🪪', 'DRE') : '', A(GOOG(x.name + ' brokers ' + loc(x)), '🔎', 'Google')].filter(Boolean).join('');
    if (kind === 'owners') { const addr = [x.address, x.city].filter(Boolean).join(', '); return [A(MAPS(addr), '📍', 'Map'), A(GOOG(addr + ' ' + (x.use_desc || '') + ' owner'), '🔎', 'Owner / deal'), A('https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=' + enc(addr), '📸', 'Street View'), A(ASSR(x.ain), '🏛️', 'Assessor')].join(''); }
    return [A(LI_P(x.name, x.firm_name), '👤', 'LinkedIn'), A(GOOG(x.name + ' ' + (x.firm_name || '') + ' ' + loc(x)), '🔎', 'Google'), x.firm_name ? A(WEB(x.firm_name), '🌐', 'Firm site') : '', x.firm_name ? A(LI_C(x.firm_name), '🏢', 'Firm') : '', loc(x) ? A(MAPS((x.firm_name || x.name) + ' ' + loc(x)), '📍', 'Map') : '', x.license_no ? A(DRE(x.license_no), '🪪', 'DRE') : ''].filter(Boolean).join('');
  }
  const nm = x => x.name || x.address || x.ain;
  const sub = (kind, x) => kind === 'brokers' ? (x.firm_name || '—') : kind === 'firms' ? ((x.agent_count || 0).toLocaleString() + ' agents') : (x.type_label || '');

  async function load() {
    const get = (f, fb) => fetch('data/' + f).then(r => r.json()).catch(() => fb);
    const [b, f, la] = await Promise.all([get('brokers.json', { rows: [] }), get('firms.json', { rows: [] }), get('la-commercial.json', { marquee: [] })]);
    return {
      brokers: b.rows || [], firms: f.rows || [], owners: la.marquee || [],
      totalB: b.total || (b.rows || []).length, totalF: f.total || (f.rows || []).length,
    };
  }
  // preload data FIRST, then mount chrome with a synchronous render → numbering sees the full DOM
  async function mount(layout, render) {
    const d = await load();
    RENTV.mount({ dark: true, layout, render: () => render(d) });
  }
  return { esc, LI_P, LI_C, WEB, MAPS, DRE, GOOG, ASSR, loc, A, actions, nm, sub, load, mount };
})();