feat: complete POI Clean House website with Karcher theme, blog, interactive animations and full CMS configuration

This commit is contained in:
2026-08-26 02:49:44 +02:00
commit 9acdfe05d3
57 changed files with 11415 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
import { notFound } from 'next/navigation'
import type { ReactNode } from 'react'
import {
getConsentTexts,
getAnalyticsConfig,
getSystemPagePath,
} from '@intecion/ipal-kit'
import {
ConsentProvider,
CookieBanner,
CookieButton,
Analytics,
} from '@intecion/ipal-kit/client'
import { i18nConfig } from '@/i18n.config'
import { getCachedPayload, getConfiguredLocales } from '@/lib/content'
import { getSettings } from '@/lib/payload'
import { Header, type NavItem } from '@/components/Header'
import { Footer, type FooterNavItem } from '@/components/Footer'
import '../styles.css'
import type { Company, Navigation, Page } from '@/payload-types'
interface LayoutProps {
children: ReactNode
params: Promise<{ locale: string }>
}
function resolveNavItemHref(item: { page?: Page | number | string | null; url?: string | null }): string {
if (item.url) return item.url
if (item.page && typeof item.page === 'object' && 'slug' in item.page && item.page.slug) {
return item.page.slug === 'home' ? '/' : `/${item.page.slug}`
}
return '#'
}
export default async function LocaleLayout({ children, params }: LayoutProps) {
const { locale } = await params
const locales = await getConfiguredLocales()
if (!locales.includes(locale)) notFound()
const payload = await getCachedPayload()
const settings = await getSettings(locale)
const privacyPage = (settings as { privacyPolicy?: unknown })?.privacyPolicy
const cookiePage = (settings as { cookiePolicy?: unknown })?.cookiePolicy
const homePage = (settings as { homepage?: unknown })?.homepage
let company: Company | null = null
let navigation: Navigation | null = null
try {
const [compDoc, navDoc] = await Promise.all([
payload.findGlobal({ slug: 'company', locale: locale as never }),
payload.findGlobal({ slug: 'navigation', locale: locale as never, depth: 2 }),
])
company = compDoc
navigation = navDoc
} catch {
// fallback if globals not yet created
}
const privacyHref = privacyPage
? getSystemPagePath({ config: i18nConfig, locale, page: privacyPage })
: undefined
const cookieHref = cookiePage
? getSystemPagePath({ config: i18nConfig, locale, page: cookiePage })
: undefined
const homeHref = homePage
? getSystemPagePath({ config: i18nConfig, locale, page: homePage }) || '/'
: '/'
const [texts, analytics] = await Promise.all([
getConsentTexts({
config: i18nConfig,
locale,
payload,
privacyPolicy:
privacyPage && typeof privacyPage === 'object'
? { page: privacyPage, label: 'Polityka prywatności' }
: undefined,
}),
getAnalyticsConfig(payload),
])
const headerItems: NavItem[] =
navigation?.headerItems?.map((item) => ({
id: item.id || undefined,
label: item.label,
href: resolveNavItemHref(item),
})) || []
const footerItems: FooterNavItem[] =
navigation?.footerItems?.map((item) => ({
id: item.id || undefined,
label: item.label,
href: resolveNavItemHref(item),
})) || []
return (
<html lang={locale}>
<body className="min-h-screen flex flex-col bg-slate-950 text-slate-100 antialiased selection:bg-sky-500 selection:text-white">
<ConsentProvider texts={texts}>
<Header
companyName={company?.shortName || company?.name}
tagline={navigation?.tagline}
items={headerItems}
phone={company?.phone}
homeHref={homeHref}
currentLocale={locale}
contactHref={`/${locale}/kontakt`}
contactLabel="KONTAKT"
/>
<main className="flex-1">{children}</main>
<Footer
companyName={company?.name}
footerTagline={navigation?.footerTagline}
nip={company?.nip}
regon={company?.regon}
address={company?.address}
city={company?.city}
phone={company?.phone}
email={company?.email}
items={footerItems}
privacyHref={privacyHref}
cookieHref={cookieHref}
/>
<CookieBanner
classNames={{
root: 'fixed bottom-0 inset-x-0 z-50 bg-[#1f1f1f] text-white p-6 border-t-4 border-[#FFED00] shadow-2xl',
primaryButton:
'bg-[#FFED00] hover:bg-[#fae100] text-[#1f1f1f] border-2 border-[#1f1f1f] px-6 py-2.5 text-xs font-black uppercase tracking-widest transition-all cursor-pointer shadow-xs',
secondaryButton:
'bg-[#2b2b2b] hover:bg-[#383838] text-white border border-[#444444] px-4 py-2.5 text-xs font-bold uppercase tracking-wider transition-colors cursor-pointer',
}}
/>
<CookieButton className="fixed bottom-4 left-4 z-40 bg-[#1f1f1f] hover:bg-[#FFED00] text-[#FFED00] hover:text-[#1f1f1f] border-2 border-[#FFED00] p-2.5 transition-all shadow-lg cursor-pointer" />
<Analytics {...analytics} />
</ConsentProvider>
</body>
</html>
)
}
export async function generateStaticParams() {
const locales = await getConfiguredLocales()
return locales.map((locale) => ({ locale }))
}