/** * LPS-1 Parcel Marketplace — integrated GMIIE desk UI */ (function () { 'use strict'; var grid = document.getElementById('mk-parcel-grid'); var resetEl = document.getElementById('mk-reset-status'); var igniteBtn = document.getElementById('mk-ignite-reset'); var refreshBtn = document.getElementById('mk-refresh'); function esc(s) { return String(s || '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function setMon(id, val, on) { var el = document.getElementById(id); if (!el) return; el.textContent = val; if (on) el.classList.add('on'); else el.classList.remove('on'); } function renderCard(art) { var card = document.createElement('article'); card.className = 'lps-card'; card.setAttribute('data-brief', art.brief_id || ''); var title = art.title || art.brief_id || 'Parcel'; var meta = 'Escrow ' + esc(art.escrow_tx || '—') + ' · APR ' + esc(art.treasury_apr || '—') + ' · ' + esc(art.status || '—'); card.innerHTML = '

' + esc(title) + '

' + '
' + esc(art.brief_id) + (art.lps1_registration_id ? ' · ' + esc(art.lps1_registration_id) : '') + '
' + '
' + meta + '
' + '
Condition: ' + esc((art.condition || '').slice(0, 32)) + (art.condition && art.condition.length > 32 ? '…' : '') + '
' + '
' + '
' + (art.status === 'locked' ? '' : 'Yield released') + 'Verify' + '
'; var host = card.querySelector('.lps-mint-host'); if (window.GMIIELpsMint && art.brief_id) { window.GMIIELpsMint.renderButton(host, { briefId: art.brief_id, title: title, lps1Id: art.lps1_registration_id, compact: true, }); } return card; } function wireFinishButtons() { grid.querySelectorAll('.mk-finish').forEach(function (btn) { btn.addEventListener('click', function () { var briefId = btn.getAttribute('data-brief'); btn.disabled = true; btn.textContent = 'Claiming…'; fetch('/api/lps/escrow-finish', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ brief_id: briefId }), }) .then(function (r) { return r.json(); }) .then(function (d) { if (d.ok) { btn.textContent = 'Released'; load(); } else { btn.textContent = d.error || 'Failed'; btn.disabled = false; } }) .catch(function () { btn.textContent = 'Error'; btn.disabled = false; }); }); }); } function load() { Promise.all([ fetch('/api/lps/marketplace', { cache: 'no-store' }).then(function (r) { return r.json(); }), fetch('/api/lps/monitor', { cache: 'no-store' }).then(function (r) { return r.json(); }), fetch('/api/articles?limit=30', { cache: 'no-store' }).then(function (r) { return r.ok ? r.json() : { articles: [] }; }), ]) .then(function (results) { var data = results[0]; var monitor = results[1]; var articles = results[2].articles || []; var titleById = {}; articles.forEach(function (a) { titleById[a.id] = a.title; }); if (resetEl) { resetEl.textContent = data.reset_mode ? 'Reset mode active · Public marketplace open' : 'Reset mode off · Mint briefs to list parcels here'; resetEl.classList.toggle('on', !!data.reset_mode); } setMon('mk-mon-reset', monitor.reset_mode ? 'ON' : 'OFF', monitor.reset_mode); setMon('mk-mon-r5', monitor.r5_fract != null ? String(monitor.r5_fract) : '—', monitor.stress_active); setMon('mk-mon-parcels', String((data.parcels || []).length), (data.parcels || []).length > 0); setMon('mk-mon-briefs', monitor.brief_count != null ? String(monitor.brief_count) : '—', true); var parcels = data.parcels || []; if (!grid) return; grid.innerHTML = ''; if (!parcels.length) { grid.innerHTML = '
No parcels yet

Mint a brief from the Mint Console or Pulse feed to list your first yield parcel here.

'; return; } parcels.forEach(function (p) { p.title = titleById[p.brief_id] || p.brief_id; grid.appendChild(renderCard(p)); }); wireFinishButtons(); }) .catch(function () { if (grid) { grid.innerHTML = '
Desk offline

Could not reach marketplace API. Try Query Console.

'; } }); } if (igniteBtn) { igniteBtn.addEventListener('click', function () { if ( !confirm( 'Ignite full reset mode? Backfills provenance, runs stress + agents, opens public marketplace.', ) ) { return; } igniteBtn.disabled = true; igniteBtn.textContent = 'Igniting…'; fetch('/api/lps/reset-mode', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ run_pipeline: true }), }) .then(function (r) { return r.json(); }) .then(function (d) { igniteBtn.textContent = d.status || 'Ignited'; load(); }) .catch(function () { igniteBtn.textContent = 'Failed'; igniteBtn.disabled = false; }); }); } if (refreshBtn) refreshBtn.addEventListener('click', load); load(); setInterval(load, 30000); })();