From 4c51a00c9f1faafbb8f3f0ca1abe39536e536a7b Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 20 Jul 2026 19:27:50 +0200 Subject: [PATCH] fix(#2612): parse ISO due_at string before arithmetic in loose-ends panel The Reminder loose-end variant's due_at field is serialized as an ISO 8601 string (DateTime on the wire), but the JS was doing: const dueIn = (t.due_at || 0) - now; A string minus a number is NaN in JS, so fmtAge(NaN) returned 'NaNd', producing the 'due NaNd overdue' label seen in the screenshot. Fix: parse the ISO string to unix seconds with new Date(...).getTime() / 1000 before the subtraction. --- frontend/packages/agent/src/app.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/packages/agent/src/app.js b/frontend/packages/agent/src/app.js index da1812d7..5790915b 100644 --- a/frontend/packages/agent/src/app.js +++ b/frontend/packages/agent/src/app.js @@ -894,10 +894,12 @@ window.marked = marked; buildAnswerForm(t.id), ); } else if (t.kind === 'reminder') { - // due_at is an absolute unix-seconds value; show time-until-fire - // (negative when overdue, fmtAge handles 0/positive case here). + // due_at arrives as an ISO 8601 string (DateTime on the wire). + // Parse it to unix seconds before arithmetic — doing `t.due_at - now` + // directly yields NaN because a string minus a number is NaN in JS. const now = Math.floor(Date.now() / 1000); - const dueIn = (t.due_at || 0) - now; + const dueAtSec = t.due_at ? Math.floor(new Date(t.due_at).getTime() / 1000) : 0; + const dueIn = dueAtSec - now; const dueLabel = dueIn >= 0 ? 'in ' + fmtAge(dueIn) : fmtAge(-dueIn) + ' overdue'; li.append( el('span', { class: 'inbox-from' }, '⏰ reminder #' + t.id), ' ',