Skip to content

Add offline-first sync queue and harden PWA boot#14

Draft
hsalaman1 wants to merge 1 commit into
mainfrom
claude/add-offline-mode-Bm0K0
Draft

Add offline-first sync queue and harden PWA boot#14
hsalaman1 wants to merge 1 commit into
mainfrom
claude/add-offline-mode-Bm0K0

Conversation

@hsalaman1

Copy link
Copy Markdown
Owner

Summary

Reported issue: the app appears to "shut down" (blank screen) when there is no internet, especially on first launch. Two real causes were found:

  1. No ErrorBoundary anywhere — any uncaught hook/render error produced a blank screen.
  2. Partial PWA precachemaximumFileSizeToCacheInBytes was 5 MB, which silently dropped the pdfmake/docx bundles and left users with no signal that the app had cached for offline use.

This PR makes the form fully usable offline, queues submissions locally, and auto-syncs when connectivity returns.

What changed

  • Root ErrorBoundary (src/components/UI/ErrorBoundary.jsx, wired in src/main.jsx) renders a recoverable fallback with Reload / Copy details so a hook failure never blanks the UI again.
  • Hardened Workbox precache (vite.config.js): maximumFileSizeToCacheInBytes bumped to 10 MB so the heavy export bundles are precached, plus cleanupOutdatedCaches, navigateFallbackDenylist, and explicit devOptions: { enabled: false }.
  • Offline-ready signalsrc/main.jsx listens on onOfflineReady, fires an app:offline-ready event, and persists a sticky flag. New src/hooks/usePwaStatus.js exposes that to the UI as an "Offline-ready" pill in the bottom bar.
  • Shared submit helper (src/lib/submitObservation.js) factored out of src/hooks/useSupabase.js so both the direct submit and the sync queue use one code path.
  • Sync queue (src/hooks/useSyncQueue.js):
    • localStorage-backed (observation-sync-queue), one item per offline submission.
    • Auto-drains when useConnectivity reports supabaseReachable and on the raw online event (debounced 500 ms).
    • Per-item statuses (queued | syncing | synced | error); errors don't block the rest of the queue.
    • enqueue / flushQueue / retryItem / retryAll / removeItem API.
  • Submit handler (src/App.jsx) is now offline-aware: online → direct submit (and resetObservation() on first insert), offline or server failure → enqueue and reset so the user can keep going.
  • UI surface (src/components/Export/ExportButtons.jsx):
    • Submit button reads "Submit" online, "Save & Queue" offline; no longer disabled by offline state.
    • Pending-count badge on the connectivity dot, dedicated Sync button when the queue is non-empty.
    • Status banner explains queued / syncing / synced state and surfaces per-item Retry / Discard controls.
    • Transient "All N reports synced" banner when the queue drains.
  • README — new "Offline mode" section explains setup, the queue, limits, and DevTools verification.

Honest constraint (called out in README)

A pure web PWA cannot load on a brand-new device that has never had internet — the browser must fetch the page at least once. After that single online visit the service worker caches everything and the app launches offline forever. Wrapping with Capacitor/Tauri is the only path to true zero-internet-first-launch and is out of scope for this PR.

Test plan

  • npm run build && npm run preview. Open once online; confirm the green Offline-ready pill appears in the bottom bar.
  • DevTools → Application → Service Workers → tick Offline → hard reload. The full UI must render (no blank screen).
  • Fill an observation, click Submit while offline. Expected: item is queued, badge shows "1", draft is cleared, no red error.
  • Fill another observation and submit. Badge shows "2".
  • Untick Offline. Within ~1 s the queue drains, both items show synced, "All 2 reports synced." banner appears, badge clears.
  • Re-enable Offline mid-flush: in-flight item moves to error; remaining queued items stay queued. Disable Offline and click Sync — remaining items succeed; errored item is retryable.
  • Temporarily throw in a child component to confirm the ErrorBoundary fallback renders instead of a blank screen, then revert.
  • Clear site data and reload offline once — confirm the browser's native offline page (expected; documented in README).

https://claude.ai/code/session_017dxUBBwJ41917z2m6Z4ePp


Generated by Claude Code

Make the app stay usable when the network is unavailable so observations are
never lost. Adds a localStorage-backed sync queue that holds submissions while
offline and drains them automatically when connectivity returns; adds a root
ErrorBoundary so a hook failure no longer blanks the screen; bumps the Workbox
precache cap so the pdfmake/docx bundles ship with the service worker; and
surfaces the offline state, pending count, manual Sync, and per-item retry/
discard controls in the existing export bar.

https://claude.ai/code/session_017dxUBBwJ41917z2m6Z4ePp
@vercel

vercel Bot commented May 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
behavioral-observation-app Ready Ready Preview May 8, 2026 2:37pm

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.

2 participants