diff --git a/backend/package-lock.json b/backend/package-lock.json index 7358f3a9..f415a364 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1881,27 +1881,8 @@ } }, "node_modules/notes-app-backend": { - "version": "1.0.0", - "resolved": "file:", - "license": "ISC", - "dependencies": { - "@react-oauth/google": "^0.12.1", - "axios": "^1.7.2", - "bcrypt": "^5.1.1", - "cors": "^2.8.5", - "dotenv": "^16.4.5", - "express": "^4.21.0", - "express-async-handler": "^1.2.0", - "express-rate-limit": "^7.4.1", - "fs": "^0.0.1-security", - "google-auth-library": "^9.11.0", - "jsonwebtoken": "^9.0.2", - "mongodb": "^6.9.0", - "mongoose": "^8.4.4", - "multer": "^1.4.5-lts.1", - "nodemailer": "^6.9.15", - "notes-app-backend": "file:" - } + "resolved": "", + "link": true }, "node_modules/npmlog": { "version": "5.0.1", diff --git a/frontend/public/offline.html b/frontend/public/offline.html new file mode 100644 index 00000000..37fb7533 --- /dev/null +++ b/frontend/public/offline.html @@ -0,0 +1,196 @@ + + + + + + You're Offline - Notes-App + + + +
+
+ + + +
+

You're Currently Offline

+

Don't worry! You can still access previously loaded content. We'll automatically reconnect when your internet connection is restored.

+
+ + +
+
+ + Checking connection status... +
+
+ + + \ No newline at end of file diff --git a/frontend/public/service-worker.js b/frontend/public/service-worker.js new file mode 100644 index 00000000..69e05d78 --- /dev/null +++ b/frontend/public/service-worker.js @@ -0,0 +1,51 @@ +const CACHE_NAME = 'offline-v1'; +const OFFLINE_URL = '/offline.html'; + +self.addEventListener('install', (event) => { + event.waitUntil( + (async () => { + const cache = await caches.open(CACHE_NAME); + // Cache the offline page + await cache.add(new Request(OFFLINE_URL, { cache: 'reload' })); + })() + ); + // Force the waiting service worker to become the active service worker + self.skipWaiting(); +}); + +self.addEventListener('activate', (event) => { + event.waitUntil( + (async () => { + // Enable navigation preload if available + if ('navigationPreload' in self.registration) { + await self.registration.navigationPreload.enable(); + } + })() + ); + // Tell the active service worker to take control of the page immediately + self.clients.claim(); +}); + +self.addEventListener('fetch', (event) => { + if (event.request.mode === 'navigate') { + event.respondWith( + (async () => { + try { + // First, try to use the navigation preload response if available + const preloadResponse = await event.preloadResponse; + if (preloadResponse) { + return preloadResponse; + } + + // Try to fetch the request from the network + return await fetch(event.request); + } catch (error) { + // If fetch fails (offline), get the offline page from cache + const cache = await caches.open(CACHE_NAME); + const cachedResponse = await cache.match(OFFLINE_URL); + return cachedResponse; + } + })() + ); + } +}); \ No newline at end of file diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index 4db83c50..d73ba5df 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -5,6 +5,18 @@ import "./index.css"; import { Toaster } from "react-hot-toast"; import { GoogleOAuthProvider } from "@react-oauth/google"; +if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/service-worker.js') + .then(registration => { + console.log('ServiceWorker registration successful'); + }) + .catch(err => { + console.log('ServiceWorker registration failed: ', err); + }); + }); +} + createRoot(document.getElementById("root")).render(