Files
e-tib.com/app/[locale]/page.tsx

165 lines
5.3 KiB
TypeScript

import { Metadata } from 'next';
import { setRequestLocale } from 'next-intl/server';
import { notFound } from 'next/navigation';
import { getMdxContent } from '@/lib/mdx';
import { MDXRemote } from 'next-mdx-remote/rsc';
import nextDynamic from 'next/dynamic';
import { getImageProps } from 'next/image';
import { HeroVideo as HomeHero } from '@/components/blocks/HeroVideo';
const HomeSubCompanyTiles = nextDynamic(() => import('@/components/blocks/SubCompanyTiles').then(mod => mod.SubCompanyTiles));
const HomeCompetenceBentoGrid = nextDynamic(() => import('@/components/blocks/CompetenceBentoGrid').then(mod => mod.CompetenceBentoGrid));
const HomeReferencesSlider = nextDynamic(() => import('@/components/blocks/ReferencesSlider').then(mod => mod.ReferencesSlider));
const FaqBlock = nextDynamic(() => import('@/components/blocks/FaqBlock').then(mod => mod.FaqBlock));
const CertificatesBlock = nextDynamic(() => import('@/components/blocks/CertificatesBlock').then(mod => mod.CertificatesBlock));
import { HeroSection } from '@/components/blocks/HeroSection';
import JsonLd from '@/components/JsonLd';
import { Button } from '@/components/ui/Button';
import { Heading } from '@/components/ui/Heading';
const AnimatedCounter = nextDynamic(() => import('@/components/ui').then(mod => mod.AnimatedCounter));
const InteractiveGermanyMap = nextDynamic(() => import('@/components/blocks/InteractiveGermanyMap').then(mod => mod.InteractiveGermanyMap));
const ScaleOfImpact = nextDynamic(() => import('@/components/blocks/ScaleOfImpact').then(mod => mod.ScaleOfImpact));
import { getAllReferences } from '@/lib/references';
const mdxComponents = (references: any[]) => ({
HomeHero,
HomeSubCompanyTiles,
HomeCompetenceBentoGrid,
HomeReferencesSlider: (props: any) => <HomeReferencesSlider {...props} references={props.references || references} />,
FaqBlock,
CertificatesBlock,
HeroSection,
JsonLd,
Button,
Heading,
AnimatedCounter,
InteractiveGermanyMap,
ScaleOfImpact,
ResponsiveImage: (props: any) => {
// Parse src if it's already a next image proxy
let src = props.src;
if (typeof src === 'string' && src.startsWith('/_next/image')) {
try {
const urlParam = new URLSearchParams(src.split('?')[1]).get('url');
if (urlParam) src = decodeURIComponent(urlParam);
} catch (e) {
// Fallback
}
}
// Use Next.js getImageProps for responsive srcSet generation
const {
props: { srcSet, src: finalSrc, sizes }
} = getImageProps({
src,
alt: props.alt || '',
width: 1920,
height: 1080,
sizes: '(max-width: 768px) 100vw, (max-width: 1200px) 75vw, 50vw',
quality: 80,
});
return (
<img
{...props}
src={finalSrc}
srcSet={srcSet}
sizes={sizes}
loading="lazy"
decoding="async"
/>
);
},
img: (props: any) => {
// Parse src if it's already a next image proxy
let src = props.src;
if (typeof src === 'string' && src.startsWith('/_next/image')) {
try {
const urlParam = new URLSearchParams(src.split('?')[1]).get('url');
if (urlParam) src = decodeURIComponent(urlParam);
} catch (e) {
// Fallback
}
}
// Use Next.js getImageProps for responsive srcSet generation
const {
props: { srcSet, src: finalSrc, sizes }
} = getImageProps({
src,
alt: props.alt || '',
width: 1920,
height: 1080,
sizes: '(max-width: 768px) 100vw, (max-width: 1200px) 75vw, 50vw',
quality: 80,
});
return (
<img
{...props}
src={finalSrc}
srcSet={srcSet}
sizes={sizes}
loading="lazy"
decoding="async"
style={{ width: '100%', height: 'auto', ...props.style }}
/>
);
}
});
export async function generateMetadata(props: any): Promise<Metadata> {
const { locale } = await props.params;
if (locale !== 'de' && locale !== 'en') return {};
const mdx = await getMdxContent(locale, 'home');
return {
title: mdx?.frontmatter?.title || (locale === 'de' ? 'Startseite' : 'Home'),
description: mdx?.frontmatter?.description,
};
}
import { preload } from 'react-dom';
export default async function Home(props: { params: Promise<{ locale: string }> }) {
const { locale } = await props.params;
if (locale !== 'de' && locale !== 'en') {
notFound();
}
setRequestLocale(locale);
preload('/assets/videos/web/hero-kabelpflug-poster.webp', {
as: 'image',
fetchPriority: 'high',
imageSrcSet: '/assets/videos/web/hero-kabelpflug-poster-mobile.webp 800w, /assets/videos/web/hero-kabelpflug-poster.webp 1920w',
imageSizes: '100vw'
});
const mdx = await getMdxContent(locale, 'home');
const allReferences = await getAllReferences(locale);
// Transform ReferenceData to the format expected by ReferencesSlider
const sliderReferences = allReferences.map(ref => ({
id: ref.slug,
title: ref.frontmatter.title,
slug: ref.slug,
category: ref.frontmatter.location, // Using location as category if not specified
image: ref.frontmatter.featuredImage
})).slice(0, 6);
if (!mdx) {
notFound();
}
return (
<main>
<MDXRemote source={mdx.content} components={mdxComponents(sliderReferences)} />
</main>
);
}