132 lines
4.2 KiB
TypeScript
132 lines
4.2 KiB
TypeScript
'use client'
|
|
|
|
import Image from 'next/image'
|
|
import { Session } from 'next-auth'
|
|
import { signOut } from 'next-auth/react'
|
|
|
|
import { Button } from '@/components/ui/button'
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger
|
|
} from '@/components/ui/dropdown-menu'
|
|
import { sync } from 'framer-motion'
|
|
import service from '@/lib/http/service'
|
|
import React from 'react'
|
|
import toast from 'react-hot-toast'
|
|
import { useRouter } from 'next/navigation'
|
|
|
|
function getUserInitials(name: string) {
|
|
const [firstName, lastName] = name.split(' ')
|
|
return lastName ? `${firstName[0]}${lastName[0]}` : firstName.slice(0, firstName.length)
|
|
}
|
|
|
|
export interface UserData {
|
|
auth_token: string;
|
|
id: number;
|
|
login_ip: string;
|
|
login_time: number;
|
|
role: string;
|
|
user_name: string;
|
|
version: string;
|
|
image?: string;
|
|
}
|
|
|
|
export function UserMenu({ user }: { user: UserData }) {
|
|
|
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
|
|
const router = useRouter()
|
|
|
|
const getRandomColor = (name: string | undefined): string => {
|
|
if (!name) return "#999"; // 默认颜色
|
|
const colors = ["#FF5733", "#33FF57", "#3357FF", "#FF33A8", "#FFC300", "#FF5733", "#57FF33", "#A833FF"];
|
|
const index = name.charCodeAt(0) % colors.length; // 根据名字的首字母选择颜色
|
|
return colors[index];
|
|
};
|
|
|
|
|
|
return (
|
|
<div className="flex items-center justify-between">
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button className="p-0 m-0 w-12 h-12 bg-transparent border-none shadow-none outline-none hover:bg-transparent active:bg-transparent focus:ring-0 cursor-pointer">
|
|
{user?.image ? (
|
|
<Image
|
|
className="h-12 w-12 select-none rounded-full ring-1 ring-zinc-100/10 transition-opacity duration-300 hover:opacity-80"
|
|
src={`${user.image}&s=60`}
|
|
alt='User profile image'
|
|
width={32}
|
|
height={32}
|
|
/>
|
|
) : (
|
|
<div className="flex h-12 w-12 shrink-0 select-none items-center justify-center rounded-full bg-muted/50 text-xs font-medium uppercase text-muted-foreground">
|
|
style={{ backgroundColor: getRandomColor(user?.user_name) }}
|
|
{user?.user_name ? getUserInitials(user?.user_name.slice(0, 2)) : null}
|
|
</div>
|
|
)}
|
|
<span className="hidden">{user?.user_name && getUserInitials(user?.user_name)}</span>
|
|
{/* <span className="ml-2 hidden lg:flex">{user?.user_name && getUserInitials(user?.user_name)}</span> */}
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent sideOffset={8} align="start" className="w-[180px]">
|
|
|
|
{/* 新增 "Profile" 选项 */}
|
|
<DropdownMenuItem
|
|
onClick={() => {
|
|
router.push('/profile'); // 假设用户的个人资料页面是 "/profile"
|
|
}}
|
|
className="text-xs"
|
|
>
|
|
Profile
|
|
</DropdownMenuItem>
|
|
|
|
{/* 分隔线(可选) */}
|
|
<div className="border-t border-gray-200 my-1"></div>
|
|
|
|
{/* "Log Out" 选项 */}
|
|
<DropdownMenuItem
|
|
onClick={async () => {
|
|
console.log('logout')
|
|
if (isLoading) return
|
|
setIsLoading(true);
|
|
await service.post('/api/v1/customer/logout', {
|
|
}, {
|
|
headers: {
|
|
'Authorization': user.auth_token
|
|
}
|
|
}).then(function (result: any) {
|
|
setIsLoading(false);
|
|
console.log("result:", result)
|
|
|
|
if (result && result.header.code != 0) {
|
|
|
|
toast.error(result.header.message)
|
|
return
|
|
}
|
|
|
|
localStorage.removeItem("UserData");
|
|
|
|
window.location.href = `/`
|
|
|
|
}).catch((err) => {
|
|
setIsLoading(false);
|
|
localStorage.removeItem("UserData");
|
|
window.location.href = `/`
|
|
console.log(err);
|
|
});
|
|
}
|
|
|
|
}
|
|
className="text-xs"
|
|
>
|
|
Log Out
|
|
</DropdownMenuItem>
|
|
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
)
|
|
}
|