/**
* 顶栏用户菜单:接 `auth.me` / `auth.logout`,未登录显示登录/注册入口。
*/
import type { Locale } from "@app/i18n";
import { t } from "@app/i18n";
import {
Avatar,
AvatarFallback,
AvatarImage,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
toast,
} from "@app/ui";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { createTRPCReactClient, trpc } from "../lib/trpc";
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false } },
});
const trpcClient = createTRPCReactClient();
export interface UserMenuProps {
locale?: Locale | undefined;
name?: string | undefined;
email?: string | undefined;
avatarUrl?: string | undefined;
}
function home(locale: Locale): string {
return locale === "zh-CN" ? "/zh-CN" : "/en";
}
export default function UserMenu({ locale = "zh-CN", avatarUrl }: UserMenuProps) {
return (
);
}
function UserMenuInner({ locale, avatarUrl }: { locale: Locale; avatarUrl?: string | undefined }) {
const me = trpc.auth.me.useQuery();
const logout = trpc.auth.logout.useMutation({
onSuccess: () => {
toast.success(t(locale, "auth.msg.logoutOk"));
queryClient.clear();
window.location.reload();
},
onError: (err) => toast.error(err.message || t(locale, "auth.err.generic")),
});
const base = home(locale);
const user = me.data?.user ?? null;
if (me.isPending) {
return …;
}
if (!user) {
return (
{t(locale, "auth.menu.login")}
{t(locale, "auth.menu.register")}
);
}
const name = user.name;
const initials = name.slice(0, 1);
return (
{name}
{user.email}
{t(locale, "auth.menu.dashboard")}
{t(locale, "auth.menu.settings")}
{
e.preventDefault();
logout.mutate();
}}
disabled={logout.isPending}
>
{t(locale, "auth.menu.logout")}
);
}