31560a712f
- Fix ClientWrappers missing 'about' namespace (MISSING_MESSAGE error) - Add system/light/dark theme toggle with prefers-color-scheme detection - Rewrite 404 page with i18n, accessibility, and proper navigation - Rewrite books page with Header/Footer, i18n, and semantic HTML - Add i18n keys to About, Footer, and both locale files - Fix dark mode contrast: text-stone-300/600 -> text-stone-400 - Replace raw hex bg-[#fdfcf8] with bg-stone-50 across all components - Guard console.error in ChatWidget and manage/page behind NODE_ENV - Add aria-label to admin login form - Remove emoji from manage page password toggle - Update stale dates in privacy-policy and legal-notice - Fix ScrollFadeIn index->delay prop type error in books page - Fix privacy-policy and legal-notice landmark structure - Add pre-push-check.test.ts: 13-category static analysis (i18n parity, namespace coverage, key resolution, accessibility, email validation, hex colors, emojis, console guards, env docs, types) - Add explicit i18n check step to CI workflow
98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* Transitional Wrapper für bestehende Components
|
|
* Nutzt direkt JSON Messages statt komplexe Translation-Loader
|
|
*/
|
|
|
|
import { NextIntlClientProvider } from 'next-intl';
|
|
import dynamic from 'next/dynamic';
|
|
|
|
// Lazy-load below-fold components so their JS doesn't block initial paint / LCP.
|
|
// SSR stays on (default) so content is in the initial HTML for SEO.
|
|
const About = dynamic(() => import('./About'));
|
|
const Projects = dynamic(() => import('./Projects'));
|
|
const Contact = dynamic(() => import('./Contact'));
|
|
const Footer = dynamic(() => import('./Footer'));
|
|
import type {
|
|
AboutTranslations,
|
|
ProjectsTranslations,
|
|
ContactTranslations,
|
|
FooterTranslations,
|
|
} from '@/types/translations';
|
|
import enMessages from '@/messages/en.json';
|
|
import deMessages from '@/messages/de.json';
|
|
|
|
const messageMap = { en: enMessages, de: deMessages };
|
|
|
|
function getNormalizedLocale(locale: string): 'en' | 'de' {
|
|
return locale.startsWith('de') ? 'de' : 'en';
|
|
}
|
|
|
|
export function AboutClient({ locale }: { locale: string; translations: AboutTranslations }) {
|
|
const normalLocale = getNormalizedLocale(locale);
|
|
const baseMessages = messageMap[normalLocale];
|
|
|
|
const messages = {
|
|
home: {
|
|
about: baseMessages.home.about
|
|
},
|
|
about: baseMessages.about
|
|
};
|
|
|
|
return (
|
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
|
<About />
|
|
</NextIntlClientProvider>
|
|
);
|
|
}
|
|
|
|
export function ProjectsClient({ locale }: { locale: string; translations: ProjectsTranslations }) {
|
|
const normalLocale = getNormalizedLocale(locale);
|
|
const baseMessages = messageMap[normalLocale];
|
|
|
|
const messages = {
|
|
home: {
|
|
projects: baseMessages.home.projects
|
|
}
|
|
};
|
|
|
|
return (
|
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
|
<Projects />
|
|
</NextIntlClientProvider>
|
|
);
|
|
}
|
|
|
|
export function ContactClient({ locale }: { locale: string; translations: ContactTranslations }) {
|
|
const normalLocale = getNormalizedLocale(locale);
|
|
const baseMessages = messageMap[normalLocale];
|
|
|
|
const messages = {
|
|
home: {
|
|
contact: baseMessages.home.contact
|
|
}
|
|
};
|
|
|
|
return (
|
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
|
<Contact />
|
|
</NextIntlClientProvider>
|
|
);
|
|
}
|
|
|
|
export function FooterClient({ locale }: { locale: string; translations: FooterTranslations }) {
|
|
const normalLocale = getNormalizedLocale(locale);
|
|
const baseMessages = messageMap[normalLocale];
|
|
|
|
const messages = {
|
|
footer: baseMessages.footer
|
|
};
|
|
|
|
return (
|
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
|
<Footer />
|
|
</NextIntlClientProvider>
|
|
);
|
|
}
|