{ const s = typeof v==='object'?JSON.stringify(v??''):String(v??''); return s.includes(',')||s.includes('"')||s.includes('\n') ? `"${s.replace(/"/g,'""')}"` : s; }; const csv = [headers.join(','), ...rows.map(r=>headers.map(h=>escape(r[h])).join(','))].join('\n'); try { const blob = new Blob([csv],{type:'text/csv'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href=url; a.download=filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(()=>URL.revokeObjectURL(url),1000); } catch(e) { // Fallback: open in new tab const w = window.open('','_blank'); if(w){ w.document.write('
'+csv+'
'); w.document.title=filename; } } } function exportAssetsCSV(assets) { return exportCSV( `stateway_assets_${new Date().toISOString().slice(0,10)}.csv`, assets.map(a=>({ ID:a.id, Name:a.name, Type:a.type, Country:a.country, City:a.city, Risk:a.risk, ATLAS_Score:a.as, Yield_Pct:a.yld, Valuation_Mid_TZS:a.vM, Valuation_Low_TZS:a.vL, Valuation_High_TZS:a.vH, NOI_Monthly_TZS:a.noi, Occupancy:a.occ, Documentation:a.docs, })) ); } function exportDealsCSV(deals) { return exportCSV( `stateway_pipeline_${new Date().toISOString().slice(0,10)}.csv`, deals.map(d=>({ ID:d.id, Name:d.name, Stage:d.stage, Type:d.type, Amount:d.amt, Currency:d.cur, IRR_Pct:d.irr, Tenor_Years:d.tenor, Counterparty:d.cp, })) ); } function exportAuditCSV(logs) { return exportCSV( `stateway_audit_${new Date().toISOString().slice(0,10)}.csv`, logs.map(l=>({ Timestamp:l.created_at||l.ts, Action:l.action_type||l.action, Module:l.module, Reference:l.reference_id||l.ref, User:l.user_id||l.user, Role:l.user_role||l.role, })) ); } function exportDecisionsCSV(decisions) { return exportCSV( `stateway_decisions_${new Date().toISOString().slice(0,10)}.csv`, decisions.map(d=>({ Session_ID:d.sessionId, Decision:d.decision, Asset:d.asset?.name||d.assetId, Confidence_Pct:d.confidence, Allocation_Cap_Pct:d.cap, Reason:d.reason, Decided_At:d.decidedAt, })) ); } >