ReviewOS

also looking at this

stacks/analyticshq

feat(dashboard): presets-and-calendar reporting-period picker

#55
Merged glennmichael123 wants to merge feat/date-range-picker into main
3 files +457 -34
9 days ago

Replaces the two native date inputs behind Custom with a picker in the style of Fathom's: eleven presets down the left beside two month calendars, an inline range highlight, and a live preview as you drag from one day to the other.

Why

The old control was two <input type="date"> fields with no presets and no calendar, and the mobile audit found its popover landed off-screen at phone width (dashboard.stx:2242). This is also the datepicker style requested directly.

How it fits the existing model

  • The URL stays the only state. Presets the server already buckets — 7d, 30d, 90d, 1y, all — go out as ?range=, so the chart keeps its bucket-granularity logic. A hand-picked span goes out as ?from=&to=, exactly what the server block already parses (isCustom). Nothing about how a range is read changes.
  • No new DOM access. The picker reads the current params through useRoute().query and writes with navigate() — it touches no window/document/location and trips none of stx's DOM guards (the one match in the file is a comment).
  • Self-contained logic. The date math — calendar grid, day arithmetic across DST and year boundaries, preset resolution, and the query it builds — lives between #region pure markers so the unit test evaluates exactly the shipped text, not a copy.

Mobile

At ≤1023px the second calendar drops to one, the presets become a wrapped chip row, and the panel is bounded by the visible viewport (max-height: calc(100dvh - 6rem), overflow-y: auto, overscroll-behavior: contain) — the same treatment as the merged nav fixes.

Verification

  • tests/unit/date-range-picker.test.ts — 15 cases: 42-cell grid (leading Sunday, leap Feb, Dec→Jan rollover, future-day flag), day shifts across both US DST changes and year ends, all eleven presets (including last-month on Jan 1), and the exact query string produced (custom replaces preset and vice-versa; site/filters/compare preserved). 90/90 across this plus the payload-hygiene and fathom-import suites. pickier clean.
  • Rendered against the built page on an unguarded harness (since the authenticated dashboard needs an API backend that isn't available standalone): the runtime expands the x-for over the derived() month to 84 cells across two calendars, marks today, disables future days, and fills a ?from&to range with solid endpoints — confirmed in light and dark, and the phone layout collapses to one calendar with chip presets and no horizontal overflow.

The one thing I could not do here is click through the picker inside the real dashboard, because that page's client auth-gate redirects to sign-in without an /api/me backend locally — the same limit noted on the recent dashboard PRs. The logic is covered by unit tests and the runtime rendering by the harness.

3 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.