Files
chinese-family-tree-2/components/dashboard/family-trees-list.tsx
T
freedakgmail 86e889cc2a 0.3.1.2
2025-11-30 19:10:30 +08:00

141 lines
4.5 KiB
TypeScript

"use client"
import { useEffect, useState } from "react"
import { useSession } from "next-auth/react"
import Link from "next/link"
import { ChineseCard, ChineseCardContent, ChineseCardHeader, ChineseCardTitle, ChineseCardDescription } from "@/components/ui/chinese-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) {
fetch('/api/trees')
.then(res => res.json())
.then(data => {
if (data.trees) {
setTrees(data.trees)
}
setLoading(false)
})
.catch(err => {
console.error('获取家族树失败:', err)
setLoading(false)
})
} else {
setLoading(false)
}
}, [session?.user?.id])
if (!session) {
return (
<ChineseCard variant="plaque" className="shadow-sm">
<ChineseCardHeader>
<ChineseCardTitle></ChineseCardTitle>
<ChineseCardDescription></ChineseCardDescription>
</ChineseCardHeader>
<ChineseCardContent>
<Link href="/auth/signin">
<Button></Button>
</Link>
</ChineseCardContent>
</ChineseCard>
)
}
if (loading) {
return (
<ChineseCard variant="plaque" className="shadow-sm">
<ChineseCardHeader>
<ChineseCardTitle></ChineseCardTitle>
</ChineseCardHeader>
<ChineseCardContent>
<p className="text-muted-foreground">...</p>
</ChineseCardContent>
</ChineseCard>
)
}
return (
<ChineseCard variant="plaque" className="shadow-sm">
<ChineseCardHeader className="flex flex-row items-center justify-between">
<div>
<ChineseCardTitle></ChineseCardTitle>
<ChineseCardDescription>
{trees.length > 0 ? `${trees.length} 个家族树` : '还没有家族树'}
</ChineseCardDescription>
</div>
<Link href="/trees/new">
<Button size="sm">
<Plus className="h-4 w-4 mr-2" />
</Button>
</Link>
</ChineseCardHeader>
<ChineseCardContent>
{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/50 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>
)}
</ChineseCardContent>
</ChineseCard>
)
}