Local Storage and Persistence (TryRamadan)
Use this skill when adding or changing stored state, onboarding completion, or sync before navigation so the app and dashboard read fresh data.
1. Core hook: useLocalStorage
- •Location:
src/hooks/useLocalStorage.ts. - •Signature:
useLocalStorage<T>(key: string, initialValue: T): [T, (value: T | ((prev: T) => T)) => void]. - •Behavior: Reads from
localStorageon mount (falls back to initialValue on parse error). Writes tolocalStorageinuseEffectwhenever state changes. Key must be unique per store.
2. Preferences and quick actions (sync before navigation)
- •Preferences:
persistPreferencesSync(partial)mergespartialinto current preferences and writes totryramadan-preferences. Call before navigating away from onboarding so Dashboard sees up-to-date preferences (e.g. onboardingComplete, location, timezone). - •Quick actions:
persistQuickActionsSync(order)writes dashboard quick-action order totryramadan-dashboard-quick-actions. Call before navigation when order was updated (e.g. from onboarding or Settings). - •Usage: OnboardingGoals and OnboardingLayout call
persistPreferencesSync(newPrefs)andpersistQuickActionsSync(getQuickActionOrderFromPriorities(priorities))before navigating to dashboard.
3. Main storage keys
| Key | Purpose |
|---|---|
tryramadan-preferences | User preferences (theme, location, timezone, priorities, macro/sex/weight, etc.). |
tryramadan-progress | Fasting progress (completedDays, fastingLog). |
tryramadan-daily-goals | Daily calorie and macro goals. |
tryramadan-dashboard-quick-actions | Ordered list of quick-action IDs. |
tryramadan-prayer-times-cache | Single entry: today’s prayer times for (dateStr, lat, lng). |
tryramadan-ramadan-prayers | Ramadan month prayer times by lat_lng_year. |
tryramadan-notifications | Notification settings (suhoor/iftar minutes before, etc.). |
tryramadan-today | Per-date today data (hydration, energy, intention). |
tryramadan-journal | Journal entries. |
tryramadan-daily-goals | Calories, protein, carbs, fat goals. |
4. "Today" and location-based date
- •Fasting log / completion: When
displayTimezoneis set, "today" should be location’s date (getTodayStringInTimezone(displayTimezone)). Helpers accept optionaltodayOverride:getTodayFastingLog(progress, todayOverride),isFastingToday(progress, todayOverride),startFastingToday(..., todayOverride), etc. PasstodayStrfrom the component when it’s derived from display timezone so countdowns and log stay in sync. - •Dashboard / FastingBottomBar: Compute
todayStrfromdisplayTimezonewhen set and pass it into these helpers and into start/complete/break/uncomplete.
5. Cache invalidation
- •Prayer times (today): Cache is keyed by (dateStr, lat, lng). New day or new location → cache miss → fetch. See timezone-and-countdown skill.
- •Ramadan month: Keyed by lat, lng, Ramadan year. New location or new year → new key → fetch. Stale after 7 days.
- •Preferences: No automatic invalidation; user changes location/settings in Settings and state updates.
6. Tests
- •File:
src/test/localStorage.test.ts– persistPreferencesSync, persistQuickActionsSync, useLocalStorage (initial, read, write, invalid JSON), getSuggestedCalories, daily goals persistence. - •When adding new keys or sync logic, add tests for round-trip and merge behavior where applicable.