feat: offline pages mode

This commit is contained in:
Julien Froidefond
2025-02-21 09:31:23 +01:00
parent b62b44eab9
commit 8c13021bfb
8 changed files with 136 additions and 116 deletions

View File

@@ -8,6 +8,8 @@ import { InstallPWA } from "../ui/InstallPWA";
import { Toaster } from "@/components/ui/toaster";
import { usePathname } from "next/navigation";
import { PreferencesProvider } from "@/contexts/PreferencesContext";
import { registerServiceWorker } from "@/lib/registerSW";
import { NetworkStatus } from "../ui/NetworkStatus";
// Routes qui ne nécessitent pas d'authentification
const publicRoutes = ["/login", "/register"];
@@ -51,16 +53,7 @@ export default function ClientLayout({ children }: { children: React.ReactNode }
useEffect(() => {
// Enregistrer le service worker
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("/sw.js")
.then(() => {
// Succès silencieux
})
.catch((error) => {
console.error("Erreur lors de l'enregistrement du Service Worker:", error);
});
}
registerServiceWorker();
}, []);
// Ne pas afficher le header et la sidebar sur les routes publiques
@@ -75,6 +68,7 @@ export default function ClientLayout({ children }: { children: React.ReactNode }
<main className={`${!isPublicRoute ? "container pt-4 md:pt-8" : ""}`}>{children}</main>
<InstallPWA />
<Toaster />
<NetworkStatus />
</div>
</PreferencesProvider>
</ThemeProvider>

View File

@@ -106,7 +106,7 @@ export const Thumbnail = forwardRef<HTMLButtonElement, ThumbnailProps>(
return (
<button
ref={(node) => {
thumbnailRef.current = node;
// thumbnailRef.current = node;
if (typeof ref === "function") {
ref(node);
} else if (ref) {

View File

@@ -0,0 +1,17 @@
"use client";
import { useNetworkStatus } from "@/hooks/useNetworkStatus";
import { WifiOff } from "lucide-react";
export function NetworkStatus() {
const isOnline = useNetworkStatus();
if (isOnline) return null;
return (
<div className="fixed bottom-4 left-4 z-[100] flex items-center gap-2 rounded-lg bg-destructive px-4 py-2 text-sm text-destructive-foreground shadow-lg">
<WifiOff className="h-4 w-4" />
<span>Hors ligne</span>
</div>
);
}

View File

@@ -1,25 +0,0 @@
"use client";
import * as React from "react";
import * as SeparatorPrimitive from "@radix-ui/react-separator";
import { cn } from "@/lib/utils";
const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
"shrink-0 bg-border",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className
)}
{...props}
/>
));
Separator.displayName = SeparatorPrimitive.Root.displayName;
export { Separator };