diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx index 406c1f1..a576e35 100644 --- a/frontend/src/pages/Profile.tsx +++ b/frontend/src/pages/Profile.tsx @@ -31,6 +31,54 @@ function NumberField({ ); } +// Renders/edits BackfillHorizonDays as a calendar date (the day sync should +// backfill through) rather than a raw day count, which is easier to reason +// about than counting days back -- the stored value is still a day count +// (what the backend actually consumes), just presented as its equivalent +// date, recomputed against "today" on every render/change. +function daysAgoToISODate(days: number): string { + const d = new Date(); + d.setHours(0, 0, 0, 0); + d.setDate(d.getDate() - days); + // Deliberately not toISOString(): that formats in UTC, which in any + // timezone ahead of UTC shifts local midnight back to the previous day. + const y = d.getFullYear(); + const m = String(d.getMonth() + 1).padStart(2, "0"); + const day = String(d.getDate()).padStart(2, "0"); + return `${y}-${m}-${day}`; +} + +function isoDateToDaysAgo(iso: string): number { + const picked = new Date(iso + "T00:00:00"); + const today = new Date(); + today.setHours(0, 0, 0, 0); + const diffMs = today.getTime() - picked.getTime(); + return Math.max(0, Math.round(diffMs / (24 * 60 * 60 * 1000))); +} + +function BackfillHorizonField({ + value, + onChange, +}: { + value: number; + onChange: (v: number) => void; +}) { + return ( + + ); +} + // How long to wait after the last edit before actually saving, so typing a // name or a multi-digit number doesn't fire one request per keystroke -- // only the last edit in a burst triggers a save, covering every field @@ -162,8 +210,7 @@ export function Profile({ onSaved }: { onSaved?: (p: ProfileType) => void }) { onChange={(e) => set("GarminPassword", e.target.value)} /> - set("BackfillHorizonDays", v)} />