[object Object]

← back to Commercialrealestate

condos: add color-coded 'Days to expiry' field (live calc from FHA expiration)

41ae00f7ba779687319c36f748e5ed961f1811e1 · 2026-08-07 15:50:16 -0700 · Steve Abrams

Computed client-side from fha_expiration_date vs today so it never goes stale;
negative = lapsed N days ago. Rendered as a color-coded badge in fcell (red=lapsed,
gold<=90d, green further out) on both list columns and cards; sorts numerically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 41ae00f7ba779687319c36f748e5ed961f1811e1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Aug 7 15:50:16 2026 -0700

    condos: add color-coded 'Days to expiry' field (live calc from FHA expiration)
    
    Computed client-side from fha_expiration_date vs today so it never goes stale;
    negative = lapsed N days ago. Rendered as a color-coded badge in fcell (red=lapsed,
    gold<=90d, green further out) on both list columns and cards; sorts numerically.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 public/condos.html | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/public/condos.html b/public/condos.html
index 8b3770d..d0e7e0e 100644
--- a/public/condos.html
+++ b/public/condos.html
@@ -216,6 +216,15 @@ const FIELDS=[
   // server from warrant_source (listings) or expiration_date (FHA directory). Plain string, not date:1
   // (the value is date-only, so the datetime formatter would tack on a bogus "12:00 AM").
   {k:'fha_expiration_date', l:'FHA expires', col:1},
+  // Days until FHA approval expires, computed live from fha_expiration_date against today (so it's
+  // never stale). Negative = already lapsed N days ago. Rendered as a color-coded badge in fcell
+  // (red = expired, gold = ≤90d, green = further out). calc returns a Number so List-sort is numeric.
+  {k:'days_to_expiry', l:'Days to expiry', col:1, calc:c=>{
+    const m=String(c.fha_expiration_date||'').match(/(\d{2})\/(\d{2})\/(\d{4})/); if(!m) return null;
+    const exp=new Date(+m[3],+m[1]-1,+m[2]); exp.setHours(0,0,0,0);
+    const t=new Date(); t.setHours(0,0,0,0);
+    return Math.round((exp-t)/86400000);
+  }},
   {k:'city',        l:'City',                  col:1},
   {k:'hoa',         l:'HOA/mo',       money:1, col:1, suf:'/mo'},
   {k:'beds',        l:'Beds',                  col:1},
@@ -303,6 +312,12 @@ function fcell(c,f){ const v=fval(c,f);
   if(f.k==='responsible_broker'){ const rb=respBroker(c); return rb?esc(rb):'—'; }
   if(f.k==='buyer_agent'){ const ba=buyerAgents(c); if(!ba.length) return '—';
     return ba.map(a=>{ const dre=a.dre?` · DRE# ${esc(a.dre)}`:''; return esc(a.name||'')+(a.firm?' · '+esc(a.firm):'')+dre; }).join('<br>'); }
+  // days-to-expiry: color-coded badge (red=lapsed, gold=≤90d, green=further out). Its own null-guard
+  // so a listing with no matched FHA cert reads '—' rather than a bogus 0.
+  if(f.k==='days_to_expiry'){ if(v==null||v==='') return '—'; const d=+v; const dt=esc(c.fha_expiration_date||'');
+    const col=d<0?'var(--red)':(d<=90?'var(--gold)':'var(--acc)');
+    const txt=d<0?(-d).toLocaleString()+'d ago':'in '+d.toLocaleString()+'d';
+    return `<span title="FHA ${d<0?'expired':'expires'} ${dt}" style="color:${col};font-weight:600;white-space:nowrap">${txt}</span>`; }
   if(v==null||v==='') return '—';
   if(f.money) return '$'+(+v).toLocaleString()+(f.suf||'');
   if(f.num) return (+v).toLocaleString();

← 4edfac9 condos: surface FHA expiration date as a toggleable grid col  ·  back to Commercialrealestate  ·  auto-data-snapshot: 2026-08-07T15:54:54 (13 data files) — da 0f76d8b →