locale upgrade

This commit is contained in:
2026-01-22 20:56:35 +01:00
parent 377631ee50
commit 37a1bc4e18
28 changed files with 2117 additions and 71 deletions

View File

@@ -2,6 +2,16 @@ import { NextIntlClientProvider } from "next-intl";
import { setRequestLocale } from "next-intl/server";
import React from "react";
import ConsentBanner from "../components/ConsentBanner";
import { getLocalizedMessage } from "@/lib/i18n-loader";
async function loadEnhancedMessages(locale: string) {
// Lade basis JSON Messages
const baseMessages = (await import(`../../messages/${locale}.json`)).default;
// Erweitere mit Directus (wenn verfügbar)
// Für jetzt: return base messages, Directus wird per Server Component geladen
return baseMessages;
}
export default async function LocaleLayout({
children,
@@ -15,7 +25,7 @@ export default async function LocaleLayout({
setRequestLocale(locale);
// Load messages explicitly by route locale to avoid falling back to the wrong
// language when request-level locale detection is unavailable/misconfigured.
const messages = (await import(`../../messages/${locale}.json`)).default;
const messages = await loadEnhancedMessages(locale);
return (
<NextIntlClientProvider locale={locale} messages={messages}>

View File

@@ -1,5 +1,5 @@
import type { Metadata } from "next";
import HomePage from "../_ui/HomePage";
import HomePageServer from "../_ui/HomePageServer";
import { getLanguageAlternates, toAbsoluteUrl } from "@/lib/seo";
export async function generateMetadata({
@@ -17,7 +17,12 @@ export async function generateMetadata({
};
}
export default function Page() {
return <HomePage />;
export default async function Page({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
return <HomePageServer locale={locale} />;
}

View File

@@ -32,20 +32,32 @@ export default async function ProjectPage({
where: { slug, published: true },
include: {
translations: {
where: { locale },
select: { title: true, description: true },
select: { title: true, description: true, content: true, locale: true },
},
},
});
if (!project) return notFound();
const tr = project.translations?.[0];
const trPreferred = project.translations?.find((t) => t.locale === locale && (t?.title || t?.description));
const trDefault = project.translations?.find(
(t) => t.locale === project.defaultLocale && (t?.title || t?.description),
);
const tr = trPreferred ?? trDefault;
const { translations: _translations, ...rest } = project;
const localizedContent = (() => {
if (typeof tr?.content === "string") return tr.content;
if (tr?.content && typeof tr.content === "object" && "markdown" in tr.content) {
const markdown = (tr.content as Record<string, unknown>).markdown;
if (typeof markdown === "string") return markdown;
}
return project.content;
})();
const localized = {
...rest,
title: tr?.title ?? project.title,
description: tr?.description ?? project.description,
content: localizedContent,
};
return <ProjectDetailClient project={localized} locale={locale} />;

View File

@@ -32,14 +32,17 @@ export default async function ProjectsPage({
orderBy: { createdAt: "desc" },
include: {
translations: {
where: { locale },
select: { title: true, description: true },
select: { title: true, description: true, locale: true },
},
},
});
const localized = projects.map((p) => {
const tr = p.translations?.[0];
const trPreferred = p.translations?.find((t) => t.locale === locale && (t?.title || t?.description));
const trDefault = p.translations?.find(
(t) => t.locale === p.defaultLocale && (t?.title || t?.description),
);
const tr = trPreferred ?? trDefault;
const { translations: _translations, ...rest } = p;
return {
...rest,