diff --git a/OFFLINE_SYNC_PWA.md b/OFFLINE_SYNC_PWA.md index 0f7e347..fddb5e1 100644 --- a/OFFLINE_SYNC_PWA.md +++ b/OFFLINE_SYNC_PWA.md @@ -62,16 +62,17 @@ A critical feature is the ability to link tasting notes to a bottle that hasn't ## 📱 PWA Features -### Service Worker (`public/sw.js`) - "Bunker v7 + SWR" +### Service Worker (`public/sw.js`) - "Offline-Modus v10 + SWR" The Service Worker implements a robust "Cache-First, Network-Background" strategy: -- **Pre-Caching**: The landing page (`/`) and core static assets are cached individually during installation to prevent total failure on single-file 404s. +- **Pre-Caching**: The landing page (`/`) and core static assets are cached individually (sequentially) during installation to prevent total failure on single-file 404s. - **Manifest Path**: Corrected to `/manifest.webmanifest` to match Next.js defaults. - **SWR Navigation & Assets**: Both load instantly from cache. Updates happen in the background via `fetchWithTimeout` and `AbortController`. - **Universal Root Fallback**: Deep links (like `/bottles/[id]`) fallback to `/` if not cached, allowing Next.js to take over. - **Network Stability**: Added a 2-second stabilization delay in `UploadQueue.tsx` before background sync starts after a network change. - **RSC Data Resiliency**: Requests to `/_next/data/` return an empty JSON object if they fail. -- **Stale-While-Revalidate**: Applied to static assets to ensure immediate UI response. +- **Indicator**: Located in the application header for constant status visibility. +- **Offline-Modus**: Formerly called "Bunker", this system ensures all core assets are ready for a zero-connectivity environment. ### Manifest (`src/app/manifest.ts`) Defines the app's appearance when installed: diff --git a/src/app/bottles/[id]/page.tsx b/src/app/bottles/[id]/page.tsx index 90ef311..d8fd562 100644 --- a/src/app/bottles/[id]/page.tsx +++ b/src/app/bottles/[id]/page.tsx @@ -4,6 +4,7 @@ import React, { useEffect, useState } from 'react'; import BottleDetails from '@/components/BottleDetails'; import { createClient } from '@/lib/supabase/client'; import { validateSession } from '@/services/validate-session'; +import OfflineIndicator from '@/components/OfflineIndicator'; import { useParams, useSearchParams } from 'next/navigation'; export default function BottlePage() { @@ -40,7 +41,10 @@ export default function BottlePage() { if (!bottleId) return null; return ( -
+
+
+ +
- {children} diff --git a/src/app/page.tsx b/src/app/page.tsx index 26f49c7..4201b27 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -10,6 +10,7 @@ import SessionList from "@/components/SessionList"; import StatsDashboard from "@/components/StatsDashboard"; import DramOfTheDay from "@/components/DramOfTheDay"; import LanguageSwitcher from "@/components/LanguageSwitcher"; +import OfflineIndicator from "@/components/OfflineIndicator"; import { useI18n } from "@/i18n/I18nContext"; import { useSession } from "@/context/SessionContext"; import { Sparkles } from "lucide-react"; @@ -181,6 +182,7 @@ export default function Home() { )}
+