diff --git a/app/__tests__/components/Hero.test.tsx b/app/__tests__/components/Hero.test.tsx index 5f540b7..fd73215 100644 --- a/app/__tests__/components/Hero.test.tsx +++ b/app/__tests__/components/Hero.test.tsx @@ -1,16 +1,21 @@ import { render, screen } from '@testing-library/react'; import Hero from '@/app/components/Hero'; -// Mock next-intl -jest.mock('next-intl', () => ({ - useLocale: () => 'en', - useTranslations: () => (key: string) => { +// Mock next-intl/server +jest.mock('next-intl/server', () => ({ + getTranslations: () => Promise.resolve((key: string) => { const messages: Record = { description: 'Dennis is a student and passionate self-hoster.', - ctaWork: 'View My Work' + ctaWork: 'View My Work', + ctaContact: 'Get in touch', }; return messages[key] || key; - }, + }), +})); + +// Mock directus getMessages +jest.mock('@/lib/directus', () => ({ + getMessages: () => Promise.resolve({}), })); // Mock next/image @@ -36,8 +41,9 @@ jest.mock('next/image', () => ({ })); describe('Hero', () => { - it('renders the hero section correctly', () => { - render(); + it('renders the hero section correctly', async () => { + const HeroResolved = await Hero({ locale: 'en' }); + render(HeroResolved); // Check for the main headlines (defaults in Hero.tsx) expect(screen.getByText('Building')).toBeInTheDocument(); diff --git a/app/_ui/HomePage.tsx b/app/_ui/HomePage.tsx index 6a95652..2cdde49 100644 --- a/app/_ui/HomePage.tsx +++ b/app/_ui/HomePage.tsx @@ -41,7 +41,7 @@ export default function HomePage() { {/* Spacer to prevent navbar overlap */}
- + {/* Wavy Separator 1 - Hero to About */}
diff --git a/app/_ui/HomePageServer.tsx b/app/_ui/HomePageServer.tsx index d2bc7e4..67f150c 100644 --- a/app/_ui/HomePageServer.tsx +++ b/app/_ui/HomePageServer.tsx @@ -1,14 +1,13 @@ import Header from "../components/Header.server"; +import Hero from "../components/Hero"; import Script from "next/script"; import { - getHeroTranslations, getAboutTranslations, getProjectsTranslations, getContactTranslations, getFooterTranslations, } from "@/lib/translations-loader"; import { - HeroClient, AboutClient, ProjectsClient, ContactClient, @@ -20,9 +19,8 @@ interface HomePageServerProps { } export default async function HomePageServer({ locale }: HomePageServerProps) { - // Parallel laden aller Translations - const [heroT, aboutT, projectsT, contactT, footerT] = await Promise.all([ - getHeroTranslations(locale), + // Parallel laden aller Translations (hero translations handled by Hero server component) + const [aboutT, projectsT, contactT, footerT] = await Promise.all([ getAboutTranslations(locale), getProjectsTranslations(locale), getContactTranslations(locale), @@ -57,7 +55,7 @@ export default async function HomePageServer({ locale }: HomePageServerProps) { {/* Spacer to prevent navbar overlap */}
- + {/* Wavy Separator 1 - Hero to About */}
diff --git a/app/components/ClientWrappers.tsx b/app/components/ClientWrappers.tsx index 7003119..20fdbec 100644 --- a/app/components/ClientWrappers.tsx +++ b/app/components/ClientWrappers.tsx @@ -7,9 +7,7 @@ import { NextIntlClientProvider } from 'next-intl'; import dynamic from 'next/dynamic'; -import Hero from './Hero'; import type { - HeroTranslations, AboutTranslations, ProjectsTranslations, ContactTranslations, @@ -30,23 +28,6 @@ function getNormalizedLocale(locale: string): 'en' | 'de' { return locale.startsWith('de') ? 'de' : 'en'; } -export function HeroClient({ locale }: { locale: string; translations: HeroTranslations }) { - const normalLocale = getNormalizedLocale(locale); - const baseMessages = messageMap[normalLocale]; - - const messages = { - home: { - hero: baseMessages.home.hero - } - }; - - return ( - - - - ); -} - export function AboutClient({ locale }: { locale: string; translations: AboutTranslations }) { const normalLocale = getNormalizedLocale(locale); const baseMessages = messageMap[normalLocale]; diff --git a/app/components/Hero.tsx b/app/components/Hero.tsx index c6a119c..d00c988 100644 --- a/app/components/Hero.tsx +++ b/app/components/Hero.tsx @@ -1,27 +1,17 @@ -"use client"; - -import { useLocale, useTranslations } from "next-intl"; +import { getTranslations } from "next-intl/server"; import Image from "next/image"; -import { useEffect, useState } from "react"; +import { getMessages } from "@/lib/directus"; -const Hero = () => { - const locale = useLocale(); - const t = useTranslations("home.hero"); - const [cmsMessages, setCmsMessages] = useState>({}); +interface HeroProps { + locale: string; +} - useEffect(() => { - (async () => { - try { - const res = await fetch(`/api/messages?locale=${locale}`); - if (res.ok) { - const data = await res.json(); - setCmsMessages(data.messages || {}); - } - } catch {} - })(); - }, [locale]); +export default async function Hero({ locale }: HeroProps) { + const [t, cmsMessages] = await Promise.all([ + getTranslations("home.hero"), + getMessages(locale).catch(() => ({} as Record)), + ]); - // Helper to get CMS text or fallback const getLabel = (key: string, fallback: string) => cmsMessages[key] || fallback; return ( @@ -86,6 +76,4 @@ const Hero = () => {
); -}; - -export default Hero; +}