This commit is contained in:
freedakgmail
2025-11-23 19:38:51 +08:00
parent e44dd0bd95
commit 3b0d8255f6
649 changed files with 656698 additions and 4133 deletions
+150 -48
View File
@@ -2,6 +2,7 @@
import type React from "react"
import Link from "next/link"
import Image from "next/image"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { SiteHeader } from "@/components/site-header"
@@ -159,6 +160,122 @@ export default function DashboardPage() {
// 按日期排序
return anniversaries.sort((a, b) => a.day - b.day).slice(0, 5)
}, [treeData])
// 计算家族迁徙记录
const locationGroups = useMemo(() => {
const members = Object.values(treeData.members)
const groups: Record<string, any[]> = {}
members.forEach(member => {
if (member.ancestralHome) {
if (!groups[member.ancestralHome]) {
groups[member.ancestralHome] = []
}
groups[member.ancestralHome].push(member)
}
})
return Object.entries(groups).sort((a, b) => b[1].length - a[1].length)
}, [treeData])
// 如果用户没有家族树,显示欢迎页面
if (!isLoading && !currentTree) {
return (
<div className="flex min-h-screen flex-col bg-background font-sans">
<SiteHeader />
<main className="flex-1 flex items-center justify-center px-4 md:px-6 relative">
{/* 背景装饰图片 */}
<div className="absolute inset-0 pointer-events-none overflow-hidden">
{/* 建筑图片 - 左下 */}
<div className="absolute left-24 top-[60%] -translate-y-1/2 w-[30rem] h-[30rem] opacity-30 rotate-12">
<Image
src="/building.png"
alt=""
fill
className="object-contain"
priority
/>
</div>
{/* 树图片 - 右上 */}
<div className="absolute right-24 top-[40%] -translate-y-1/2 w-[30rem] h-[30rem] opacity-30 -rotate-12">
<Image
src="/tree.png"
alt=""
fill
className="object-contain"
priority
/>
</div>
</div>
{/* 内容区域 */}
<div className="max-w-3xl mx-auto text-center space-y-12">
{/* 图标 */}
<div className="inline-flex items-center justify-center w-16 h-16 text-primary/20">
<BookOpen className="h-16 w-16" strokeWidth={1} />
</div>
{/* 标题 */}
<div className="space-y-6">
<h1 className="text-4xl md:text-5xl font-serif font-light text-foreground tracking-wide">
</h1>
{/* 哲理文字 - 滚动显示 */}
<div className="h-48 overflow-hidden relative">
<div className="space-y-8 text-muted-foreground antialiased" style={{ animation: 'scroll 30s linear infinite' }}>
<p className="text-lg md:text-xl font-normal leading-relaxed">
</p>
<p className="text-base md:text-lg font-normal leading-relaxed opacity-85">
</p>
<p className="text-base md:text-lg font-normal leading-relaxed opacity-70">
</p>
<p className="text-base md:text-lg font-normal leading-relaxed opacity-60">
</p>
<p className="text-base md:text-lg font-normal leading-relaxed opacity-50">
</p>
<p className="text-base md:text-lg font-normal leading-relaxed opacity-40">
</p>
{/* 重复内容实现无缝滚动 */}
<p className="text-lg md:text-xl font-normal leading-relaxed">
</p>
<p className="text-base md:text-lg font-normal leading-relaxed opacity-85">
</p>
<p className="text-base md:text-lg font-normal leading-relaxed opacity-70">
</p>
</div>
</div>
</div>
{/* 创建按钮 */}
<div className="pt-8">
<Link href="/trees/new">
<Button
size="lg"
className="gap-2 bg-primary text-primary-foreground hover:bg-primary/90 transition-all duration-300"
>
<ArrowRight className="h-4 w-4" />
</Button>
</Link>
</div>
</div>
</main>
</div>
)
}
return (
<div className="flex min-h-screen flex-col bg-background font-sans">
<SiteHeader />
@@ -244,7 +361,9 @@ export default function DashboardPage() {
</div>
<div className="flex flex-col space-y-1">
<div className="flex items-center justify-center gap-3">
<span className="text-3xl font-serif font-bold text-primary tracking-tight">1</span>
<span className="text-3xl font-serif font-bold text-primary tracking-tight">
{stats.maleCount > 0 ? '1' : '0'}
</span>
<span className="text-2xl font-bold text-muted-foreground">:</span>
<span className="text-3xl font-serif font-bold text-primary tracking-tight">
{stats.maleCount > 0 ? (stats.femaleCount / stats.maleCount).toFixed(2) : '0'}
@@ -323,8 +442,8 @@ export default function DashboardPage() {
</div>
))
) : (
<div className="text-center text-muted-foreground py-8">
<div className="text-center py-12">
<p className="text-sm text-foreground font-light tracking-wide"></p>
</div>
)}
</div>
@@ -367,8 +486,8 @@ export default function DashboardPage() {
)
})
) : (
<div className="text-center text-muted-foreground py-8 text-sm">
<div className="text-center py-12">
<p className="text-sm text-foreground font-light tracking-wide"></p>
</div>
)}
</CardContent>
@@ -457,8 +576,8 @@ export default function DashboardPage() {
)
})
) : (
<div className="col-span-full text-center py-12 text-muted-foreground">
<div className="col-span-full text-center py-16">
<p className="text-sm text-foreground font-light tracking-wide"></p>
</div>
)
})()}
@@ -481,49 +600,32 @@ export default function DashboardPage() {
</CardHeader>
<CardContent>
<div className="space-y-6">
{useMemo(() => {
const members = Object.values(treeData.members)
const locationGroups: Record<string, any[]> = {}
members.forEach(member => {
if (member.ancestralHome) {
if (!locationGroups[member.ancestralHome]) {
locationGroups[member.ancestralHome] = []
}
locationGroups[member.ancestralHome].push(member)
}
})
const sortedLocations = Object.entries(locationGroups)
.sort((a, b) => b[1].length - a[1].length)
return sortedLocations.length > 0 ? (
sortedLocations.map(([location, locationMembers]) => (
<div key={location} className="border-l-4 border-primary pl-4">
<div className="flex items-center justify-between mb-3">
<h3 className="text-lg font-serif font-bold">{location}</h3>
<span className="text-sm text-muted-foreground">
{locationMembers.length}
</span>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2">
{locationMembers.map((member: any) => (
<Link href={`/members/${member.id}`} key={member.id}>
<div className="px-3 py-2 bg-muted rounded hover:bg-muted/80 transition-colors">
<p className="text-sm font-medium truncate">{member.fullName}</p>
<p className="text-xs text-muted-foreground"> {member.generation} </p>
</div>
</Link>
))}
</div>
{locationGroups.length > 0 ? (
locationGroups.map(([location, locationMembers]) => (
<div key={location} className="border-l-4 border-primary pl-4">
<div className="flex items-center justify-between mb-3">
<h3 className="text-lg font-serif font-bold">{location}</h3>
<span className="text-sm text-muted-foreground">
{locationMembers.length}
</span>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2">
{locationMembers.map((member: any) => (
<Link href={`/members/${member.id}`} key={member.id}>
<div className="px-3 py-2 bg-muted rounded hover:bg-muted/80 transition-colors">
<p className="text-sm font-medium truncate">{member.fullName}</p>
<p className="text-xs text-muted-foreground"> {member.generation} </p>
</div>
</Link>
))}
</div>
))
) : (
<div className="text-center py-12 text-muted-foreground">
</div>
)
}, [treeData])}
))
) : (
<div className="text-center py-16">
<p className="text-sm text-foreground font-light tracking-wide"></p>
</div>
)}
</div>
</CardContent>
</Card>