150 lines
4.5 KiB
TypeScript
150 lines
4.5 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
import { useSession } from "next-auth/react"
|
|
import Link from "next/link"
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Users, Calendar, Plus, ArrowRight } from "lucide-react"
|
|
import { format } from "date-fns"
|
|
import { zhCN } from "date-fns/locale"
|
|
|
|
interface FamilyTree {
|
|
id: string
|
|
name: string
|
|
description: string | null
|
|
createdAt: string
|
|
updatedAt: string
|
|
_count: {
|
|
members: number
|
|
collaborators: number
|
|
}
|
|
}
|
|
|
|
export function FamilyTreesList() {
|
|
const { data: session } = useSession()
|
|
const [trees, setTrees] = useState<FamilyTree[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
if (session?.user?.id) {
|
|
console.log('📋 开始获取家族树列表...')
|
|
fetch('/api/trees')
|
|
.then(res => {
|
|
console.log('📋 家族树列表响应状态:', res.status)
|
|
return res.json()
|
|
})
|
|
.then(data => {
|
|
console.log('📋 家族树列表数据:', {
|
|
data,
|
|
treesCount: data.trees?.length,
|
|
trees: data.trees
|
|
})
|
|
if (data.trees) {
|
|
setTrees(data.trees)
|
|
}
|
|
setLoading(false)
|
|
})
|
|
.catch(err => {
|
|
console.error('获取家族树失败:', err)
|
|
setLoading(false)
|
|
})
|
|
} else {
|
|
setLoading(false)
|
|
}
|
|
}, [session?.user?.id])
|
|
|
|
if (!session) {
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>我的家族树</CardTitle>
|
|
<CardDescription>请先登录查看您的家族树</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Link href="/auth/signin">
|
|
<Button>登录</Button>
|
|
</Link>
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
if (loading) {
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>我的家族树</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p className="text-muted-foreground">加载中...</p>
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between">
|
|
<div>
|
|
<CardTitle>我的家族树</CardTitle>
|
|
<CardDescription>
|
|
{trees.length > 0 ? `共 ${trees.length} 个家族树` : '还没有家族树'}
|
|
</CardDescription>
|
|
</div>
|
|
<Link href="/trees/new">
|
|
<Button size="sm">
|
|
<Plus className="h-4 w-4 mr-2" />
|
|
创建家族树
|
|
</Button>
|
|
</Link>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{trees.length === 0 ? (
|
|
<div className="text-center py-8">
|
|
<p className="text-muted-foreground mb-4">您还没有创建任何家族树</p>
|
|
<Link href="/trees/new">
|
|
<Button>
|
|
<Plus className="h-4 w-4 mr-2" />
|
|
创建第一个家族树
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-4">
|
|
{trees.map((tree) => (
|
|
<div
|
|
key={tree.id}
|
|
className="flex items-center justify-between p-4 rounded-lg border bg-card hover:bg-accent/50 transition-colors"
|
|
>
|
|
<div className="flex-1">
|
|
<h3 className="font-semibold text-lg">{tree.name}</h3>
|
|
{tree.description && (
|
|
<p className="text-sm text-muted-foreground mt-1">{tree.description}</p>
|
|
)}
|
|
<div className="flex items-center gap-4 mt-2 text-xs text-muted-foreground">
|
|
<span className="flex items-center gap-1">
|
|
<Users className="h-3 w-3" />
|
|
{tree._count.members} 个成员
|
|
</span>
|
|
<span className="flex items-center gap-1">
|
|
<Calendar className="h-3 w-3" />
|
|
创建于 {format(new Date(tree.createdAt), 'yyyy年MM月dd日', { locale: zhCN })}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<Link href={`/tree?treeId=${tree.id}`}>
|
|
<Button variant="ghost" size="sm">
|
|
查看
|
|
<ArrowRight className="h-4 w-4 ml-2" />
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|