M3 reminders: notes.remind_at + Reminders view
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 5s
CI & Build / Python tests (push) Successful in 7s
CI & Build / Build & push image (push) Successful in 32s

- Migration 0010: notes.remind_at (nullable tz). PATCH accepts remind_at
  (ISO set / null clear); GET /api/notes/reminders (soonest first, non-trashed);
  serialize includes remind_at.
- Frontend: datetime util (local<->ISO, format, overdue); notes store setReminder;
  editor datetime-local picker + clear; card reminder chip (overdue = red);
  sidebar Reminders entry + /reminders view.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
2026-07-20 08:12:14 -04:00
co-authored by Claude Opus 4.8
parent ad006ccb58
commit c57982d910
12 changed files with 205 additions and 1 deletions
+28
View File
@@ -0,0 +1,28 @@
// Reminder datetime helpers. Reminders are stored as ISO UTC; the editor's
// <input type="datetime-local"> works in local time.
export function toLocalInput(iso: string | null): string {
if (!iso) return "";
const d = new Date(iso);
const pad = (n: number) => String(n).padStart(2, "0");
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
}
export function fromLocalInput(local: string): string | null {
if (!local) return null;
return new Date(local).toISOString();
}
export function formatReminder(iso: string | null): string {
if (!iso) return "";
return new Date(iso).toLocaleString(undefined, {
month: "short",
day: "numeric",
hour: "numeric",
minute: "2-digit",
});
}
export function isOverdue(iso: string | null): boolean {
return !!iso && new Date(iso).getTime() < Date.now();
}