This commit is contained in:
freedakgmail
2025-11-23 03:07:39 +08:00
parent 626d7dddde
commit e92884ae53
679 changed files with 208175 additions and 1183474 deletions
+53 -11
View File
@@ -9,35 +9,72 @@ import { ScrollArea } from "@/components/ui/scroll-area"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { UserPlus, Network, Map, Calendar, Users, ArrowRight, Clock, Search, BookOpen, BarChart3 } from "lucide-react"
import { useFamily } from "@/context/family-context"
import { useMemo, useState, useEffect } from "react"
import { useMemo, useState, useEffect, useRef } from "react"
import { StatisticsCharts } from "@/components/dashboard/statistics-charts"
import { getActivityLogs } from "@/lib/activity-logger"
import type { ActivityLog } from "@/lib/db"
import { format } from "date-fns"
import { useSession } from "next-auth/react"
import { useSearchParams } from "next/navigation"
interface ActivityLog {
id: string
action: string
entityType: string
entityId?: string | null
entityName?: string | null
timestamp: string
user?: {
name?: string | null
email?: string | null
}
}
export default function DashboardPage() {
const { treeData } = useFamily()
const { treeData, currentTree, isLoading } = useFamily()
const { data: session } = useSession()
const [recentActivities, setRecentActivities] = useState<ActivityLog[]>([])
// 调试日志
console.log('Dashboard - treeData:', treeData, 'currentTree:', currentTree?.name, 'isLoading:', isLoading)
// 加载最近的操作日志
useEffect(() => {
getActivityLogs(10).then(setRecentActivities)
}, [treeData])
if (currentTree?.id && session?.user?.id) {
fetch(`/api/trees/${currentTree.id}/activity-logs?limit=10`)
.then(res => {
if (!res.ok) {
throw new Error('获取活动日志失败')
}
return res.json()
})
.then(data => {
if (data.logs) {
setRecentActivities(data.logs)
}
})
.catch(err => {
console.error('获取活动日志失败:', err)
setRecentActivities([])
})
} else {
setRecentActivities([])
}
}, [currentTree?.id, session?.user?.id])
// 计算统计数据
const stats = useMemo(() => {
const members = Object.values(treeData.members)
const totalMembers = members.length
// 计算最大代数
const maxGeneration = Math.max(...members.map(m => m.generation || 0))
// 计算最大代数(处理空数组的情况)
const generations = members.map(m => m.generation || 0)
const maxGeneration = generations.length > 0 ? Math.max(...generations) : 0
// 计算最早出生年份
const birthYears = members
.map(m => m.birthDate ? new Date(m.birthDate).getFullYear() : null)
.filter(y => y !== null) as number[]
const earliestYear = birthYears.length > 0 ? Math.min(...birthYears) : new Date().getFullYear()
const yearsSpan = new Date().getFullYear() - earliestYear
const yearsSpan = birthYears.length > 0 ? new Date().getFullYear() - earliestYear : 0
return {
totalMembers,
@@ -106,8 +143,13 @@ export default function DashboardPage() {
<main className="flex-1 container mx-auto py-8 px-4 md:px-6">
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 mb-8">
<div>
<h1 className="text-3xl font-serif font-bold text-foreground"></h1>
<p className="text-muted-foreground mt-1">西 · 24 </p>
<h1 className="text-3xl font-serif font-bold text-foreground">
{currentTree?.name || '家族族谱'}
</h1>
<p className="text-muted-foreground mt-1">
{currentTree?.description || '记录家族历史,传承家族文化'}
{stats.maxGeneration > 0 && ` · 第 ${stats.maxGeneration} 代传人`}
</p>
</div>
<div className="flex gap-2">
<Link href="/tree">