This commit is contained in:
freedakgmail
2025-11-24 14:02:34 +08:00
parent b7a8c9ee6e
commit 3d075c6076
941 changed files with 25613 additions and 27641 deletions
+50 -12
View File
@@ -8,6 +8,7 @@ import { Clock, Map as MapIcon, ArrowRight, Calendar } from "lucide-react"
import dynamic from 'next/dynamic'
import { useMemo, useEffect, useState } from 'react'
import * as echarts from 'echarts'
import { MemberNameWithStatus } from "@/components/member-name-with-status"
const ReactECharts = dynamic(() => import('echarts-for-react'), { ssr: false })
@@ -184,9 +185,10 @@ const geoCoordMap: Record<string, [number, number]> = {
}
export default function TimelinePage() {
const { treeData, getMember, isLoading } = useFamily()
const { treeData, currentTree, getMember, isLoading } = useFamily()
const members = Object.values(treeData.members)
const [mapLoaded, setMapLoaded] = useState(false)
const treeId = currentTree?.id
// 注册中国地图 - 从外部文件加载完整数据(必须在条件渲染之前)
useEffect(() => {
@@ -505,17 +507,17 @@ export default function TimelinePage() {
<SiteHeader />
<main className="container mx-auto py-8 px-4 md:px-6 flex-1">
<div className="mb-8">
<h1 className="text-3xl font-serif font-bold mb-2"> (History)</h1>
<h1 className="text-3xl font-serif font-bold mb-2"></h1>
<p className="text-muted-foreground"></p>
</div>
<Tabs defaultValue="timeline" className="w-full">
<TabsList className="mb-6 w-full md:w-auto">
<TabsTrigger value="timeline" className="flex items-center gap-2">
<Clock className="h-4 w-4" /> (Chronology)
<Clock className="h-4 w-4" />
</TabsTrigger>
<TabsTrigger value="migration" className="flex items-center gap-2">
<MapIcon className="h-4 w-4" /> (Migration)
<MapIcon className="h-4 w-4" />
</TabsTrigger>
</TabsList>
@@ -545,7 +547,14 @@ export default function TimelinePage() {
>
{event.type === "birth" ? "诞生" : "逝世"}
</span>
<span className="font-serif font-bold">{event.member.fullName}</span>
<span className="font-serif font-bold">
<MemberNameWithStatus
name={event.member.fullName}
isDead={!!event.member.deathDate}
memberId={event.member.id}
treeId={treeId}
/>
</span>
<span className={`text-xs px-1.5 py-0.5 rounded ${event.member.gender === "MALE" ? "bg-blue-100 text-blue-700" : "bg-pink-100 text-pink-700"}`}>
{event.member.gender === "MALE" ? "男" : "女"}
</span>
@@ -554,19 +563,34 @@ export default function TimelinePage() {
{/* 父母信息 */}
{event.member.fatherId && (
<span className="text-xs px-1.5 py-0.5 rounded bg-orange-50 text-orange-700 border border-orange-200">
:{getMember(event.member.fatherId)?.fullName || "未知"}
:<MemberNameWithStatus
name={getMember(event.member.fatherId)?.fullName || "未知"}
isDead={!!getMember(event.member.fatherId)?.deathDate}
memberId={event.member.fatherId}
treeId={treeId}
/>
</span>
)}
{event.member.motherId && (
<span className="text-xs px-1.5 py-0.5 rounded bg-orange-50 text-orange-700 border border-orange-200">
:{getMember(event.member.motherId)?.fullName || "未知"}
:<MemberNameWithStatus
name={getMember(event.member.motherId)?.fullName || "未知"}
isDead={!!getMember(event.member.motherId)?.deathDate}
memberId={event.member.motherId}
treeId={treeId}
/>
</span>
)}
{/* 配偶信息 */}
{event.member.spouseIds && event.member.spouseIds.length > 0 && (
<span className="text-xs px-1.5 py-0.5 rounded bg-purple-50 text-purple-700 border border-purple-200">
:{getMember(event.member.spouseIds[0])?.fullName || "未知"}
:<MemberNameWithStatus
name={getMember(event.member.spouseIds[0])?.fullName || "未知"}
isDead={!!getMember(event.member.spouseIds[0])?.deathDate}
memberId={event.member.spouseIds[0]}
treeId={treeId}
/>
</span>
)}
@@ -618,7 +642,7 @@ export default function TimelinePage() {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
<Card>
<CardHeader>
<CardTitle className="font-serif"> (Records)</CardTitle>
<CardTitle className="font-serif"></CardTitle>
</CardHeader>
<CardContent>
<ScrollArea className="h-[600px] pr-4">
@@ -635,13 +659,27 @@ export default function TimelinePage() {
<div className="flex-1 text-center p-2 bg-background rounded border border-border/50">
<div className="text-xs text-muted-foreground mb-1"></div>
<div className="font-bold">{mig.from}</div>
<div className="text-xs text-muted-foreground mt-1">{mig.father.fullName}</div>
<div className="text-xs text-muted-foreground mt-1">
<MemberNameWithStatus
name={mig.father.fullName}
isDead={!!mig.father.deathDate}
memberId={mig.father.id}
treeId={treeId}
/>
</div>
</div>
<ArrowRight className="text-muted-foreground" />
<div className="flex-1 text-center p-2 bg-background rounded border border-border/50">
<div className="text-xs text-muted-foreground mb-1"></div>
<div className="font-bold text-primary">{mig.to}</div>
<div className="text-xs text-muted-foreground mt-1">{mig.person.fullName}</div>
<div className="text-xs text-muted-foreground mt-1">
<MemberNameWithStatus
name={mig.person.fullName}
isDead={!!mig.person.deathDate}
memberId={mig.person.id}
treeId={treeId}
/>
</div>
</div>
</div>
</div>
@@ -658,7 +696,7 @@ export default function TimelinePage() {
<Card className="bg-gradient-to-br from-primary/5 via-background to-secondary/5 border-primary/20">
<CardHeader>
<CardTitle className="font-serif"> (Migration Flow)</CardTitle>
<CardTitle className="font-serif"></CardTitle>
</CardHeader>
<CardContent>
<div className="relative h-[600px] overflow-hidden rounded-lg bg-background/50 backdrop-blur border border-border/50">