95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { Nunito, Pixelify_Sans } from "next/font/google";
|
|
import Script from "next/script";
|
|
import { NextIntlClientProvider } from "next-intl";
|
|
import { getLocale, getMessages } from "next-intl/server";
|
|
import type { ReactNode } from "react";
|
|
import { ViewTransitions } from "next-view-transitions";
|
|
import { PwaRegister } from "@/components/pwa-register";
|
|
import { ThemeVars } from "@/components/theme-vars";
|
|
import { SmoothScroll } from "@/components/smooth-scroll";
|
|
import { enforceSiteAccess } from "@/lib/access-guard";
|
|
import { siteSettings } from "@/lib/services/site-settings";
|
|
import "./globals.css";
|
|
|
|
const nunito = Nunito({
|
|
subsets: ["latin"],
|
|
weight: ["400", "600", "700", "800"],
|
|
display: "swap",
|
|
variable: "--font-nunito",
|
|
});
|
|
|
|
const pixelFont = Pixelify_Sans({
|
|
subsets: ["latin"],
|
|
weight: ["400", "700"],
|
|
display: "swap",
|
|
variable: "--font-pixel",
|
|
});
|
|
|
|
export async function generateMetadata(): Promise<Metadata> {
|
|
const appUrl = process.env.APP_URL ?? "http://localhost:3000";
|
|
const hotel = (await siteSettings.get("hotel_name", "Atom")) ?? "Atom";
|
|
const customFavicon = await siteSettings.get("cms_favicon");
|
|
const faviconUrl = customFavicon ?? "/favicon.svg";
|
|
const icons = [
|
|
{ rel: "icon", url: faviconUrl },
|
|
{ rel: "shortcut icon", url: faviconUrl },
|
|
];
|
|
return {
|
|
title: { default: `${hotel} - Hotel`, template: `%s · ${hotel}` },
|
|
description: `${hotel} — a Habbo retro hotel. Hang out, collect furni and meet friends.`,
|
|
metadataBase: new URL(appUrl),
|
|
alternates: { canonical: appUrl },
|
|
icons,
|
|
openGraph: {
|
|
title: `${hotel} - Hotel`,
|
|
description: `${hotel} — a Habbo retro hotel. Hang out, collect furni and meet friends.`,
|
|
type: "website",
|
|
siteName: hotel,
|
|
},
|
|
twitter: { card: "summary_large_image", title: `${hotel} - Hotel` },
|
|
};
|
|
}
|
|
|
|
export default async function RootLayout({
|
|
children,
|
|
}: {
|
|
children: ReactNode;
|
|
}) {
|
|
await enforceSiteAccess();
|
|
const locale = await getLocale();
|
|
const messages = await getMessages();
|
|
const defaultDark = await siteSettings.getBool("default_dark", false);
|
|
const nitroUrl = await siteSettings.get("nitro_client_url", "");
|
|
|
|
return (
|
|
<html
|
|
lang={locale}
|
|
className={`app ${nunito.variable} ${pixelFont.variable}`}
|
|
>
|
|
<head>
|
|
<meta name="theme-default-dark" content={String(defaultDark)} />
|
|
<Script src="/scripts/theme-init.js" strategy="beforeInteractive" />
|
|
<link rel="preconnect" href="https://www.habbo.com" />
|
|
<link rel="dns-prefetch" href="https://www.habbo.com" />
|
|
{nitroUrl?.startsWith("http") ? (
|
|
<link rel="preconnect" href={new URL(nitroUrl).origin} />
|
|
) : null}
|
|
</head>
|
|
<body
|
|
className="flex min-h-screen flex-col site-bg"
|
|
style={{ backgroundColor: "var(--color-background)" }}
|
|
>
|
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
|
<ThemeVars />
|
|
<ViewTransitions>
|
|
{children}
|
|
</ViewTransitions>
|
|
<PwaRegister />
|
|
<SmoothScroll />
|
|
</NextIntlClientProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|