Request Management Portal
Request Management
View Your Sell Request
Enter your Request ID and the email address used when submitting to access your request status.
Request ID
Work Email
function fmtDate(ts) { if (!ts) return null; return new Date(ts).toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'}); } function fmtUsd(v) { if (v == null || v === '') return '—'; return '$' + Number(v).toLocaleString('en-US',{maximumFractionDigits:0}); } function show(id) { document.getElementById(id).style.display = 'block'; } function hide(id) { document.getElementById(id).style.display = 'none'; } function text(id, v) { document.getElementById(id).textContent = v; } function escHtml(str) { return str.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } window.addEventListener('DOMContentLoaded', () => { const p = new URLSearchParams(window.location.search); const id = p.get('id'); if (id) document.getElementById('inputId').value = id.toUpperCase(); }); async function lookup() { const reqId = document.getElementById('inputId').value.trim().toUpperCase(); const email = document.getElementById('inputEmail').value.trim().toLowerCase(); const errEl = document.getElementById('lookupError'); if (!reqId || !email) { errEl.textContent = 'Please enter both your Request ID and work email.'; errEl.style.display = 'block'; return; } errEl.style.display = 'none'; hide('lookupView'); show('loadingView'); try { const res = await fetch(`${SUPABASE_URL}/rest/v1/seller_submissions?submission_ref=eq.${encodeURIComponent(reqId)}&select=*`, { headers: { apikey: SUPABASE_KEY, Authorization: `Bearer ${SUPABASE_KEY}` } }); const data = await res.json(); if (!data || data.length === 0) throw new Error('not_found'); const sub = data[0]; if (sub.email.toLowerCase() !== email) throw new Error('not_found'); hide('loadingView'); renderRequest(sub); show('requestView'); loadOffers(sub); loadMarketIntel(sub); loadDemandSignals(sub); } catch(e) { hide('loadingView'); show('lookupView'); const errEl = document.getElementById('lookupError'); errEl.textContent = 'No request found matching that ID and email. Please check your details and try again.'; errEl.style.display = 'block'; } } function renderRequest(sub) { const status = sub.status; text('reqTitle', sub.model_name); text('reqId', sub.submission_ref); text('reqMeta', `${sub.quantity} unit${sub.quantity !== 1 ? 's' : ''} · ${sub.hardware_location} · Submitted ${fmtDate(sub.created_at)}`); const badgeMap = { received: ['Under Review', 'status-received'], listed: ['Actively Listed', 'status-listed'], offer_received: ['Offer Received', 'status-offer_received'], sold: ['Closed', 'status-sold'], expired: ['Expired', 'status-received'], archived: ['Archived', 'status-received'], }; const [label, cls] = badgeMap[status] || ['Unknown','status-received']; document.getElementById('reqStatusBadge').innerHTML = `${label}`; const idx = PIPELINE_ORDER.indexOf(status); PIPELINE_ORDER.forEach((s, i) => { const el = document.getElementById('ps-' + s); const tsEl = document.getElementById('pts-' + s); el.className = i < idx ? 'pipeline-step done' : i === idx ? 'pipeline-step active' : 'pipeline-step'; const tsMap = { received: sub.created_at, listed: sub.listed_at, offer_received: sub.offer_received_at, sold: sub.sold_at }; tsEl.textContent = tsMap[s] ? fmtDate(tsMap[s]) : '—'; }); if (status === 'sold') show('soldBlock'); if (sub.seller_notes) { text('notesText', sub.seller_notes); text('notesTs', `From the desk · ${fmtDate(sub.reviewed_at || sub.created_at)}`); show('notesBlock'); } text('dModel', sub.model_name); text('dMfr', sub.manufacturer); text('dQty', `${sub.quantity} unit${sub.quantity !== 1 ? 's' : ''}`); text('dCond', sub.condition_grade); text('dLoc', sub.hardware_location); text('dAsk', fmtUsd(Number(sub.asking_price_usd) * sub.quantity) + ` total · ${fmtUsd(sub.asking_price_usd)}/unit`); const events = [ { label: 'Request Received', ts: sub.created_at }, { label: 'Listed to Network', ts: sub.listed_at }, { label: 'Offer Received', ts: sub.offer_received_at }, { label: 'Transaction Closed', ts: sub.sold_at }, ]; document.getElementById('trail').innerHTML = events.map(e => `
${e.label}
${e.ts ? fmtDate(e.ts) : 'Pending'}
`).join(''); window._currentSub = sub; } async function loadMarketIntel(sub) { try { const model = (sub.model_name || '').toLowerCase().replace(/\s+/g, ''); const res = await fetch( `${SUPABASE_URL}/rest/v1/market_comps?model_slug=eq.${encodeURIComponent(model)}&select=*&limit=1`, { headers: { apikey: SUPABASE_KEY, Authorization: `Bearer ${SUPABASE_KEY}` } } ); const data = await res.json(); if (!data || data.length === 0) return; const mc = data[0]; const asking = Number(sub.asking_price_usd); const median = Number(mc.median_ask_usd); const delta = median ? ((asking - median) / median * 100) : null; const deltaStr = delta !== null ? `${delta > 0 ? '+' : ''}${delta.toFixed(1)}%` : '—'; const deltaClass = delta === null ? '' : delta < -5 ? 'green' : delta > 10 ? 'red' : 'yellow'; document.getElementById('marketIntelGrid').innerHTML = `
Market median
${mc.median_ask_usd ? fmtUsd(mc.median_ask_usd) : '—'}
Your price vs median
${deltaStr}
Market range (P25–P75)
${mc.p25_ask_usd && mc.p75_ask_usd ? fmtUsd(mc.p25_ask_usd) + ' – ' + fmtUsd(mc.p75_ask_usd) : '—'}
Comparable listings
${mc.obs_count ? mc.obs_count + ' obs' : '—'}
`; document.getElementById('marketIntelSection').style.display = 'block'; } catch(e) { /* silently skip if no market data */ } } async function loadDemandSignals(sub) { try { const model = (sub.model_name || '').toLowerCase().replace(/\s+/g, ''); const res = await fetch( `${SUPABASE_URL}/rest/v1/demand_signals?model_name=eq.${encodeURIComponent(model)}&status=eq.new&select=id`, { headers: { apikey: SUPABASE_KEY, Authorization: `Bearer ${SUPABASE_KEY}`, 'Prefer': 'count=exact', 'Range-Unit': 'items', 'Range': '0-0' } } ); const countHeader = res.headers.get('content-range'); const total = countHeader ? parseInt(countHeader.split('/')[1]) : 0; if (total === 0) return; document.getElementById('demandCount').textContent = total; document.getElementById('demandLabel').textContent = `Active buyer${total !== 1 ? 's' : ''} in market`; document.getElementById('demandSub').textContent = total === 1 ? 'One buyer is actively looking for this model across monitored channels.' : `${total} buyers are actively looking for this model across monitored channels.`; document.getElementById('demandSection').style.display = 'block'; } catch(e) { /* silently skip */ } } async function loadOffers(sub) { const section = document.getElementById('offersSection'); const body = document.getElementById('offersBody'); try { const res = await fetch(`${SUPABASE_URL}/rest/v1/offers?submission_id=eq.${sub.id}&order=created_at.desc`, { headers: { apikey: SUPABASE_KEY, Authorization: `Bearer ${SUPABASE_KEY}` } }); const offers = await res.json(); if (!offers || offers.length === 0) { if (['listed','offer_received','sold'].includes(sub.status)) { section.style.display = 'block'; body.innerHTML = '
No offers posted yet. The desk will notify you when a buyer offer is available.
'; } return; } section.style.display = 'block'; body.innerHTML = offers.map(o => renderOfferCard(o, sub)).join(''); } catch(e) { section.style.display = 'block'; body.innerHTML = '
Unable to load offers. Please refresh.
'; } } function renderOfferCard(o, sub) { const perUnit = sub.quantity > 1 ? ` · ${fmtUsd(Math.round(Number(o.amount_usd) / sub.quantity))}/unit` : ''; const expiry = o.expiry_date ? ` · Expires ${new Date(o.expiry_date).toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'})}` : ''; const pillMap = { pending:'pill-pending', accepted:'pill-accepted', declined:'pill-declined' }; const pillCls = pillMap[o.status] || 'pill-pending'; const pillLabel = o.status.charAt(0).toUpperCase() + o.status.slice(1); const notesHtml = o.notes ? `
${escHtml(o.notes)}
` : ''; let actionsHtml = ''; if (o.status === 'pending') { actionsHtml = `
`; } else if (o.status === 'accepted') { actionsHtml = '
✓ You accepted this offer — the desk will be in touch shortly.
'; } else if (o.status === 'declined') { actionsHtml = '
You declined this offer. The desk will follow up with alternatives.
'; } return `
${fmtUsd(o.amount_usd)}
${pillLabel}
${sub.quantity} unit${sub.quantity !== 1 ? 's' : ''}${perUnit}${expiry} · Posted ${fmtDate(o.created_at)}
${notesHtml} ${actionsHtml}
`; } async function respondOffer(offerId, response) { const confirmMsg = response === 'accepted' ? 'Confirm you wish to accept this offer. The desk will follow up to coordinate next steps.' : 'Confirm you wish to decline this offer. The desk will be notified.'; if (!confirm(confirmMsg)) return; await fetch(`${SUPABASE_URL}/rest/v1/offers?id=eq.${offerId}`, { method: 'PATCH', headers: { apikey: SUPABASE_KEY, Authorization: `Bearer ${SUPABASE_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ status: response, responded_at: new Date().toISOString() }), }); const card = document.getElementById('offer-card-' + offerId); if (card) { const el = card.querySelector('.offer-card-actions, .offer-responded-msg'); if (response === 'accepted') { el.outerHTML = '
✓ You accepted this offer — the desk will be in touch shortly.
'; card.querySelector('.offer-pill').className = 'offer-pill pill-accepted'; card.querySelector('.offer-pill').textContent = 'Accepted'; } else { el.outerHTML = '
You declined this offer. The desk will follow up with alternatives.
'; card.querySelector('.offer-pill').className = 'offer-pill pill-declined'; card.querySelector('.offer-pill').textContent = 'Declined'; } } } function resetView() { hide('requestView'); hide('soldBlock'); hide('notesBlock'); document.getElementById('offersSection').style.display = 'none'; document.getElementById('offersBody').innerHTML = '
Loading…
'; document.getElementById('inputId').value = ''; document.getElementById('inputEmail').value = ''; show('lookupView'); }