mirror of
https://gitlab.massbug.com/massbug/judge4c.git
synced 2025-07-04 09:51:15 +00:00
feat(auth): add user button component
This commit is contained in:
parent
32f52945de
commit
4367d147f4
74
src/features/auth/components/user-button.tsx
Normal file
74
src/features/auth/components/user-button.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user