92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
import { useTranslation } from "react-i18next";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuLabel,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import { Globe } from "lucide-react";
|
|
|
|
const LANGUAGES = [
|
|
{ code: "zh", label: "简体中文", flag: "🇨🇳", dir: "ltr" },
|
|
{ code: "en", label: "English", flag: "🇺🇸", dir: "ltr" },
|
|
{ code: "ar", label: "العربية", flag: "🇦🇪", dir: "rtl" },
|
|
{ code: "ja", label: "日本語", flag: "🇯🇵", dir: "ltr" },
|
|
{ code: "ko", label: "한국어", flag: "🇰🇷", dir: "ltr" },
|
|
{ code: "fr", label: "Français", flag: "🇫🇷", dir: "ltr" },
|
|
{ code: "ru", label: "Русский", flag: "🇷🇺", dir: "ltr" },
|
|
];
|
|
|
|
interface LanguageSwitcherProps {
|
|
variant?: "icon" | "full";
|
|
className?: string;
|
|
}
|
|
|
|
export function LanguageSwitcher({ variant = "icon", className }: LanguageSwitcherProps) {
|
|
const { i18n, t } = useTranslation();
|
|
|
|
const currentLang = LANGUAGES.find((l) => l.code === i18n.language) || LANGUAGES[0];
|
|
|
|
const handleLanguageChange = (code: string) => {
|
|
const lang = LANGUAGES.find((l) => l.code === code);
|
|
i18n.changeLanguage(code);
|
|
// Apply RTL/LTR direction to document
|
|
if (lang) {
|
|
document.documentElement.dir = lang.dir;
|
|
document.documentElement.lang = code;
|
|
}
|
|
// Persist language preference
|
|
localStorage.setItem("nac-admin-language", code);
|
|
};
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button
|
|
variant="ghost"
|
|
size={variant === "icon" ? "icon" : "sm"}
|
|
className={`text-slate-400 hover:text-white hover:bg-slate-700/50 ${className ?? ""}`}
|
|
>
|
|
<Globe className="h-4 w-4" />
|
|
{variant === "full" && (
|
|
<span className="ml-2 text-sm">
|
|
{currentLang.flag} {currentLang.label}
|
|
</span>
|
|
)}
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent
|
|
align="end"
|
|
className="w-48 bg-slate-800 border-slate-700 text-slate-200"
|
|
>
|
|
<DropdownMenuLabel className="text-slate-400 text-xs">
|
|
{t("languageSwitcher.selectLanguage")}
|
|
</DropdownMenuLabel>
|
|
<DropdownMenuSeparator className="bg-slate-700" />
|
|
{LANGUAGES.map((lang) => (
|
|
<DropdownMenuItem
|
|
key={lang.code}
|
|
onClick={() => handleLanguageChange(lang.code)}
|
|
className={`cursor-pointer hover:bg-slate-700 focus:bg-slate-700 ${
|
|
i18n.language === lang.code
|
|
? "text-amber-400 bg-slate-700/50"
|
|
: "text-slate-200"
|
|
}`}
|
|
>
|
|
<span className="mr-2 text-base">{lang.flag}</span>
|
|
<span className="flex-1">{lang.label}</span>
|
|
{i18n.language === lang.code && (
|
|
<span className="text-amber-400 text-xs">✓</span>
|
|
)}
|
|
</DropdownMenuItem>
|
|
))}
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
);
|
|
}
|
|
|
|
export default LanguageSwitcher;
|