0.8.0.0
This commit is contained in:
+110
-4
@@ -7,11 +7,11 @@ import dynamic from "next/dynamic"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { ChineseCard, ChineseCardContent, ChineseCardHeader, ChineseCardTitle, ChineseCardDescription, ChineseDivider } from "@/components/ui/chinese-card"
|
||||
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"
|
||||
import { Dialog, DialogContent, DialogTitle, DialogHeader, DialogDescription, DialogFooter } from "@/components/ui/dialog"
|
||||
import { SiteHeader } from "@/components/site-header"
|
||||
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, Calculator, Loader2, Images, ChevronDown, ChevronUp, EyeOff, Play, Video } from "lucide-react"
|
||||
import { UserPlus, Network, Map, Calendar, Users, ArrowRight, Clock, Search, BookOpen, BarChart3, Calculator, Loader2, Images, ChevronDown, ChevronUp, EyeOff, Play, Video, Edit } from "lucide-react"
|
||||
import { useFamily } from "@/context/family-context"
|
||||
import { useMemo, useState, useEffect, useRef, useCallback } from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
@@ -24,7 +24,11 @@ import { isInCurrentMonth, solar2lunar, lunar2solar } from "@/lib/lunar-calendar
|
||||
import { MemberNameWithStatus } from "@/components/member-name-with-status"
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
|
||||
import { Switch } from "@/components/ui/switch"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import type { FamilyPhoto } from "@/types/family"
|
||||
import { useDialog } from "@/components/ui/alert-dialog-custom"
|
||||
|
||||
// 动态导入统计图表组件(减少初始加载体积)
|
||||
const StatisticsCharts = dynamic(
|
||||
@@ -63,10 +67,14 @@ const isVideoFile = (url: string) => {
|
||||
export default function DashboardPage() {
|
||||
const { treeData, isLoading, currentTree, updateMember } = useFamily()
|
||||
const { data: session } = useSession()
|
||||
const { showAlert } = useDialog()
|
||||
const [recentActivities, setRecentActivities] = useState<ActivityLog[]>([])
|
||||
const [selectedPhoto, setSelectedPhoto] = useState<string | null>(null)
|
||||
const [statsExpanded, setStatsExpanded] = useState(true)
|
||||
const [adminToggleLoading, setAdminToggleLoading] = useState<string | null>(null)
|
||||
const [editDialogOpen, setEditDialogOpen] = useState(false)
|
||||
const [editForm, setEditForm] = useState({ name: '', description: '' })
|
||||
const [isSaving, setIsSaving] = useState(false)
|
||||
const router = useRouter()
|
||||
|
||||
// 首次登录跳转到使用帮助
|
||||
@@ -223,6 +231,38 @@ export default function DashboardPage() {
|
||||
}
|
||||
}, [isOwner, treeData.members, updateMember])
|
||||
|
||||
// 保存编辑
|
||||
const handleSaveEdit = async () => {
|
||||
if (!currentTree?.id || !editForm.name.trim()) return
|
||||
|
||||
setIsSaving(true)
|
||||
try {
|
||||
const response = await fetch(`/api/trees/${currentTree.id}`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: editForm.name.trim(),
|
||||
description: editForm.description.trim() || null,
|
||||
}),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('更新失败')
|
||||
}
|
||||
|
||||
setEditDialogOpen(false)
|
||||
// 刷新页面以显示更新后的数据
|
||||
window.location.reload()
|
||||
} catch (error) {
|
||||
console.error('更新家族信息失败:', error)
|
||||
await showAlert('更新失败,请重试', "错误")
|
||||
} finally {
|
||||
setIsSaving(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取本月纪念日(生日和忌日)- 支持农历
|
||||
const monthlyAnniversaries = useMemo(() => {
|
||||
const members = Object.values(treeData.members)
|
||||
@@ -452,12 +492,28 @@ export default function DashboardPage() {
|
||||
</div>
|
||||
<p className="text-muted-foreground mt-1">
|
||||
{currentTree?.description || '记录家族历史,传承家族文化'}
|
||||
{stats.maxGeneration > 0 && ` · 第 ${stats.maxGeneration} 代传人`}
|
||||
{stats.maxGeneration > 0 && ` · 共 ${stats.maxGeneration} 代传人`}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{session && currentTree?.ownerId === session.user?.id && (
|
||||
<CollaboratorDialog />
|
||||
<>
|
||||
<CollaboratorDialog />
|
||||
<Button
|
||||
variant="outline"
|
||||
className="gap-2"
|
||||
onClick={() => {
|
||||
setEditForm({
|
||||
name: currentTree?.name || '',
|
||||
description: currentTree?.description || ''
|
||||
})
|
||||
setEditDialogOpen(true)
|
||||
}}
|
||||
>
|
||||
<Edit className="h-4 w-4" />
|
||||
编辑
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{permissions.canCreate(currentTree?.currentUserRole) && (
|
||||
<Link href={currentTree?.id ? `/members/new?treeId=${currentTree.id}` : '/members/new'}>
|
||||
@@ -1181,6 +1237,56 @@ export default function DashboardPage() {
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* 编辑家族信息对话框 */}
|
||||
<Dialog open={editDialogOpen} onOpenChange={setEditDialogOpen}>
|
||||
<DialogContent className="sm:max-w-[500px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>编辑家族信息</DialogTitle>
|
||||
<DialogDescription>
|
||||
修改家族名称和说明
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4 py-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="tree-name">家族名称</Label>
|
||||
<Input
|
||||
id="tree-name"
|
||||
value={editForm.name}
|
||||
onChange={(e) => setEditForm({ ...editForm, name: e.target.value })}
|
||||
placeholder="请输入家族名称"
|
||||
maxLength={50}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="tree-description">家族说明</Label>
|
||||
<Textarea
|
||||
id="tree-description"
|
||||
value={editForm.description}
|
||||
onChange={(e) => setEditForm({ ...editForm, description: e.target.value })}
|
||||
placeholder="请输入家族说明"
|
||||
rows={4}
|
||||
maxLength={200}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setEditDialogOpen(false)}
|
||||
disabled={isSaving}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSaveEdit}
|
||||
disabled={isSaving || !editForm.name.trim()}
|
||||
>
|
||||
{isSaving ? '保存中...' : '保存'}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user