Files
anouma/app/(frontend)/layout.tsx
T
maro 5d83c0dc1e Add calendar-based booking system: accounts, availability, admin calendar
- Customer accounts (separate auth collection) with /konto area
- Availability + AvailabilityOverrides collections driving real slot calculation
- BookingRequests with race-safe confirmation (Postgres advisory lock + transaction)
- Booking emails (request received, admin notify, confirmed, rejected, alternative proposed/accepted, cancelled)
- Confirmed online bookings auto-create a private linked video-call Event
- Custom Payload admin calendar view (month grid + day schedule)
- Wired booking widget into offer pages and /termin-buchen
2026-08-25 16:52:34 +02:00

73 lines
2.2 KiB
TypeScript

import type { Metadata } from "next";
import { Cormorant_Garamond, Inter } from "next/font/google";
import { Navbar } from "@/components/Navbar";
import { Footer } from "@/components/Footer";
import { siteConfig } from "@/lib/site";
import { getOffers } from "@/lib/payload/content";
import { getCurrentCustomer } from "@/lib/auth/customer";
import "./globals.css";
// Every page under this layout can read live content from Payload, so the
// whole subtree is rendered dynamically rather than statically at build time.
export const dynamic = "force-dynamic";
const cormorant = Cormorant_Garamond({
variable: "--font-cormorant",
subsets: ["latin"],
weight: ["400", "500", "600"],
style: ["normal", "italic"],
});
const inter = Inter({
variable: "--font-inter",
subsets: ["latin"],
});
export const metadata: Metadata = {
metadataBase: new URL(siteConfig.domain),
title: {
default: siteConfig.title,
template: `%s — ${siteConfig.name}`,
},
description: siteConfig.description,
openGraph: {
type: "website",
locale: siteConfig.locale,
url: siteConfig.domain,
siteName: siteConfig.name,
title: siteConfig.title,
description: siteConfig.description,
},
twitter: {
card: "summary_large_image",
title: siteConfig.title,
description: siteConfig.description,
},
};
export default async function RootLayout({ children }: LayoutProps<"/">) {
const [offers, customer] = await Promise.all([getOffers(), getCurrentCustomer()]);
return (
<html
lang="de"
data-scroll-behavior="smooth"
className={`${cormorant.variable} ${inter.variable} h-full antialiased`}
>
<body className="flex min-h-full flex-col bg-background text-foreground">
<a
href="#main-content"
className="sr-only focus:not-sr-only focus:absolute focus:left-4 focus:top-4 focus:z-[100] focus:rounded-full focus:bg-anouma-mauve-dark focus:px-5 focus:py-3 focus:text-anouma-cream-light"
>
Zum Inhalt springen
</a>
<Navbar offers={offers} customerName={customer?.name ?? null} />
<main id="main-content" className="flex-1">
{children}
</main>
<Footer />
</body>
</html>
);
}