[object Object]

← back to Wallco Ai

admin-card: add created date+time chip to dogs-curator + return created_at from dogs/list API (cactus-curator convention)

08a8775e9a17fbb7de6de0799a16d3e6586948be · 2026-05-27 14:56:27 -0700 · Steve

Files touched

Diff

commit 08a8775e9a17fbb7de6de0799a16d3e6586948be
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed May 27 14:56:27 2026 -0700

    admin-card: add created date+time chip to dogs-curator + return created_at from dogs/list API (cactus-curator convention)
---
 public/admin/dogs-curator.html | 11 ++++++++++-
 server.js                      |  2 +-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/public/admin/dogs-curator.html b/public/admin/dogs-curator.html
index e461c51..4058822 100644
--- a/public/admin/dogs-curator.html
+++ b/public/admin/dogs-curator.html
@@ -46,6 +46,9 @@
   .chip .pick { position:absolute; bottom:6px; right:6px; width:22px; height:22px; border-radius:50%;
           background:#000a; display:flex; align-items:center; justify-content:center; font-size:13px; }
   .chip.keep .pick { background:var(--pass); color:#0c1a10; }
+  .chip .when { position:absolute; left:0; right:0; bottom:0; padding:3px 6px; background:rgba(13,11,9,.78);
+          color:var(--muted); font-size:10.5px; font-variant-numeric:tabular-nums; letter-spacing:.02em;
+          white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
   footer { position:fixed; bottom:0; left:0; right:0; background:rgba(20,17,14,.97);
            border-top:1px solid var(--line); padding:12px 22px; display:flex; gap:12px; align-items:center; z-index:30; }
   footer .grow { flex:1; }
@@ -90,6 +93,11 @@
 const state = { items: [], keep: new Set(), hideFail: false };
 const $ = s => document.querySelector(s);
 const breedOf = c => (c || '').replace(/^dogs · /, '').replace(/-/g, ' ');
+function fmtDate(iso){
+  if(!iso) return '—';
+  const d = new Date(iso); if(isNaN(d)) return '—';
+  return d.toLocaleString(undefined, { year:'numeric', month:'short', day:'numeric', hour:'numeric', minute:'2-digit' });
+}
 
 function hueOf(hex){ if(!/^#?[0-9a-f]{6}$/i.test(hex||'')) return 999;
   const n=hex.replace('#',''); const r=parseInt(n.slice(0,2),16)/255,g=parseInt(n.slice(2,4),16)/255,b=parseInt(n.slice(4,6),16)/255;
@@ -151,7 +159,8 @@ function chip(d){
   el.innerHTML=`<img loading="lazy" src="/designs/img/by-id/${d.id}" alt="#${d.id}">
     <span class="badge ${d.edges}">${d.edges||'?'}</span>
     <span class="live">LIVE</span>
-    <span class="pick">${state.keep.has(d.id)?'✓':''}</span>`;
+    <span class="pick">${state.keep.has(d.id)?'✓':''}</span>
+    <div class="when" title="created ${d.created_at||''}">🕓 ${fmtDate(d.created_at)}</div>`;
   el.title=`#${d.id} · ${breedOf(d.category)} · edges ${d.edges||'?'}${d.is_published?' · LIVE':''}`;
   el.onclick=()=>{ if(state.keep.has(d.id))state.keep.delete(d.id); else state.keep.add(d.id);
     el.classList.toggle('keep'); el.classList.toggle('reject');
diff --git a/server.js b/server.js
index 153822d..42d2e08 100644
--- a/server.js
+++ b/server.js
@@ -1096,7 +1096,7 @@ app.get('/api/admin/dogs/list', (req, res) => {
   try {
     const rawJson = psqlQuery(
       "SELECT COALESCE(json_agg(t ORDER BY t.category, t.id), '[]'::json) FROM (" +
-        "SELECT id, category, dominant_hex, is_published, " +
+        "SELECT id, category, dominant_hex, is_published, created_at, " +
         "COALESCE(split_part(notes,'DOGS_EDGES:',2),'') AS edges " +
         "FROM spoon_all_designs WHERE category LIKE 'dogs · %' " +
         // exclude seam-healer derivatives (blurred seam line / fuzzy edges)

← 899e7fd Task 31: circular-padding is now the DEFAULT for all seamles  ·  back to Wallco Ai  ·  admin-card: add created/flagged date+time chip to ghost-revi f35bb2b →