88 lines
3.2 KiB
TypeScript
88 lines
3.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import { Globe } from "lucide-react";
|
|
|
|
interface Language {
|
|
code: string;
|
|
name: string;
|
|
flag: string;
|
|
}
|
|
|
|
const LANGUAGES: Language[] = [
|
|
{ code: "en", name: "English", flag: "🇺🇸" },
|
|
{ code: "es", name: "Español", flag: "🇪🇸" },
|
|
{ code: "fr", name: "Français", flag: "🇫🇷" },
|
|
{ code: "de", name: "Deutsch", flag: "🇩🇪" },
|
|
{ code: "it", name: "Italiano", flag: "🇮🇹" },
|
|
{ code: "pt", name: "Português", flag: "🇵🇹" },
|
|
{ code: "ja", name: "日本語", flag: "🇯🇵" },
|
|
{ code: "zh", name: "中文", flag: "🇨🇳" },
|
|
{ code: "ko", name: "한국어", flag: "🇰🇷" },
|
|
];
|
|
|
|
export default function LanguageSwitcher() {
|
|
const [currentLanguage, setCurrentLanguage] = useState<string>("en");
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [mounted, setMounted] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
// Get stored language preference from localStorage
|
|
const stored = typeof window !== "undefined" ? localStorage.getItem("beatcraft-language") : null;
|
|
if (stored) {
|
|
setCurrentLanguage(stored);
|
|
document.documentElement.lang = stored;
|
|
}
|
|
}, []);
|
|
|
|
const handleLanguageChange = (code: string) => {
|
|
setCurrentLanguage(code);
|
|
localStorage.setItem("beatcraft-language", code);
|
|
document.documentElement.lang = code;
|
|
setIsOpen(false);
|
|
// Dispatch custom event for components to listen to language changes
|
|
window.dispatchEvent(new CustomEvent("languageChange", { detail: { language: code } }));
|
|
};
|
|
|
|
const currentLang = LANGUAGES.find((lang) => lang.code === currentLanguage) || LANGUAGES[0];
|
|
|
|
if (!mounted) return null;
|
|
|
|
return (
|
|
<div className="fixed top-4 right-4 z-50">
|
|
<div className="relative">
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className="flex items-center gap-2 px-3 py-2 rounded-lg bg-primary-cta/10 hover:bg-primary-cta/20 border border-primary-cta/20 transition-all duration-200"
|
|
aria-label="Change language"
|
|
>
|
|
<Globe size={18} className="text-primary-cta" />
|
|
<span className="text-sm font-medium text-foreground">{currentLang.flag}</span>
|
|
</button>
|
|
|
|
{isOpen && (
|
|
<div className="absolute top-full right-0 mt-2 bg-card border border-foreground/10 rounded-lg shadow-lg overflow-hidden min-w-48">
|
|
<div className="max-h-96 overflow-y-auto">
|
|
{LANGUAGES.map((lang) => (
|
|
<button
|
|
key={lang.code}
|
|
onClick={() => handleLanguageChange(lang.code)}
|
|
className={`w-full px-4 py-2 text-left flex items-center gap-3 transition-colors duration-150 ${
|
|
currentLanguage === lang.code
|
|
? "bg-primary-cta/20 text-primary-cta"
|
|
: "hover:bg-foreground/5 text-foreground"
|
|
}`}
|
|
>
|
|
<span className="text-lg">{lang.flag}</span>
|
|
<span className="text-sm font-medium">{lang.name}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|