"use client" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet" import { getCurrentUserForLogin, logout as logoutRequest, switchCurrentRole } from "@/lib/api" import { toApiError } from "@/lib/errors" import { useMyShop } from "@/lib/hooks/use-my-shop" import { notifyInfo } from "@/lib/toast" import type { UserRole } from "@/lib/types" import { cn } from "@/lib/utils" import { useAuthStore } from "@/store/auth" import { useNotificationStore } from "@/store/notifications" import { Bell, Gamepad2, LogOut, Menu, MessageSquare, Settings, ShoppingBag, User, Wallet, } from "lucide-react" import Link from "next/link" import { usePathname, useRouter } from "next/navigation" import { useEffect, useState } from "react" import { canAccessDashboard } from "@/components/role-guard" const roleLabels = { consumer: "客户", player: "打手", owner: "店主", admin: "管理员", } satisfies Record export function Header() { const [mobileOpen, setMobileOpen] = useState(false) const pathname = usePathname() const router = useRouter() const { isAuthenticated, currentRole, verifiedRoles, login, logout: clearAuth, user, } = useAuthStore() const canOpenDashboard = currentRole === "player" || currentRole === "owner" const { shop: ownerShop } = useMyShop(isAuthenticated && currentRole === "owner") const fetchNotifications = useNotificationStore((state) => state.fetchNotifications) useEffect(() => { if (!isAuthenticated) return void fetchNotifications() }, [fetchNotifications, isAuthenticated]) const navLinks = currentRole === "consumer" ? [ { href: "/", label: "发现" }, { href: "/community", label: "社区" }, { href: "/orders", label: "订单" }, { href: "/chat", label: "消息" }, ] : [ { href: "/", label: "发现" }, { href: "/community", label: "社区" }, { href: "/orders", label: "订单" }, { href: "/chat", label: "消息" }, ...(canOpenDashboard ? [{ href: "/dashboard", label: "管理后台" }] : []), ] const availableRoles = (Object.entries(roleLabels) as [UserRole, string][]).filter(([role]) => verifiedRoles.includes(role), ) const handleRoleSwitch = (role: UserRole) => { if (role === currentRole) { setMobileOpen(false) return } void (async () => { try { await switchCurrentRole(role) const updated = await getCurrentUserForLogin() login(updated, updated.verifiedRoles ?? [updated.role]) if (pathname.startsWith("/dashboard") && !canAccessDashboard(role, pathname)) { router.push(role === "consumer" ? "/" : "/dashboard") } } catch (error) { notifyInfo(toApiError(error).msg) } finally { setMobileOpen(false) } })() } const handleLogout = () => { void (async () => { try { await logoutRequest() } catch (error) { notifyInfo(toApiError(error).msg) } finally { clearAuth() useNotificationStore.getState().invalidate() setMobileOpen(false) router.push("/") } })() } const unreadCount = useNotificationStore( (state) => state.notifications.filter((notification) => !notification.read).length, ) const profileHref = currentRole === "player" ? user ? `/player/${user.id}` : "/settings" : currentRole === "owner" ? ownerShop ? `/shop/${ownerShop.id}` : "/dashboard/shop" : user ? `/user/${user.id}` : "/settings" return (
聚玩
{isAuthenticated ? ( <> 切换身份 {availableRoles.map(([role, label]) => ( handleRoleSwitch(role)} className={cn( currentRole === role && "bg-accent text-accent-foreground rounded-md", )} > {label} ))} {user?.nickname ?? "未登录"} 个人主页 我的订单 消息 钱包 {canOpenDashboard && ( 管理后台 )} 设置 退出登录 ) : (
)} 聚玩
{isAuthenticated && (
{user?.nickname?.[0] ?? "?"}

{user?.nickname ?? "未登录"}

{roleLabels[currentRole]}

)} {isAuthenticated && (

切换身份

{availableRoles.map(([role, label]) => ( ))}
)} {!isAuthenticated && (
)}
) }