From 5b261699a1c74892a4a641e9caffa6044a73d726 Mon Sep 17 00:00:00 2001 From: Chneemann Date: Sun, 2 Aug 2026 07:28:42 +0200 Subject: [PATCH] feat: add localized language switcher and translate header component --- src/components/Header.tsx | 173 +++++++++++++++++++++++--------------- src/i18n/messages/de.json | 10 ++- src/i18n/messages/en.json | 10 ++- 3 files changed, 121 insertions(+), 72 deletions(-) diff --git a/src/components/Header.tsx b/src/components/Header.tsx index c3b65a9..ef8fb9c 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,20 +1,26 @@ "use client"; import { useState } from "react"; -import Link from "next/link"; +import { Link, usePathname } from "@/i18n/navigation"; +import { useTranslations, useLocale } from "next-intl"; /** - * Main navigation header with desktop/mobile views and Command Palette trigger + * Main navigation header with desktop/mobile views, Command Palette trigger and Language Switcher */ export default function Header() { const [isOpen, setIsOpen] = useState(false); + const tCommon = useTranslations("Common"); + const tHeader = useTranslations("Header"); - // Smooth scroll navigation targets + const locale = useLocale(); + const pathname = usePathname(); + + // Smooth scroll navigation targets mapped to translations const navLinks = [ - { label: "About me", href: "#aboutme" }, - { label: "My Skills", href: "#myskills" }, - { label: "Portfolio", href: "#portfolio" }, - { label: "Contact me", href: "#contactme" }, + { label: tCommon("about"), href: "#aboutme" }, + { label: tCommon("skills"), href: "#myskills" }, + { label: tCommon("portfolio"), href: "#portfolio" }, + { label: tCommon("contact"), href: "#contactme" }, ]; // Dispatches global custom event to open Cmd+K palette @@ -22,6 +28,34 @@ export default function Header() { window.dispatchEvent(new CustomEvent("toggle-cmd-k")); }; + // Toggle between de and en while staying on the current page + const nextLocale = locale === "de" ? "en" : "de"; + + // Reusable language switcher + const LanguageSwitcher = () => ( + + + + + {locale === "de" ? "EN" : "DE"} + + ); + return (
@@ -34,9 +68,9 @@ export default function Header() { ANDRÉ KEMPF. - {/* Right Area: Desktop Nav & Cmd+K Trigger */} -
-
- {/* Mobile Hamburger Toggle */} - + {/* Mobile Right Area: Language Switcher & Hamburger */} +
+ + + {/* Mobile Hamburger Toggle */} + +
{/* Mobile Fullscreen Navigation Overlay */}
setIsOpen(false)} - className={`fixed inset-0 w-full h-screen bg-slate-950/98 flex flex-col items-center justify-center gap-8 text-2xl font-semibold transition-all duration-300 md:hidden ${ + className={`fixed inset-0 w-full h-screen bg-slate-950/98 flex flex-col items-center justify-center gap-8 text-2xl font-semibold transition-all duration-300 md:hidden z-40 ${ isOpen ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none" @@ -113,22 +156,12 @@ export default function Header() { setIsOpen(false)} className="hover:text-blue-400 text-white transition-colors" > {link.label} ))} - - {/* Mobile Cmd+K Trigger inside Overlay */} -
diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 540af4e..964453e 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -1,3 +1,11 @@ { - "Common": {} + "Common": { + "about": "Über mich", + "skills": "Fähigkeiten", + "portfolio": "Portfolio", + "contact": "Kontakt" + }, + "Header": { + "search": "Suchen" + } } diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 540af4e..e500088 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -1,3 +1,11 @@ { - "Common": {} + "Common": { + "about": "About me", + "skills": "My Skills", + "portfolio": "Portfolio", + "contact": "Contact me" + }, + "Header": { + "search": "Search" + } }