"use client" import { useEffect, useState } from "react" import { useParams, useRouter } from "next/navigation" import Link from "next/link" import { useFamily } from "@/context/family-context" import { SiteHeader } from "@/components/site-header" import { MemberForm } from "@/components/members/member-form" import { Button } from "@/components/ui/button" import { ArrowLeft, Edit, Trash, Share2, Printer, CircleUser, CircleUserRound, Images, BookOpen, UserPlus, Camera } from "lucide-react" import type { FamilyMember } from "@/types/family" import { db } from "@/lib/db" import { PhotoGallery } from "@/components/members/photo-gallery" import { StoryManager } from "@/components/members/story-manager" import { useDialog } from "@/components/ui/alert-dialog-custom" import { permissions } from "@/lib/permissions" import { MemberNameWithStatus } from "@/components/member-name-with-status" import { MemberVersionHistory } from "@/components/members/member-version-history" export default function MemberProfilePage() { const { id } = useParams() const { treeData, currentTree, getMember, updateMember, deleteMember, isLoading } = useFamily() const role = currentTree?.currentUserRole const { showConfirm } = useDialog() const router = useRouter() const [isEditing, setIsEditing] = useState(false) const [avatarBlobUrl, setAvatarBlobUrl] = useState(undefined) const [isUploadingAvatar, setIsUploadingAvatar] = useState(false) const member = getMember(id as string) const allMembers = Object.values(treeData.members) // 始祖专用边框样式 const founderBorderClass = member?.isFounder ? "border-2 border-amber-400 shadow-md" : "border border-border" // 计算年龄或享年 const calculateAge = () => { if (!member?.birthDate) return null const birthYear = new Date(member.birthDate).getFullYear() if (member.deathDate) { // 已故,计算享年 const deathYear = new Date(member.deathDate).getFullYear() return { age: deathYear - birthYear, type: 'deceased' } } else { // 在世,计算年龄 const currentYear = new Date().getFullYear() return { age: currentYear - birthYear, type: 'living' } } } const ageInfo = calculateAge() // Load avatar useEffect(() => { // 优先使用 avatarUrl(服务器存储) if (member?.avatarUrl) { setAvatarBlobUrl(member.avatarUrl) } // 兼容旧的 IndexedDB 存储 else if (member?.avatarImageId) { db.images.get(member.avatarImageId).then((image) => { if (image) { const url = URL.createObjectURL(image.blob) setAvatarBlobUrl(url) return () => URL.revokeObjectURL(url) } }) } else { setAvatarBlobUrl(undefined) } }, [member?.avatarUrl, member?.avatarImageId]) // 显示加载状态 if (isLoading) { return (

加载中...

) } // 成员未找到 if (!member) { return (

未找到该成员

) } const handleSave = (updatedMember: FamilyMember) => { updateMember(updatedMember.id, updatedMember) setIsEditing(false) } const handleDelete = async () => { const confirmed = await showConfirm("确定要删除这位成员吗?这将同时删除其关联关系。", "删除成员", "destructive") if (confirmed) { deleteMember(member.id) const params = new URLSearchParams(window.location.search) router.push(`/members?${params.toString()}`) } } const handleQuickAddChild = () => { // 跳转到新增成员页面,并预填父母信息 const params = new URLSearchParams(window.location.search) if (member.gender === 'MALE') { params.set('fatherId', member.id) } else { params.set('motherId', member.id) } params.set('generation', (member.generation + 1).toString()) router.push(`/members/new?${params.toString()}`) } const handleQuickAddSpouse = () => { // 跳转到新增成员页面,并预填配偶信息 const params = new URLSearchParams(window.location.search) params.set('spouseId', member.id) params.set('generation', member.generation.toString()) // 配偶性别与当前成员相反 params.set('gender', member.gender === 'MALE' ? 'FEMALE' : 'MALE') router.push(`/members/new?${params.toString()}`) } const handleQuickAddFather = () => { // 跳转到新增成员页面,并预填父亲信息 const params = new URLSearchParams(window.location.search) params.set('childId', member.id) params.set('generation', (member.generation - 1).toString()) params.set('gender', 'MALE') // 如果已有母亲,将母亲设置为配偶 if (member.motherId) { params.set('spouseId', member.motherId) } router.push(`/members/new?${params.toString()}`) } const handleAvatarUpload = async (event: React.ChangeEvent) => { const file = event.target.files?.[0] if (!file) return try { setIsUploadingAvatar(true) // 上传到服务器 const formData = new FormData() formData.append('file', file) const response = await fetch('/api/upload', { method: 'POST', body: formData, }) if (!response.ok) { const error = await response.json() throw new Error(error.error || '上传失败') } const { url } = await response.json() // 更新成员头像 URL await updateMember(member.id, { avatarUrl: url, }) // 显示新头像 setAvatarBlobUrl(url) } catch (error) { console.error('上传头像失败:', error) alert('上传头像失败: ' + (error instanceof Error ? error.message : '未知错误')) } finally { setIsUploadingAvatar(false) } } const handleQuickAddMother = () => { // 跳转到新增成员页面,并预填母亲信息 const params = new URLSearchParams(window.location.search) params.set('childId', member.id) params.set('generation', (member.generation - 1).toString()) params.set('gender', 'FEMALE') // 如果已有父亲,将父亲设置为配偶 if (member.fatherId) { params.set('spouseId', member.fatherId) } router.push(`/members/new?${params.toString()}`) } if (isEditing) { return (
{member.isFounder && (
👑

编辑家族始祖

此为家族树之始祖第一世传人。
请谨慎修改始祖信息,这将影响整个家族树的根基。

)}

{member.isFounder ? '编辑家族始祖' : `编辑成员: ${member.fullName}`}

{member.isFounder ? '修改始祖信息将影响整个家族树' : '更新成员信息'}

setIsEditing(false)} isFounder={member.isFounder} />
) } return (
{/* 始祖特殊提示框 */} {member.isFounder && (
👑

家族始祖

此为家族树之始祖第一世传人。
血脉由此而始,世系因此而传。

)} {/* Header Section */}
{avatarBlobUrl ? ( {member.fullName} ) : ( member.gender === 'FEMALE' ? ( ) : ( ) )}
{permissions.canUpdate(role) && ( )} {isUploadingAvatar && (
上传中...
)}

{member.isFounder && 👑}

{member.isFounder ? ( 始祖 · {member.generation}世 ) : ( {member.generation}世 )}
{member.isFounder && (

家族始祖 家族树的根基

)} {member.courtesyName && (

字:{member.courtesyName}

)} {member.artName && (

号:{member.artName}

)} {member.ancestralHome &&

籍贯:{member.ancestralHome}

}
{member.tags && member.tags.length > 0 && (
{member.tags.map((tag) => ( {tag} ))}
)}
{permissions.canCreate(role) && ( <> {!member.isFounder && !member.fatherId && ( )} {!member.isFounder && !member.motherId && ( )} )} {permissions.canUpdate(role) && ( )} {permissions.canDeleteMember(role) && ( )}
{/* Content Grid */}
{/* Left Column - Details and Biography */}
{/* 家族关系 */}

家族关系

父亲

{member.fatherId ? ( ) : member.spouseFatherName ? ( {member.spouseFatherName} ) : ( - )}

母亲

{member.motherId ? ( ) : member.spouseMotherName ? ( {member.spouseMotherName} ) : ( - )}

配偶

{member.spouseIds?.length > 0 ? ( member.spouseIds.map((spouseId) => ( )) ) : ( 无记录 )}

子女

{member.childrenIds?.length > 0 ? ( member.childrenIds.map((childId) => ( )) ) : ( 无记录 )}
{/* 详细信息 */}

详细信息

出生日期
{member.birthDate || "-"} {member.birthDate && member.isLunarDate && ( 农历 )}
{ageInfo && (
{ageInfo.type === 'deceased' ? '享年' : '年龄'}
{ageInfo.age} 岁
)} {member.deathDate && ( <>
逝世日期
{member.deathDate} {member.isLunarDate && ( 农历 )}
谥号
{member.posthumousName || "-"}
墓地
{member.burialPlace || "-"}
)} {member.generationName && (
字辈
{member.generationName}
)}
{/* 联系方式 */} {(member.phone || member.telephone || member.email || member.address) && (

联系方式

{member.phone && ( )} {member.telephone && ( )} {member.email && ( )} {member.address && (
现居地址
{member.address}
)}
)}

生平事迹

{member.bio ? (

{member.bio}

) : (

生平待书

)}
{/* Photo Gallery */} {member.photoIds && member.photoIds.length > 0 && (

照片墙

updateMember(member.id, { photoIds })} readonly={false} />
)} {/* Family Stories */} {member.stories && member.stories.length > 0 && (

家族故事

updateMember(member.id, { stories })} readonly={false} />
)}
{/* Right Column - Version History */}

版本历史

) }