Adds the complete Next.js website including i18n routing, house and apartment pages, Beds24 v2 integration for live availability/pricing, Stripe checkout, contact forms, Docker setup and deployment docs. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
82 lines
2.1 KiB
TypeScript
82 lines
2.1 KiB
TypeScript
import { ReactNode } from "react";
|
|
import { NextIntlClientProvider } from "next-intl";
|
|
import { getMessages, getTranslations } from "next-intl/server";
|
|
import { notFound } from "next/navigation";
|
|
import { locales, Locale } from "@/i18n";
|
|
import "../globals.css";
|
|
import { Header } from "@/components/layout/Header";
|
|
import { Footer } from "@/components/layout/Footer";
|
|
import localFont from "next/font/local";
|
|
|
|
export async function generateMetadata({
|
|
params: { locale },
|
|
}: {
|
|
params: { locale: string };
|
|
}) {
|
|
const t = await getTranslations({ locale, namespace: "metadata" });
|
|
|
|
return {
|
|
metadataBase: new URL("https://bb-apartment.de"),
|
|
title: {
|
|
template: `%s | ${t("title")}`,
|
|
default: t("title"),
|
|
},
|
|
description: t("description"),
|
|
alternates: {
|
|
canonical: `/${locale}`,
|
|
languages: {
|
|
"de-DE": "/de",
|
|
"en-US": "/en",
|
|
"x-default": "/de",
|
|
},
|
|
},
|
|
openGraph: {
|
|
type: "website",
|
|
locale: locale === "de" ? "de_DE" : "en_US",
|
|
url: `https://bb-apartment.de/${locale}`,
|
|
siteName: "BB-Apartment",
|
|
title: t("title"),
|
|
description: t("description"),
|
|
},
|
|
twitter: {
|
|
card: "summary_large_image",
|
|
title: t("title"),
|
|
description: t("description"),
|
|
},
|
|
robots: {
|
|
index: true,
|
|
follow: true,
|
|
},
|
|
};
|
|
}
|
|
|
|
const geistSans = localFont({
|
|
src: "../fonts/GeistVF.woff",
|
|
variable: "--font-geist-sans",
|
|
weight: "100 900",
|
|
});
|
|
|
|
export default async function LocaleLayout({
|
|
children,
|
|
params: { locale },
|
|
}: {
|
|
children: ReactNode;
|
|
params: { locale: string };
|
|
}) {
|
|
if (!locales.includes(locale as Locale)) notFound();
|
|
|
|
const messages = await getMessages();
|
|
|
|
return (
|
|
<html lang={locale} className={geistSans.variable}>
|
|
<body className="antialiased min-h-screen flex flex-col bg-white text-brand-grey-dark">
|
|
<NextIntlClientProvider messages={messages} locale={locale}>
|
|
<Header locale={locale} />
|
|
<main className="flex-grow pt-20">{children}</main>
|
|
<Footer />
|
|
</NextIntlClientProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|