/**
* 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 =
'';
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 =
'';
}
});
}
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);
})();