The user-facing pages pick up the new primitives: LoginPage (21
lines) gets the new form tone + the Bill Tracker wordmark on the
auth card; TrackerPage (109 lines) gets the new cashflow timeline
geometry, the new BrandGlyph on the bucket empty state, and the
new TonedCard on the summary stack; the rest are 1-9 line
import/header adjustments. App.tsx is the lazy-loaded import for
the new brand module on the about/privacy paths.
This is commit 6 of 9 in the v0.42.0 brand refresh. Depends on
b714715 (tracker cards).
- aria-label on the pencil "Edit bill" buttons (were title-only), matching the
autopay buttons' title+aria-label pattern.
- role="status" aria-live on the filter result count so filtering announces
"N of M shown"; a visually-hidden live region announces drag/keyboard reorder
("Moved <bill> to position N of M").
- Header "Keyboard shortcuts" dropdown documenting the (previously invisible)
j/k/arrows/Enter/p/Esc row shortcuts + ⌘K palette.
Deferred as low-value/optional: extra display toggles (C4) and a due-this-week
chip (C5) — avoided header/option clutter.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add a leading selection checkbox to each desktop + mobile row, threaded from
the page through TrackerBucket via an optional RowSelection prop (renders only
when the page supplies a toggle handler).
- Page owns the selection Set; a sticky bottom action bar appears when ≥1 bill is
checked: "N selected · Pay · Skip · Clear".
- Pay selected reuses the bulkPay item shape + Undo from "Pay all due".
- Skip selected fans out saveBillMonthlyState (no bulk endpoint; skip has no money
effect) with Promise.allSettled, an aggregated "n skipped / m failed" toast, and
an Undo that un-skips. Selection clears on month change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Header "Export" menu: Export CSV (via the existing /api/export?from&to date
range for the viewed month) and Print (window.print()). Extract the shared
downloadFile blob helper to lib/download.ts (reused by DownloadMyDataSection).
- Add api.exportRangeUrl(from, to, fmt).
- Tracker-scoped @media print CSS: hide interactive chrome (.tracker-print-hide),
keep the month title + summary + buckets, avoid splitting a row across pages.
- Header "Calendar" button deep-links to /calendar?year&month; CalendarPage now
reads those params as its initial month (falls back to today).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- B1: replace the two raw useEffect/api fetches (simplefinStatus, settings) with
useSimplefinStatus() and useSettings() query hooks — cached/deduped like the
rest of the app. Tracker settings now derive from the ['settings'] cache
merged under module-level TRACKER_SETTING_DEFAULTS.
- B2: settings save is now useSaveSettings() — a useMutation with optimistic
cache update + rollback on error, replacing the hand-rolled optimistic/refetch.
- B3: useDeferredValue on the search term feeding filteredRows so typing stays
snappy on large months (matches BillsPage/SubscriptionsPage).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Extract parseUtc (was copy-pasted in 4 files) and settingEnabled (3 copies,
one named settingsBool) into client/lib/utils.ts as the single source.
- Replace all local copies with the shared import.
- Add tracker_show_safe_to_spend to the tracker's local settings defaults so it
matches SettingsPage's list (behavior unchanged; aligns the two sources).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Pin-upcoming sort ranked on raw row.status, so a bill paid-by-threshold
but still carrying a stale 'late'/'missed' status was pinned to the top.
Rank on rowEffectiveStatus (same source the overdue filter uses) so it
sorts to the bottom instead.
- Filtering to zero results showed a blank content area (rows.length checks
the unfiltered list). Add a "No bills match your filters" state with a
Clear-filters action.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The tracker: URL-driven month/filters/sort, React Query data (TrackerResponse),
bank-projection banner, summary cards, safe-to-spend, overdue center, drift
insights, drag-reorder buckets, and all row/modal orchestration. TrackerSummary.trend
is typed unknown in @/types so it's cast at the TrendCard boundary.
2026-07-04 23:06:46 -05:00
Renamed from client/pages/TrackerPage.jsx (Browse further)