Service Worker (public/sw.js) cached die App-Shell für Seiten-GETs (network-first, cache-fallback). Durchsichten, die offline gespeichert werden, landen in einer IndexedDB-Warteschlange (idb) statt zu scheitern und werden automatisch synchronisiert, sobald wieder Netzwerk verfügbar ist (Mount + online-Event), mit manuellem Retry über ein Badge im App-Header. Ein modulweiter In-Flight-Lock in sync.ts verhindert doppelte Synchronisierung bei gleichzeitigen Aufrufen (gefunden über React-StrictMode-Doppel-Mount, das ohne den Lock dieselbe Durchsicht zweimal anlegte).
44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import type { Metadata } from "next";
|
||
import { Space_Grotesk, Inter, IBM_Plex_Mono } from "next/font/google";
|
||
import "./globals.css";
|
||
import { Providers } from "./providers";
|
||
import { Toaster } from "@/components/ui/sonner";
|
||
import { ServiceWorkerRegistration } from "@/components/service-worker-registration";
|
||
|
||
const spaceGrotesk = Space_Grotesk({
|
||
variable: "--font-heading",
|
||
subsets: ["latin"],
|
||
weight: ["500", "600", "700"],
|
||
});
|
||
|
||
const inter = Inter({
|
||
variable: "--font-body",
|
||
subsets: ["latin"],
|
||
});
|
||
|
||
const plexMono = IBM_Plex_Mono({
|
||
variable: "--font-data",
|
||
subsets: ["latin"],
|
||
weight: ["400", "500"],
|
||
});
|
||
|
||
export const metadata: Metadata = {
|
||
title: "ApiCore – Imkereiverwaltung",
|
||
description: "Digitale Imkereiverwaltung für Wabenhain",
|
||
};
|
||
|
||
export default function RootLayout({ children }: LayoutProps<"/">) {
|
||
return (
|
||
<html
|
||
lang="de"
|
||
className={`${spaceGrotesk.variable} ${inter.variable} ${plexMono.variable} h-full antialiased`}
|
||
>
|
||
<body className="min-h-full flex flex-col">
|
||
<Providers>{children}</Providers>
|
||
<Toaster position="top-right" richColors />
|
||
<ServiceWorkerRegistration />
|
||
</body>
|
||
</html>
|
||
);
|
||
}
|