feat(auth): add user button component

This commit is contained in:
ngc2207 2025-02-01 10:04:01 +08:00
parent 32f52945de
commit 4367d147f4

View File

@ -0,0 +1,74 @@
"use client";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useLogout } from "../api/use-logout";
import { Loader, LogOut } from "lucide-react";
import { useCurrent } from "../api/use-current";
import { Separator } from "@/components/ui/separator";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
export const UserButton = () => {
const { mutate: logout } = useLogout();
const { data: user, isLoading } = useCurrent();
if (isLoading) {
return (
<div className="size-10 rounded-full flex items-center justify-center border">
<Loader className="size-4 animate-spin text-muted-foreground" />
</div>
);
}
if (!user) {
return null;
}
const { name, email } = user;
const avatarFallback = name
? name.charAt(0).toUpperCase()
: email.charAt(0).toUpperCase() ?? "U";
return (
<DropdownMenu modal={false}>
<DropdownMenuTrigger className="outline-none relative">
<Avatar className="size-10 hover:opacity-75 transition border">
<AvatarFallback className="font-medium flex items-center justify-center">
{avatarFallback}
</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent
align="end"
side="bottom"
className="w-60"
sideOffset={10}
>
<div className="flex flex-col items-center justify-center gap-2 px-2.5 py-4">
<Avatar className="size-[52px] hover:opacity-75 transition border">
<AvatarFallback className="text-xl font-medium flex items-center justify-center">
{avatarFallback}
</AvatarFallback>
</Avatar>
<div className="flex flex-col items-center justify-center">
<p className="text-sm font-medium">{name || "User"}</p>
<p className="text-xs">{email}</p>
</div>
</div>
<Separator className="mb-1" />
<DropdownMenuItem
onClick={() => logout()}
className="h-10 flex items-center justify-center font-medium cursor-pointer"
>
<LogOut className="size-4 mr-2" />
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
};