Files
arcadia-admin/app/root.tsx
jules bfe61c220a Default to dark mode and small text on first load
The bootstrap script previously fell back to the OS color-scheme
preference and left font-scale unset until the user picked one. For
admin work — dense tables, lots of small text, monitoring dashboards —
dark + sm is the better starting point and matches what most operators
end up choosing anyway.

Users who've already picked a theme/font keep their stored preference;
this only affects fresh sessions where localStorage has no value yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:41:54 +10:00

100 lines
3.3 KiB
TypeScript

import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
isRouteErrorResponse,
} from "react-router"
import type { Route } from "./+types/root"
import "./app.css"
import { ToastProvider } from "@crema/notification-ui"
import { CommandBusProvider } from "@crema/action-bus"
import { ArcadiaProvider } from "@crema/arcadia-client"
// CREMA:PROVIDERS-IMPORTS
const ARCADIA_URL = import.meta.env.VITE_ARCADIA_URL ?? "http://localhost:4000"
const ARCADIA_TENANT = import.meta.env.VITE_ARCADIA_TENANT ?? "default"
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
<script
dangerouslySetInnerHTML={{
__html: `(function(){try{var t=localStorage.getItem('crema-theme');if(!t)t='dark';if(t==='dark')document.documentElement.classList.add('dark');var f=localStorage.getItem('crema-font-scale');if(!f||!/^(sm|md|lg|xl)$/.test(f))f='sm';document.documentElement.dataset.fontScale=f;var b=localStorage.getItem('crema-bg');if(b&&/^(drift|static)$/.test(b)){document.addEventListener('DOMContentLoaded',function(){document.body.dataset.bg=b;});}var s=localStorage.getItem('crema-surface');if(s&&/^(snow|stone|sage|slate)$/.test(s)){document.addEventListener('DOMContentLoaded',function(){document.body.dataset.surface=s;});}}catch(e){}})();`,
}}
/>
</head>
<body suppressHydrationWarning>
<div data-slot="aurora-field" aria-hidden="true">
<div className="aurora-blob aurora-blob-1" />
<div className="aurora-blob aurora-blob-2" />
</div>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
)
}
export default function App() {
return (
/* CREMA:PROVIDERS-WRAP-OPEN */
<ToastProvider>
<ArcadiaProvider
baseUrl={ARCADIA_URL}
initialTenantId={ARCADIA_TENANT}
getToken={() => (typeof window === "undefined" ? null : sessionStorage.getItem("arcadia_access_token"))}
onUnauthorized={() => {
if (typeof window !== "undefined") {
sessionStorage.removeItem("arcadia_access_token")
sessionStorage.removeItem("arcadia_refresh_token")
}
}}
>
<CommandBusProvider>
<Outlet />
</CommandBusProvider>
</ArcadiaProvider>
</ToastProvider>
/* CREMA:PROVIDERS-WRAP-CLOSE */
)
}
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
let message = "Oops!"
let details = "An unexpected error occurred."
let stack: string | undefined
if (isRouteErrorResponse(error)) {
message = error.status === 404 ? "404" : "Error"
details =
error.status === 404
? "The requested page could not be found."
: error.statusText || details
} else if (import.meta.env.DEV && error && error instanceof Error) {
details = error.message
stack = error.stack
}
return (
<main className="container mx-auto p-4 pt-16">
<h1>{message}</h1>
<p>{details}</p>
{stack && (
<pre className="w-full overflow-x-auto p-4">
<code>{stack}</code>
</pre>
)}
</main>
)
}