"use client"; import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { formatDistanceToNow } from "date-fns"; import { zhCN } from "date-fns/locale"; import { Trash2, FileImage, Loader2, Plus } from "lucide-react"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "@/components/ui/dialog"; import { canvasService } from "@/services/canvas"; import { toast } from "sonner"; import { cn } from "@/lib/utils"; import type { CanvasProject } from "@/types/canvas"; interface CanvasFileListProps { open: boolean; onOpenChange: (open: boolean) => void; currentId: string; } export function CanvasFileList({ open, onOpenChange, currentId }: CanvasFileListProps) { const router = useRouter(); const [projects, setProjects] = useState([]); const [isLoading, setIsLoading] = useState(false); // 加载项目列表 const loadProjects = async () => { setIsLoading(true); const result = await canvasService.getProjects(); if (result.success && result.data) { // 按更新时间降序排序 const sorted = result.data.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime() ); setProjects(sorted); } setIsLoading(false); }; useEffect(() => { if (open) { loadProjects(); } }, [open]); // 创建新画布 const handleCreateNew = async () => { // 生成一个新 ID 并跳转,具体的创建逻辑由页面组件处理 const newId = crypto.randomUUID(); router.push(`/canvas/${newId}`); onOpenChange(false); }; // 切换画布 const handleSwitch = (id: string) => { if (id === currentId) { onOpenChange(false); return; } // 先导航,再关闭弹窗(使用 setTimeout 确保导航生效) const targetUrl = `/canvas/${id}`; onOpenChange(false); // 使用 setTimeout 确保在 React 状态更新完成后再导航 setTimeout(() => { window.location.assign(targetUrl); }, 100); }; // 删除画布 const handleDelete = async (e: React.MouseEvent, id: string) => { e.stopPropagation(); if (!confirm("确定要删除这个画布吗?")) return; const result = await canvasService.deleteProject(id); if (result.success) { setProjects(prev => prev.filter(p => p.id !== id)); toast.success("删除成功"); // 如果删除的是当前画布,跳转到列表第一个或首页 if (id === currentId) { const next = projects.find(p => p.id !== id); if (next) { router.push(`/canvas/${next.id}`); } else { router.push('/canvas'); // 或者 handleCreateNew() } } } else { toast.error("删除失败"); } }; return (
已生成文件列表
画布列表
{isLoading ? (
) : projects.length === 0 ? (

暂无画布历史

) : (
{projects.map((project) => (
handleSwitch(project.id)} className={cn( "flex items-center gap-3 p-2 rounded-xl cursor-pointer transition-all border", "hover:bg-muted/50 hover:shadow-sm", project.id === currentId ? "bg-primary/5 border-primary/20 ring-1 ring-primary/10" : "bg-card border-transparent" )} > {/* 缩略图 */}
{project.thumbnail ? ( {project.title} ) : (
)}
{/* 信息 */}

{project.title || "未命名画布"}

{formatDistanceToNow(new Date(project.updatedAt), { addSuffix: true, locale: zhCN })}

{/* 操作 */}
))}
到底了
)}
); }