The service worker served the cached page first, so a driver ran the old build until the app was opened twice (Joachim on 2026-10-26 kept the old one after the invoice-match deploy). Each build now writes its id to /version.json. On launch a newer live build clears the cached pages and reloads once; while the app stays open an Update banner appears instead, so a reload never cuts off a photo or an upload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
73 lines
No EOL
2.3 KiB
TypeScript
73 lines
No EOL
2.3 KiB
TypeScript
import type { Metadata, Viewport } from "next";
|
|
import "leaflet/dist/leaflet.css";
|
|
import "./globals.css";
|
|
import { AuthProvider } from "@/components/AuthProvider";
|
|
import OfflineIndicator from "@/components/OfflineIndicator";
|
|
import InstallPrompt from "@/components/InstallPrompt";
|
|
import { PWABridge } from "@/components/PWABridge";
|
|
import UpdateWatcher from "@/components/UpdateWatcher";
|
|
import LocationTracker from "@/components/LocationTracker";
|
|
import { applyDarkMode } from "@/lib/theme";
|
|
|
|
// Apply dark mode BEFORE React hydrates so we don't get a flash
|
|
// of light theme on first paint. Reads the same `1driver_settings`
|
|
// key the settings page writes to.
|
|
applyDarkMode();
|
|
|
|
export const metadata: Metadata = {
|
|
title: "1Driver - Collections",
|
|
description: "Mobile driver collection management app",
|
|
manifest: "/manifest.json",
|
|
appleWebApp: {
|
|
capable: true,
|
|
statusBarStyle: "black-translucent",
|
|
title: "1Driver",
|
|
},
|
|
formatDetection: {
|
|
telephone: false,
|
|
},
|
|
};
|
|
|
|
export const viewport: Viewport = {
|
|
width: "device-width",
|
|
initialScale: 1,
|
|
maximumScale: 1,
|
|
userScalable: false,
|
|
viewportFit: "cover",
|
|
themeColor: "#26251e",
|
|
};
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode;
|
|
}) {
|
|
return (
|
|
<html lang="en">
|
|
<body className="antialiased bg-[#f2f1ed] text-[#26251e] safe-top safe-bottom overscroll-none">
|
|
<a
|
|
href="#main-content"
|
|
className="sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-[100] focus:px-3 focus:py-2 focus:bg-white focus:text-[#26251e] focus:rounded-lg focus:shadow-lg focus:font-semibold focus:text-sm"
|
|
>
|
|
Skip to main content
|
|
</a>
|
|
<AuthProvider>
|
|
<PWABridge />
|
|
<UpdateWatcher />
|
|
<OfflineIndicator />
|
|
<InstallPrompt />
|
|
{/*
|
|
LocationTracker hoisted to the layout so the GPS watch
|
|
survives bottom-nav tab switches. Previously this lived
|
|
on every page, which meant every tab switch tore down
|
|
watchPosition + the wake lock + the interval and then
|
|
re-acquired them. Now it lives once, gates on auth, and
|
|
persists across navigation.
|
|
*/}
|
|
<LocationTracker />
|
|
{children}
|
|
</AuthProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
} |