← back to Lifestyle Asset Intel
yolo tick #19: condition_facets chips on asset detail comps
9cba52d26ecc50bfd6ddf1e7b6c774821c36060f · 2026-05-13 13:46:14 -0700 · Steve Abrams
Files touched
M public/css/app.cssM views/asset.ejs
Diff
commit 9cba52d26ecc50bfd6ddf1e7b6c774821c36060f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed May 13 13:46:14 2026 -0700
yolo tick #19: condition_facets chips on asset detail comps
---
public/css/app.css | 20 ++++++++++++++++++++
views/asset.ejs | 32 +++++++++++++++++++++++++++++++-
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/public/css/app.css b/public/css/app.css
index 7a14d54..d02a5ca 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -193,6 +193,26 @@ tfoot tr.totals th, tfoot tr.totals td {
.exotic-badge { background: color-mix(in srgb, var(--accent) 22%, var(--card)); color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 50%, var(--line)); }
.edition-badge { background: color-mix(in srgb, var(--warn) 22%, var(--card)); color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 50%, var(--line)); }
+/* condition facet chips on asset detail comp rows (v0.2) */
+.facets-row {
+ display: flex; flex-wrap: wrap; gap: 0.3rem;
+ margin-top: 0.3rem; max-width: 36rem;
+}
+.facet-chip {
+ display: inline-flex; align-items: center; gap: 0.3rem;
+ font-size: 0.72em; line-height: 1;
+ padding: 0.2rem 0.45rem; border-radius: 999px;
+ background: var(--card); color: var(--muted);
+ border: 1px solid var(--line);
+ font-family: var(--mono);
+}
+.facet-chip .facet-k { color: var(--muted); }
+.facet-chip .facet-v { color: var(--fg); font-weight: 600; }
+.facet-chip.facet-true { background: color-mix(in srgb, var(--good) 14%, var(--card)); border-color: color-mix(in srgb, var(--good) 35%, var(--line)); }
+.facet-chip.facet-true .facet-v { color: var(--good); }
+.facet-chip.facet-false { background: color-mix(in srgb, var(--bad) 10%, var(--card)); border-color: color-mix(in srgb, var(--bad) 30%, var(--line)); }
+.facet-chip.facet-false .facet-v { color: var(--bad); }
+
/* MSRP / premium-to-retail block (v0.2) */
.msrp-block .premium-cell { background: color-mix(in srgb, var(--accent) 14%, var(--card)); border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }
.msrp-block .premium-val { color: var(--accent); font-size: 1.05em; }
diff --git a/views/asset.ejs b/views/asset.ejs
index 5e5bfb6..ccd2832 100644
--- a/views/asset.ejs
+++ b/views/asset.ejs
@@ -103,7 +103,10 @@
<td><%= fmtDate(c.transacted_at) %></td>
<td><%= c.source %></td>
<td>T<%= c.source_tier %></td>
- <td><%= grade(c.condition_grade) %></td>
+ <td>
+ <%= grade(c.condition_grade) %>
+ <%- facetChips(c.condition_facets) %>
+ </td>
<td class="num">$<%= money(c.gross) %></td>
<td class="num">$<%= money(c.net) %></td>
</tr>
@@ -141,5 +144,32 @@ function pct(v){ if(v==null||v==='') return '—'; var n=parseFloat(v); return i
function numFmt(v){ if(v==null) return '—'; var n=parseFloat(v); return isFinite(n)?n.toFixed(2):String(v); }
function fmtDate(v){ if(!v) return '—'; try { return new Date(v).toISOString().slice(0,10); } catch(e){ return String(v); } }
function grade(g){ const labels=['As Is','Fair','Good','Very Good','Excellent','Pristine','Giftable']; return (g==null) ? '—' : (labels[g] || g); }
+function htmlEscape(s){ return String(s).replace(/[&<>"']/g, function(ch){ return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[ch]; }); }
+function facetLabel(k){ return k.replace(/_/g,' '); }
+function facetValue(v){
+ if (v === true) return '✓';
+ if (v === false) return '✗';
+ if (v == null) return '—';
+ return String(v);
+}
+function facetChips(f){
+ if (!f || typeof f !== 'object') return '';
+ var keys = Object.keys(f);
+ if (!keys.length) return '';
+ var html = '<div class="facets-row">';
+ for (var i=0;i<keys.length;i++){
+ var k = keys[i], v = f[k];
+ var cls = 'facet-chip';
+ if (v === true) cls += ' facet-true';
+ else if (v === false) cls += ' facet-false';
+ html += '<span class="' + cls + '" title="' + htmlEscape(k) + ': ' + htmlEscape(facetValue(v)) + '">';
+ html += '<span class="facet-k">' + htmlEscape(facetLabel(k)) + '</span>';
+ if (typeof v !== 'boolean') html += '<span class="facet-v">' + htmlEscape(facetValue(v)) + '</span>';
+ else html += '<span class="facet-v">' + htmlEscape(facetValue(v)) + '</span>';
+ html += '</span>';
+ }
+ html += '</div>';
+ return html;
+}
%>
<%- include('partials/foot') %>
← ced9794 yolo tick #18: /admin/audit HTML view over recent valuation_
·
back to Lifestyle Asset Intel
·
yolo tick #20: sparkline Y-axis min/max labels + descriptive 39ba614 →