Persist admin dashboard time range per user

Task #24: Remember the admin's last-used dashboard time range.

The admin dashboard's range selector (7d/30d/90d/custom) was resetting to
"Last 7 days" on every visit. Now the selected preset range is persisted in
localStorage under a per-user key (`admin.statsRange.<userId>`) so each admin
sees their last choice on return.

Implementation notes:
- Edited only artifacts/teaboy-os/src/pages/admin.tsx.
- Added two effects: one hydrates the stored value once `user.id` is
  available (auth loads asynchronously), the other writes to localStorage
  whenever the range changes after hydration.
- Only the preset values (7d/30d/90d) are persisted; "custom" is intentionally
  not stored since the custom dates are session-scoped and would feel stale on
  return. After hydration, switching to "custom" leaves the previously stored
  preset untouched so the next visit still restores the last preset.
- Used a hydration guard to avoid clobbering stored values with the default
  "7d" before the load effect runs.
This commit is contained in:
Riyadh
2026-04-21 07:04:30 +00:00
parent e921f2f22b
commit 0fb4c80205
+17
View File
@@ -83,7 +83,24 @@ export default function AdminPage() {
const { data: services } = useListServices({ query: { queryKey: getListServicesQueryKey() } });
const { data: users } = useListUsers({ query: { queryKey: getListUsersQueryKey() } });
const { data: appSettings } = useGetAppSettings({ query: { queryKey: getGetAppSettingsQueryKey() } });
const statsRangeStorageKey = user?.id ? `admin.statsRange.${user.id}` : null;
const [statsRange, setStatsRange] = useState<"7d" | "30d" | "90d" | "custom">("7d");
const [statsRangeHydrated, setStatsRangeHydrated] = useState(false);
useEffect(() => {
setStatsRangeHydrated(false);
if (typeof window === "undefined" || !statsRangeStorageKey) return;
const stored = window.localStorage.getItem(statsRangeStorageKey);
if (stored === "7d" || stored === "30d" || stored === "90d") {
setStatsRange(stored);
}
setStatsRangeHydrated(true);
}, [statsRangeStorageKey]);
useEffect(() => {
if (typeof window === "undefined" || !statsRangeStorageKey || !statsRangeHydrated) return;
if (statsRange === "7d" || statsRange === "30d" || statsRange === "90d") {
window.localStorage.setItem(statsRangeStorageKey, statsRange);
}
}, [statsRange, statsRangeStorageKey, statsRangeHydrated]);
const todayIso = new Date().toISOString().slice(0, 10);
const sevenAgoIso = new Date(Date.now() - 6 * 24 * 60 * 60 * 1000)
.toISOString()