Skip to content

refactor: simplify mobile data fetching with useOfflineData hook - #29

Merged
Vishal-770 merged 3 commits into
masterfrom
refactor/mobile-use-offline-data-hook
Aug 7, 2026
Merged

refactor: simplify mobile data fetching with useOfflineData hook#29
Vishal-770 merged 3 commits into
masterfrom
refactor/mobile-use-offline-data-hook

Conversation

@Vishal-770

Copy link
Copy Markdown
Member

This PR extracts the repetitive cache-first SWR pattern from all mobile dashboard pages into a clean, reusable useOfflineData custom hook. Closes #28.

Copilot AI lite review requested due to automatic review settings August 7, 2026 06:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors mobile dashboard pages to use a shared useOfflineData hook for cache-first data loading, reducing repeated localStorage + fetch-with-timeout logic across screens.

Changes:

  • Introduces src/hooks/use-offline-data.ts to centralize cache read/write + timed fetching and expose a consistent { data, loading, error, retry } API.
  • Updates multiple mobile dashboard pages to replace local state + useEffect fetch flows with the new hook.
  • Standardizes offline / skeleton / error rendering conditions around the hook outputs.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/hooks/use-offline-data.ts Adds the reusable cache-first data fetching hook used by mobile dashboard pages.
src/pages-mobile/dashboard/index.tsx Migrates dashboard home aggregated fetching (CGPA/feedback/profile/trend) to useOfflineData.
src/pages-mobile/dashboard/timetable.tsx Migrates timetable + attendance fetching to useOfflineData and consolidates retry logic.
src/pages-mobile/dashboard/profile.tsx Migrates student profile fetching/caching to useOfflineData with custom emptiness check.
src/pages-mobile/dashboard/payment-receipts.tsx Migrates payment receipts fetching to useOfflineData and preserves list cleanup via transform.
src/pages-mobile/dashboard/marks.tsx Migrates marks fetching to useOfflineData and simplifies offline/error gating.
src/pages-mobile/dashboard/hod-dean.tsx Migrates HOD/Dean details fetching/caching to useOfflineData.
src/pages-mobile/dashboard/grades.tsx Migrates semester grades + history fetching to useOfflineData and syncs derived semester state.
src/pages-mobile/dashboard/exams.tsx Migrates exam schedule fetching/caching to useOfflineData.
src/pages-mobile/dashboard/courses.tsx Migrates registered courses fetching/caching to useOfflineData.
src/pages-mobile/dashboard/contact.tsx Migrates contacts fetching/caching to useOfflineData.
src/pages-mobile/dashboard/attendance.tsx Migrates attendance overview fetching/caching to useOfflineData.
src/pages-mobile/dashboard/attendance/[classId].tsx Migrates attendance detail fetching/caching to useOfflineData.
src/pages-mobile/dashboard/academic-calendar.tsx Migrates calendar options + monthly view fetching/caching to useOfflineData.
src/pages-mobile/dashboard/curriculum/index.tsx Migrates curriculum categories fetching/caching to useOfflineData.
src/pages-mobile/dashboard/curriculum/[categoryId].tsx Migrates curriculum category courses fetching/caching to useOfflineData.
Suppressed comments (2)

src/hooks/use-offline-data.ts:90

  • After introducing refs for fetcher/transform, fetchData should call the ref-held functions (otherwise it still uses the potentially-stale closures).
      const res = await fetchWithTimeout(fetcher(), timeout);

      if (res?.success && res.data !== undefined && res.data !== null) {
        const processed = transform ? transform(res.data) : res.data;
        setData(processed);
        writeCache(cacheKey, processed);

src/hooks/use-offline-data.ts:122

  • retry should use the forced-loading refresh mode so callers can disable Retry buttons / show progress even when cached data is present.
  const retry = useCallback(() => {
    fetchData();
  }, [fetchData]);

Comment on lines +71 to +74
// Use ref to avoid stale closure issues in fetch
const dataRef = useRef(data);
dataRef.current = data;

Comment on lines +75 to +83
const fetchData = useCallback(async () => {
if (!enabled) return;

const currentData = dataRef.current;
const hasCache = hasData(currentData);

setError(null);
setLoading(!hasCache);

Comment on lines +165 to +173
// Update selected tab if groups change and current tab is not in new groups
useMemo(() => {
if (groups.length > 0) {
const tabNames = groups.map(g => g.examType);
if (!selectedTab || !tabNames.includes(selectedTab)) {
setSelectedTab(groups[0].examType);
}
} finally {
setLoading(false);
}
}

useEffect(() => {
if (isLoggedIn) {
load();
}
}, [isLoggedIn, authLoading]);
}, [groups, selectedTab]);
Comment thread src/pages-mobile/dashboard/exams.tsx Outdated
Comment thread src/hooks/use-offline-data.ts Outdated
Comment on lines +114 to +118
useEffect(() => {
if (enabled) {
fetchData();
}
}, [enabled]);
Comment thread src/pages-mobile/dashboard/timetable.tsx
@Vishal-770
Vishal-770 merged commit cff602f into master Aug 7, 2026
1 check passed
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.

refactor: simplify mobile data fetching with useOfflineData hook

2 participants