"use client" import Link from "next/link" import { BookOpen, Search, Bell, Settings, LogOut, User, ChevronDown, Plus } from "lucide-react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { useFamily } from "@/context/family-context" import { useState, useRef, useEffect, useCallback } from "react" import { useRouter } from "next/navigation" import { useSession, signOut } from "next-auth/react" interface FamilyTree { id: string name: string description: string | null } export function SiteHeader() { const { searchMembers, searchResults } = useFamily() const { data: session, status } = useSession() const [searchQuery, setSearchQuery] = useState("") const [showResults, setShowResults] = useState(false) const [familyTrees, setFamilyTrees] = useState([]) const [currentTree, setCurrentTree] = useState(null) const searchRef = useRef(null) const router = useRouter() const handleSignOut = async () => { await signOut({ callbackUrl: "/auth/signin" }) } // 获取用户名首字母作为头像 const getUserInitial = () => { if (session?.user?.name) { return session.user.name.charAt(0).toUpperCase() } if (session?.user?.email) { return session.user.email.charAt(0).toUpperCase() } return "U" } // 获取家族树列表 const loadFamilyTrees = useCallback(() => { if (session?.user?.id) { fetch('/api/trees') .then(res => res.json()) .then(data => { if (data.trees) { setFamilyTrees(data.trees) // 如果 URL 中有 treeId,使用该树,否则使用第一个 const urlParams = new URLSearchParams(window.location.search) const treeId = urlParams.get('treeId') if (treeId) { const tree = data.trees.find((t: FamilyTree) => t.id === treeId) if (tree) { setCurrentTree(tree) } else if (data.trees.length > 0) { setCurrentTree(data.trees[0]) } } else if (data.trees.length > 0) { setCurrentTree(data.trees[0]) } } }) .catch(err => console.error('获取家族树失败:', err)) } }, [session?.user?.id]) useEffect(() => { loadFamilyTrees() }, [loadFamilyTrees]) // 监听路由变化,刷新家族树列表 useEffect(() => { const handleRouteChange = () => { loadFamilyTrees() } window.addEventListener('focus', handleRouteChange) return () => window.removeEventListener('focus', handleRouteChange) }, [loadFamilyTrees]) // 点击外部关闭搜索结果 useEffect(() => { function handleClickOutside(event: MouseEvent) { if (searchRef.current && !searchRef.current.contains(event.target as Node)) { setShowResults(false) } } document.addEventListener("mousedown", handleClickOutside) return () => document.removeEventListener("mousedown", handleClickOutside) }, []) const handleSearch = (query: string) => { setSearchQuery(query) searchMembers(query) setShowResults(query.length > 0) } const handleSelectMember = (memberId: string) => { router.push(`/members/${memberId}`) setSearchQuery("") setShowResults(false) } return (
华夏谱 {/* 家族树选择器 */} {session && familyTrees.length > 0 && ( 我的家族树 {familyTrees.map((tree) => ( { setCurrentTree(tree) router.push(`/?treeId=${tree.id}`) }} className="cursor-pointer" > {tree.name} {currentTree?.id === tree.id && ( )} ))} router.push('/trees/new')} className="cursor-pointer text-primary" > 创建新家族树 )}
handleSearch(e.target.value)} className="h-9 w-64 rounded-full bg-muted pl-9 text-sm focus-visible:ring-primary" /> {/* 搜索结果下拉框 */} {showResults && searchResults.length > 0 && (
{searchResults.map((member) => ( ))}
)} {/* 无结果提示 */} {showResults && searchQuery && searchResults.length === 0 && (
未找到匹配的成员
)}
{status === "loading" ? ( ... ) : session ? (

{session.user?.name || "用户"}

{session.user?.email}

个人设置 退出登录
) : ( )}
) }