← back to Rentv 2026
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>