Files
qna-viewer-react/viewer/src/components/UserProfileBox.tsx
2025-08-04 21:07:30 +09:00

97 lines
2.7 KiB
TypeScript

// src/components/UserProfileBox.tsx
import { useState, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { useDescope, useSession, useUser } from "@descope/react-sdk";
import { User } from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "./ui/button";
import { LoginModal } from "./LoginModal";
export function UserProfileBox() {
const { isAuthenticated, isSessionLoading } = useSession();
const { user, isUserLoading } = useUser();
const sdk = useDescope();
const navigate = useNavigate();
const [isLoginModalOpen, setIsLoginModalOpen] = useState(false);
const handleLogout = useCallback(() => {
sdk.logout();
navigate("/");
}, [sdk, navigate]);
const handleLoginSuccess = () => {
setIsLoginModalOpen(false);
};
if (isSessionLoading || isUserLoading) {
return (
<div className="h-8 w-8 rounded-full bg-muted flex items-center justify-center animate-pulse" />
);
}
return (
<>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="relative h-8 w-8 rounded-full">
<Avatar className="h-8 w-8">
{isAuthenticated && user?.picture && (
<AvatarImage src={user.picture} alt={user.name ?? ""} />
)}
<AvatarFallback>
{isAuthenticated && user?.name ? (
user.name
.split(" ")
.map((chunk) => chunk[0])
.join("")
.toUpperCase()
) : (
<User className="h-5 w-5" />
)}
</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="end" forceMount>
{isAuthenticated ? (
<>
<DropdownMenuLabel className="font-normal">
<div className="flex flex-col space-y-1">
<p className="text-sm font-medium leading-none">
{user?.name}
</p>
<p className="text-xs leading-none text-muted-foreground">
{user?.email}
</p>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => navigate("/profile")}>
</DropdownMenuItem>
<DropdownMenuItem onClick={handleLogout}></DropdownMenuItem>
</>
) : (
<DropdownMenuItem onClick={() => setIsLoginModalOpen(true)}>
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
<LoginModal
isOpen={isLoginModalOpen}
onOpenChange={setIsLoginModalOpen}
onSuccess={handleLoginSuccess}
/>
</>
);
}