Skip to content

feat(analytics): persist selected time range in localStorage - #462

Closed
jasnoorgill wants to merge 1 commit into
tashfeenahmed:mainfrom
jasnoorgill:feat/analytics-sticky-range
Closed

feat(analytics): persist selected time range in localStorage#462
jasnoorgill wants to merge 1 commit into
tashfeenahmed:mainfrom
jasnoorgill:feat/analytics-sticky-range

Conversation

@jasnoorgill

Copy link
Copy Markdown
Contributor

Summary

Persists the selected analytics time range (24h / 7d / 30d) in localStorage
so the user lands back on the window they were inspecting after a reload or
new session. Same persistence pattern as the existing theme toggle
(client/index.html) and the freellmapi.locale preference
(client/src/i18n/I18nProvider.tsx).

Storage key: freellmapi.analytics.range. Values are validated against
['24h', '7d', '30d']; invalid or missing entries fall back to the existing
7d default so a corrupted entry never bricks the page. localStorage
access is wrapped in try/catch for SSR / private-mode safety (same
pattern as client/src/lib/api.ts:18-26).

Motivation

The analytics page is a frequent revisit — most operators land on 7d or 30d,
not the default, and a hard reload (or new browser session) always snapped
them back to 7d. Small but persistent annoyance; the existing theme and
freellmapi.locale patterns show the project already considers
client-level preferences worth persisting, so this is consistent with the
project's UX conventions.

Changes

File Change
client/src/pages/AnalyticsPage.tsx Added useEffect import; useState<TimeRange>('7d')useState<TimeRange>(loadStoredRange); new useEffect to persist range on change; added STORAGE_KEY, TIME_RANGES, DEFAULT_RANGE constants and loadStoredRange() helper.

1 file, +34 / -2. No new dependencies. No server changes. No new
migrations. No i18n changes (the tab labels use existing
analytics.range24h / range7d / range30d keys).

Test plan

  • npx tsc -b in client/ — clean, 0 errors.
  • npx tsc -b in server/ — 9 errors in server/src/routes/keys.ts from
    upstream's multer typing bug (PR I added Agnes AI, but it doesn’t appear in the model list. #438, pre-existing on origin/main
    at 340f414). Not introduced by this PR — same errors reproduce on
    a clean git checkout origin/main.
  • npx vitest run in server/ — 524/524 passing, 0 failures, 0 regressions.
  • Live verification: deployed on integration/all-my-prs @ f81f781; the
    rebuilt client bundle (dist/assets/index-DJVe5VdN.js) contains the new
    storage key string and the read+set localStorage calls. Restarted
    service, MainPID=860700 running.

Manual smoke:

  1. Open /analytics, click 30d.
  2. Hard-reload — page opens on 30d (previously: 7d).
  3. Open DevTools → Application → Local Storage → key
    freellmapi.analytics.range is 30d.
  4. Click 24h, reload — opens on 24h, storage now 24h.
  5. Clear the key manually + reload — falls back to 7d.

Compatibility

No breaking changes. The default is unchanged (7d). The persistence is
additive — users who never visit the page see no different behaviour. The
localStorage key is namespaced (freellmapi.*) per the existing
convention.

References operator session 2026-07-04. No upstream issue number yet —
happy to file one if requested.

Remembers the last-selected 24h/7d/30d range across reloads and new
sessions so the user lands back on the window they were inspecting.
Same localStorage shape as the theme toggle (key: 'theme') and the
locale picker (key: 'freellmapi.locale').

Storage key: 'freellmapi.analytics.range'. Invalid or missing values
fall back to the 7d default; storage errors (quota, private mode) are
swallowed so the page keeps working.
@jasnoorgill

Copy link
Copy Markdown
Contributor Author

Closed in favor of #463 which combines this with the sortable-columns work to avoid rebase churn on the same file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant