107 lines
No EOL
2.8 KiB
TypeScript
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>
|
|
)
|
|
} |