church-website/src/app/(home)/layout.tsx
2026-03-09 11:16:32 +01:00

107 lines
No EOL
2.8 KiB
TypeScript

import type { Metadata } from 'next'
import './globals.css'
import { Menu } from '@/components/Menu/Menu'
import { Footer } from '@/compositions/Footer/Footer'
import { comment } from '@/app/(home)/layout-comment'
import { FONT_MAP, getFont } from '@/assets/fonts'
import { siteConfig } from '@/config/site'
import { fetchDesign } from '@/fetch/design'
import { fetchSiteConfig } from '@/fetch/siteConfig'
import { FetchedMenu } from '@/components/Menu/FetchedMenu'
export const dynamic = 'force-dynamic'
export async function generateMetadata(): Promise<Metadata> {
let site
try {
site = await fetchSiteConfig()
} catch {
site = null
}
const name = site?.name || siteConfig.name
const shortName = site?.shortName || siteConfig.shortName
const description = site?.description || siteConfig.description
const url = site?.url || siteConfig.url
const ogImage = site?.ogImage || siteConfig.ogImage
const keywords =
site?.keywords?.map((k) => k.keyword) || siteConfig.keywords
return {
title: {
default: name,
template: `%s | ${shortName}`,
},
description,
keywords,
metadataBase: new URL(url),
openGraph: {
title: name,
description,
url,
siteName: name,
images: [ogImage],
locale: 'de_DE',
type: 'website',
},
}
}
const DESIGN_DEFAULTS = {
baseColor: '#016699',
shade1: '#67A3C2',
shade2: '#DDECF7',
shade3: '#eff6ff',
contrastColor: '#CE490F',
contrastShade1: '#DA764B',
borderRadius: '13px',
defaultFont: 'cairo',
headerFont: 'faustina',
}
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
let design
try {
design = await fetchDesign()
} catch {
design = null
}
const selectedDefaultFont = getFont(
design?.defaultFont || DESIGN_DEFAULTS.defaultFont,
FONT_MAP.cairo,
)
const selectedHeaderFont = getFont(
design?.headerFont || DESIGN_DEFAULTS.headerFont,
FONT_MAP.faustina,
)
const themeStyle = {
'--base-color': design?.baseColor || DESIGN_DEFAULTS.baseColor,
'--shade1': design?.shade1 || DESIGN_DEFAULTS.shade1,
'--shade2': design?.shade2 || DESIGN_DEFAULTS.shade2,
'--shade3': design?.shade3 || DESIGN_DEFAULTS.shade3,
'--contrast-color': design?.contrastColor || DESIGN_DEFAULTS.contrastColor,
'--contrast-shade1':
design?.contrastShade1 || DESIGN_DEFAULTS.contrastShade1,
'--border-radius': design?.borderRadius || DESIGN_DEFAULTS.borderRadius,
'--header-font': selectedHeaderFont.style.fontFamily,
} as React.CSSProperties
return (
<html lang="de" className={selectedDefaultFont.className} style={themeStyle}>
<body>
<div dangerouslySetInnerHTML={{ __html: comment }}></div>
<FetchedMenu />
<main className={"mainContent"}>
{children}
</main>
<Footer />
</body>
</html>
)
}