feat(i18n): add locale switcher
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"use client"
|
||||
|
||||
import { useLocale, useTranslations } from "next-intl"
|
||||
import { useRouter, usePathname } from "@/i18n/navigation"
|
||||
import { Languages } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import { routing } from "@/i18n/routing"
|
||||
|
||||
|
||||
|
||||
export function LocaleSwitch() {
|
||||
const currentLocale = useLocale()
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
|
||||
const t = useTranslations('languages');
|
||||
const localeLabels: Record<string, string> = {
|
||||
de: t('german'),
|
||||
en: t('english'),
|
||||
}
|
||||
|
||||
function switchLocale(newLocale: string) {
|
||||
router.replace(pathname, { locale: newLocale })
|
||||
}
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="icon">
|
||||
<Languages className="size-5" />
|
||||
<span className="sr-only">Toggle language</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{routing.locales.map((locale) => (
|
||||
<DropdownMenuItem
|
||||
key={locale}
|
||||
onClick={() => switchLocale(locale)}
|
||||
className={currentLocale === locale ? "font-medium" : ""}
|
||||
>
|
||||
{localeLabels[locale]}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import Link from "next/link"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { ThemeSwitch } from "./theme-switch"
|
||||
import { useTranslations } from "next-intl"
|
||||
import { LocaleSwitch } from "./locale-switch"
|
||||
|
||||
export default function Navbar() {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
@@ -55,7 +56,10 @@ export default function Navbar() {
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<ThemeSwitch/>
|
||||
<LocaleSwitch/>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Moon, Sun } from "lucide-react"
|
||||
import { useTheme } from "next-themes"
|
||||
|
||||
@@ -11,9 +10,17 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import { useTranslations } from "next-intl"
|
||||
|
||||
export function ThemeSwitch() {
|
||||
const { setTheme } = useTheme()
|
||||
const { setTheme } = useTheme();
|
||||
|
||||
const t = useTranslations('themes');
|
||||
const themeLabels: Record<string, string> = {
|
||||
light: t('light'),
|
||||
dark: t('dark'),
|
||||
system: t('system'),
|
||||
}
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
@@ -26,13 +33,13 @@ export function ThemeSwitch() {
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => setTheme("light")}>
|
||||
Light
|
||||
{themeLabels['light']}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("dark")}>
|
||||
Dark
|
||||
{themeLabels['dark']}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("system")}>
|
||||
System
|
||||
{themeLabels['system']}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
+1
-1
@@ -2,6 +2,6 @@ import { defineRouting } from "next-intl/routing";
|
||||
|
||||
export const routing = defineRouting({
|
||||
locales: ["de", "en"],
|
||||
defaultLocale: "de",
|
||||
defaultLocale: "en",
|
||||
localePrefix: "as-needed",
|
||||
});
|
||||
@@ -3,5 +3,14 @@
|
||||
"home": "Startseite",
|
||||
"aboutMe": "Über Mich",
|
||||
"projects": "Projekte"
|
||||
},
|
||||
"languages": {
|
||||
"english": "Englisch",
|
||||
"german": "Deutsch"
|
||||
},
|
||||
"themes": {
|
||||
"light": "Hell",
|
||||
"dark": "Dunkel",
|
||||
"system": "System"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,5 +3,14 @@
|
||||
"home": "Home",
|
||||
"aboutMe": "About Me",
|
||||
"projects": "Projects"
|
||||
},
|
||||
"languages": {
|
||||
"german": "German",
|
||||
"english": "English"
|
||||
},
|
||||
"themes": {
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"system": "System"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user