src/app/layout.tsx
Linked repository file from this build.
import { ui } from "@clerk/ui";
import { AccountSetupError, getServerSession } from "@/lib/auth/server";
import { AccessError } from "@/lib/auth/scope";
import { ClerkProvider } from "@clerk/nextjs";
import { SessionProvider } from "@/lib/auth/client";
import type { Metadata } from "next";
import {
Archivo,
Bricolage_Grotesque,
DM_Serif_Display,
Figtree,
Fraunces,
JetBrains_Mono,
Manrope,
Newsreader,
Nunito,
Space_Grotesk,
} from "next/font/google";
import { SpeedInsights } from "@vercel/speed-insights/next";
import "./globals.css";
import { AccountSetup } from "@/components/account-setup";
import { AppearanceProvider } from "@/components/appearance-provider";
import { appearanceBootScript } from "@/lib/appearance";
import { NotificationProvider } from "@/features/inbox/notifications";
// Preferences select the font in the browser; preload would fetch every palette face.
const sans = Figtree({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-figtree",
});
const display = Fraunces({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-fraunces",
axes: ["opsz", "SOFT"],
});
const mono = JetBrains_Mono({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-jetbrains",
});
/* Faces used by the expressive palettes. Browsers only download the ones a palette uses. */
const newsreader = Newsreader({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-newsreader",
axes: ["opsz"],
});
const grotesk = Space_Grotesk({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-grotesk",
});
const archivo = Archivo({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-archivo",
});
const nunito = Nunito({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-nunito",
});
const bricolage = Bricolage_Grotesque({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-bricolage",
});
const manrope = Manrope({
subsets: ["latin"],
preload: false,
display: "swap",
variable: "--font-manrope",
});
const dmSerif = DM_Serif_Display({
subsets: ["latin"],
preload: false,
weight: "400",
display: "swap",
variable: "--font-dm-serif",
});
const fontVariables = [
sans,
display,
mono,
newsreader,
grotesk,
archivo,
nunito,
bricolage,
manrope,
dmSerif,
]
.map((font) => font.variable)
.join(" ");
export const metadata: Metadata = {
title: "Iris · SNAP Negative quality control",
description:
"Iris is a synthetic SNAP Negative review demo: seeded reviews, exact-cent computation and supervisor and PEC decisions. Not production scope.",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
let initialSession = null;
let setupFields: string[] | null = null;
try {
initialSession = await getServerSession();
} catch (error) {
if (error instanceof AccountSetupError) setupFields = error.fields;
// Signed-out visitors can still open public authentication pages.
if (!(error instanceof AccessError)) throw error;
}
return (
<html lang="en" suppressHydrationWarning className={fontVariables}>
<head>
<script dangerouslySetInnerHTML={{ __html: appearanceBootScript }} />
</head>
<body className="antialiased">
<AppearanceProvider>
<ClerkProvider
ui={ui}
appearance={{
cssLayerName: "clerk",
variables: {
colorPrimary: "var(--primary)",
colorPrimaryForeground: "var(--primary-foreground)",
colorBackground: "var(--card)",
colorForeground: "var(--foreground)",
colorMutedForeground: "var(--muted-foreground)",
colorMuted: "var(--muted)",
colorInput: "var(--card)",
colorInputForeground: "var(--foreground)",
colorBorder: "var(--input)",
colorDanger: "var(--destructive)",
colorSuccess: "var(--success)",
colorWarning: "var(--warning)",
colorRing: "var(--ring)",
colorNeutral: "var(--foreground)",
colorModalBackdrop: "rgba(0, 0, 0, 0.6)",
borderRadius: "var(--radius)",
fontFamily: "var(--font-sans)",
},
}}
>
<SessionProvider initialSession={initialSession}>
<NotificationProvider testSession={initialSession?.userId === null}>
{setupFields ? <AccountSetup fields={setupFields} /> : children}
</NotificationProvider>
</SessionProvider>
<SpeedInsights />
</ClerkProvider>
</AppearanceProvider>
</body>
</html>
);
}