0.3.1.4
This commit is contained in:
@@ -179,28 +179,92 @@ function PersonCard({
|
||||
// 调试日志
|
||||
console.log('PersonCard render:', member.fullName, { canEdit, hasAddOptions, relationMode })
|
||||
|
||||
// 庄严正式的中国风配色
|
||||
const isDead = !!member.deathDate
|
||||
const isMale = member.gender === 'MALE'
|
||||
|
||||
const cardContent = (
|
||||
<div
|
||||
className={cn(
|
||||
"family-node-card relative flex flex-col items-center gap-2 p-3 rounded-lg transition-all cursor-pointer hover:scale-105 shadow-sm w-32",
|
||||
"family-node-card relative flex flex-col items-center p-4 transition-all cursor-pointer hover:scale-[1.02] w-[140px]",
|
||||
// 庄严的边框样式 - 双层边框效果
|
||||
"border-[3px] rounded-none",
|
||||
"shadow-lg hover:shadow-xl",
|
||||
// 根据状态设置样式
|
||||
isSelected
|
||||
? "border-4 border-blue-500 bg-blue-50 dark:bg-blue-900/20 ring-4 ring-blue-200 dark:ring-blue-800"
|
||||
? "border-blue-600 bg-blue-50 dark:bg-blue-950/50 ring-2 ring-blue-400"
|
||||
: isHighlighted
|
||||
? "border-4 border-yellow-400 bg-yellow-50 dark:bg-yellow-900/20 ring-4 ring-yellow-200 dark:ring-yellow-800 animate-pulse"
|
||||
? "border-yellow-600 bg-yellow-50/90 dark:bg-yellow-950/50 ring-2 ring-yellow-400 animate-pulse"
|
||||
: isRoot
|
||||
? "border-2 border-primary bg-primary/5"
|
||||
? "border-red-800 bg-gradient-to-b from-red-50 via-amber-50/30 to-red-50 dark:from-red-950/40 dark:to-amber-950/20 shadow-xl"
|
||||
: isSpouse
|
||||
? "border-2 border-dashed border-border/60 bg-muted/30"
|
||||
: "border-2 border-border bg-card",
|
||||
relationMode && "hover:border-blue-400 hover:shadow-lg"
|
||||
? "border-dashed border-stone-500 bg-stone-50/50 dark:bg-stone-900/30"
|
||||
: isDead
|
||||
? "border-stone-500 bg-gradient-to-b from-stone-100 to-stone-50 dark:from-stone-900/50 dark:to-stone-800/30"
|
||||
: isMale
|
||||
? "border-amber-800 bg-gradient-to-b from-amber-50 via-orange-50/30 to-amber-50/80 dark:from-amber-950/40 dark:to-orange-950/20"
|
||||
: "border-rose-800 bg-gradient-to-b from-rose-50 via-pink-50/30 to-rose-50/80 dark:from-rose-950/40 dark:to-pink-950/20",
|
||||
relationMode && "hover:border-blue-600 hover:shadow-xl"
|
||||
)}
|
||||
onClick={() => onSelect?.(member)}
|
||||
>
|
||||
<div className="absolute -top-3 bg-background border border-border px-2 py-0.5 rounded-full text-[10px] text-muted-foreground font-mono">
|
||||
{/* 内边框装饰 */}
|
||||
<div className={cn(
|
||||
"absolute inset-[3px] border pointer-events-none",
|
||||
isSelected ? "border-blue-400/50"
|
||||
: isHighlighted ? "border-yellow-500/50"
|
||||
: isRoot ? "border-red-600/40"
|
||||
: isSpouse ? "border-stone-400/30"
|
||||
: isDead ? "border-stone-400/40"
|
||||
: isMale ? "border-amber-600/40"
|
||||
: "border-rose-600/40"
|
||||
)} />
|
||||
|
||||
{/* 四角装饰 - 更精致的角花 */}
|
||||
<div className={cn(
|
||||
"absolute top-0 left-0 w-4 h-4 border-t-[3px] border-l-[3px]",
|
||||
isSelected ? "border-blue-600" : isHighlighted ? "border-yellow-600" : isRoot ? "border-red-800" : isSpouse ? "border-stone-500" : isDead ? "border-stone-500" : isMale ? "border-amber-800" : "border-rose-800"
|
||||
)} />
|
||||
<div className={cn(
|
||||
"absolute top-0 right-0 w-4 h-4 border-t-[3px] border-r-[3px]",
|
||||
isSelected ? "border-blue-600" : isHighlighted ? "border-yellow-600" : isRoot ? "border-red-800" : isSpouse ? "border-stone-500" : isDead ? "border-stone-500" : isMale ? "border-amber-800" : "border-rose-800"
|
||||
)} />
|
||||
<div className={cn(
|
||||
"absolute bottom-0 left-0 w-4 h-4 border-b-[3px] border-l-[3px]",
|
||||
isSelected ? "border-blue-600" : isHighlighted ? "border-yellow-600" : isRoot ? "border-red-800" : isSpouse ? "border-stone-500" : isDead ? "border-stone-500" : isMale ? "border-amber-800" : "border-rose-800"
|
||||
)} />
|
||||
<div className={cn(
|
||||
"absolute bottom-0 right-0 w-4 h-4 border-b-[3px] border-r-[3px]",
|
||||
isSelected ? "border-blue-600" : isHighlighted ? "border-yellow-600" : isRoot ? "border-red-800" : isSpouse ? "border-stone-500" : isDead ? "border-stone-500" : isMale ? "border-amber-800" : "border-rose-800"
|
||||
)} />
|
||||
|
||||
{/* 世代标签 - 庄严印章风格 */}
|
||||
<div className={cn(
|
||||
"absolute -top-3 px-3 py-1 text-[11px] font-serif font-bold tracking-wider",
|
||||
"border-2 shadow-md",
|
||||
isRoot
|
||||
? "bg-red-800 text-amber-100 border-red-900"
|
||||
: isDead
|
||||
? "bg-stone-600 text-stone-100 border-stone-700"
|
||||
: isMale
|
||||
? "bg-amber-800 text-amber-100 border-amber-900"
|
||||
: "bg-rose-800 text-rose-100 border-rose-900"
|
||||
)}>
|
||||
{member.generation}世
|
||||
</div>
|
||||
|
||||
<div className="h-12 w-12 rounded-full bg-muted flex items-center justify-center text-muted-foreground overflow-hidden border border-border/50">
|
||||
{/* 头像 - 方形带庄严边框 */}
|
||||
<div className={cn(
|
||||
"h-14 w-14 flex items-center justify-center overflow-hidden mt-2",
|
||||
"border-2 shadow-inner bg-white/80 dark:bg-black/20",
|
||||
isRoot
|
||||
? "border-red-700"
|
||||
: isDead
|
||||
? "border-stone-400"
|
||||
: isMale
|
||||
? "border-amber-700"
|
||||
: "border-rose-700"
|
||||
)}>
|
||||
{avatarBlobUrl ? (
|
||||
<img
|
||||
src={avatarBlobUrl}
|
||||
@@ -209,38 +273,48 @@ function PersonCard({
|
||||
/>
|
||||
) : (
|
||||
member.gender === 'FEMALE' ? (
|
||||
<CircleUserRound className="h-8 w-8 text-pink-400" />
|
||||
<CircleUserRound className={cn("h-9 w-9", isDead ? "text-stone-400" : "text-rose-700")} />
|
||||
) : (
|
||||
<CircleUser className="h-8 w-8 text-blue-400" />
|
||||
<CircleUser className={cn("h-9 w-9", isDead ? "text-stone-400" : "text-amber-700")} />
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="text-center w-full">
|
||||
<div className="font-serif font-bold text-foreground leading-tight flex items-center justify-center gap-1">
|
||||
{/* 姓名和信息 */}
|
||||
<div className="text-center w-full mt-2 space-y-0.5">
|
||||
<div className={cn(
|
||||
"font-serif font-bold leading-tight flex items-center justify-center gap-1 text-base tracking-wide",
|
||||
isDead ? "text-stone-500" : "text-stone-900 dark:text-stone-100"
|
||||
)}>
|
||||
<MemberNameWithStatus
|
||||
name={`${member.surname}${member.givenName}`}
|
||||
isDead={!!member.deathDate}
|
||||
isDead={isDead}
|
||||
/>
|
||||
</div>
|
||||
{member.courtesyName && (
|
||||
<div className="text-[10px] text-muted-foreground mt-0.5">字 {member.courtesyName}</div>
|
||||
<div className={cn(
|
||||
"text-[11px] font-serif tracking-wide",
|
||||
isDead ? "text-stone-400" : "text-stone-600 dark:text-stone-400"
|
||||
)}>
|
||||
字 {member.courtesyName}
|
||||
</div>
|
||||
)}
|
||||
{lifeSpan && (
|
||||
<div className="text-[9px] text-muted-foreground/70 mt-1 font-mono">
|
||||
<div className={cn(
|
||||
"text-[10px] font-mono tracking-wider mt-1",
|
||||
isDead ? "text-stone-400" : "text-stone-500"
|
||||
)}>
|
||||
{lifeSpan}
|
||||
</div>
|
||||
)}
|
||||
{ageText && (
|
||||
<div className="text-[9px] text-muted-foreground/60 font-mono">
|
||||
<div className={cn(
|
||||
"text-[10px] font-serif",
|
||||
isDead ? "text-stone-400" : "text-stone-500"
|
||||
)}>
|
||||
{ageText}
|
||||
</div>
|
||||
)}
|
||||
{member.phone && (
|
||||
<div className="text-[9px] text-muted-foreground/60 font-mono truncate">
|
||||
📱 {member.phone}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user