"use client" import * as React from "react" import { useTransition } from "react" import { useLocale, useTranslations } from "next-intl" import { Check, Globe } from "lucide-react" import { toast } from "sonner" import { Button } from "@/shared/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/shared/components/ui/dropdown-menu" import { LOCALES, type Locale } from "@/shared/i18n/locale" import { setLocaleAction } from "@/i18n/actions" import { cn } from "@/shared/lib/utils" /** * 语言切换组件(v3 i18n 体系)。 * * 设计: * - 不使用 URL 路由段,通过 cookie 持久化用户偏好 * - 切换时调用 setLocaleAction 写入 cookie + revalidatePath * - 用 useTransition 保证切换过程不阻塞 UI */ export function LocaleSwitcher({ compact = false }: { compact?: boolean }) { const locale = useLocale() const t = useTranslations("common.locale") const [isPending, startTransition] = useTransition() function handleSelect(next: Locale) { if (next === locale) return startTransition(async () => { const result = await setLocaleAction(next) if (result.success) { toast.success(t("switch")) } else { toast.error(t("switch")) } }) } return ( {LOCALES.map((l) => ( handleSelect(l)} className="flex items-center justify-between gap-2" > {t(l)} {l === locale ? : null} ))} ) }