← back to Rentv

mockups/admin/A03.html

66 lines

<!doctype html><html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>A03 · Master-Detail — RENTV Admin</title>
<link rel="stylesheet" href="../assets/base.css"><link rel="stylesheet" href="admin.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
  body{background:#0d1014;color:#e7ecf1;font-family:'Inter',system-ui,sans-serif}
  .split{display:grid;grid-template-columns:380px 1fr;height:calc(100vh - 52px)}
  .master{border-right:1px solid #232a32;display:flex;flex-direction:column;min-height:0}
  .msearch{padding:12px;border-bottom:1px solid #232a32}
  .msearch input{width:100%;background:#11161c;border:1px solid #232a32;border-radius:9px;color:#e7ecf1;padding:10px 12px;font:inherit}
  .mtabs{display:flex;gap:4px;padding:8px 12px 0}
  .mtabs button{background:none;border:0;color:#8b939b;font:800 12px system-ui;padding:7px 10px;cursor:pointer;border-radius:7px}.mtabs button.on{color:#fff;background:#11161c}
  .mlist{overflow-y:auto;flex:1}
  .mrow{padding:12px 14px;border-bottom:1px solid #171d24;cursor:pointer}
  .mrow:hover{background:#141b22}.mrow.sel{background:#11161c;border-left:3px solid #c8102e}
  .mrow .nm{font-weight:700;font-size:14px}.mrow .f{font-size:12px;color:#9aa4ad;margin-top:2px}
  .detail{overflow-y:auto;padding:34px 40px}
  .detail .k{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#c8102e;font-weight:800}
  .detail h2{font-size:34px;font-weight:800;margin:6px 0 4px;letter-spacing:-.5px}
  .detail .meta{color:#9aa4ad;font-size:15px}
  .detail .acts{margin:22px 0}
  .detail .grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:20px}
  .detail .cell{background:#11161c;border:1px solid #232a32;border-radius:10px;padding:14px}
  .detail .cell .kk{font-size:11px;color:#8b939b;text-transform:uppercase;letter-spacing:.05em}.detail .cell .vv{font-size:18px;font-weight:700;margin-top:3px}
  @media(max-width:820px){.split{grid-template-columns:1fr;height:auto}.master{height:50vh}}
</style></head>
<body>
<div class="split">
  <div class="master">
    <div class="msearch" data-eln><input id="q" placeholder="Search the registry…"></div>
    <div class="mtabs" data-eln id="tabs"><button data-tab="brokers" class="on">Brokers</button><button data-tab="firms">Firms</button><button data-tab="owners">Owners</button></div>
    <div class="mlist" data-eln id="mlist"></div>
  </div>
  <div class="detail" data-eln id="detail"></div>
</div>
<script src="../assets/chrome.js"></script><script src="admin-core.js"></script>
<script>
let S={tab:'brokers',sel:0};
ADM.mount('A03', d=>{
  S.d=d;const esc=ADM.esc;
  function items(){let r=(S.tab==='brokers'?d.brokers:S.tab==='firms'?d.firms:d.owners).slice();const q=(document.getElementById('q').value||'').toLowerCase();if(q)r=r.filter(x=>JSON.stringify(x).toLowerCase().includes(q));return r;}
  function detail(x){
    if(!x){document.getElementById('detail').innerHTML='<p style="color:#6b747d">Select a record.</p>';return;}
    const grid=S.tab==='owners'
      ? [['Assessed',RENTV.shortUsd(x.assessed_total)],['SqFt',(x.sqft||0).toLocaleString()],['Built',x.year_built||'—'],['AIN',x.ain]]
      : S.tab==='firms'
      ? [['Agents',(x.agent_count||0).toLocaleString()],['HQ',ADM.loc(x)||'—'],['License',x.license_no||'—'],['Source',x.source||'—']]
      : [['License',x.license_no||'—'],['Type',x.license_type||'—'],['Firm',x.firm_name||'—'],['City',x.city||'—']];
    document.getElementById('detail').innerHTML=`<div class="k">${esc(S.tab==='owners'?(x.type_label||'Asset'):S.tab==='firms'?'Brokerage':(x.license_type||'Licensee'))}</div>
      <h2>${esc(ADM.nm(x))}</h2><div class="meta">${esc(S.tab==='owners'?[x.address,x.city].filter(Boolean).join(', '):(ADM.sub(S.tab,x)+' · '+(ADM.loc(x)||'')))}</div>
      <div class="acts">${ADM.actions(S.tab,x)}</div>
      <div class="grid">${grid.map(([k,v])=>`<div class="cell"><div class="kk">${k}</div><div class="vv">${esc(v)}</div></div>`).join('')}</div>`;
  }
  function render(){
    const r=items();
    document.getElementById('mlist').innerHTML=r.map((x,i)=>`<div class="mrow${i===S.sel?' sel':''}" data-i="${i}"><div class="nm">${esc(ADM.nm(x))}</div><div class="f">${esc(ADM.sub(S.tab,x))}</div></div>`).join('');
    document.querySelectorAll('.mrow').forEach(row=>row.onclick=()=>{S.sel=+row.dataset.i;document.querySelectorAll('.mrow').forEach(x=>x.classList.remove('sel'));row.classList.add('sel');detail(r[S.sel]);});
    detail(r[S.sel]||r[0]);
  }
  document.getElementById('tabs').onclick=e=>{const b=e.target.closest('button');if(!b)return;document.querySelectorAll('#tabs button').forEach(x=>x.classList.remove('on'));b.classList.add('on');S.tab=b.dataset.tab;S.sel=0;render();};
  document.getElementById('q').oninput=()=>{S.sel=0;render();};
  render();
});
</script></body></html>