"use client"; import { useState, useRef, useEffect } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { Plus, Search, FolderOpen, Film, Clock, MoreHorizontal, Zap, ChevronRight, Loader2, Settings, Copy, Archive, Trash2, X, Sparkles, } from "lucide-react"; /* ───────────────────────────────────────────── Mock Data ───────────────────────────────────────────── */ interface Project { id: string; name: string; type: "original" | "adaptation" | "short" | "custom"; episodes: number; currentEpisode: number; currentStage: number; status: "idle" | "running" | "completed" | "failed"; updatedAt: string; thumbnail?: string; } const TYPE_LABELS: Record = { original: "原创动画", adaptation: "网文改编", short: "短片 / PV", custom: "自定义", }; const STATUS_CONFIG: Record< Project["status"], { label: string; dot: string; text: string } > = { idle: { label: "空闲", dot: "bg-gray-500", text: "text-text-secondary" }, running: { label: "运行中", dot: "bg-blue-500 animate-pulse", text: "text-blue-400", }, completed: { label: "已完成", dot: "bg-emerald-500", text: "text-emerald-400" }, failed: { label: "失败", dot: "bg-red-500", text: "text-red-400" }, }; const STAGE_NAMES = [ "剧本对话", "规划", "参考图生成", "宫格生成", "切分", "视频生成", "剪辑导出", ]; const MOCK_PROJECTS: Project[] = [ { id: "proj_001", name: "T仔的上班日记", type: "original", episodes: 12, currentEpisode: 1, currentStage: 6, status: "running", updatedAt: "2 小时前", }, { id: "proj_002", name: "星际萌宠大冒险", type: "original", episodes: 8, currentEpisode: 3, currentStage: 7, status: "completed", updatedAt: "昨天", }, { id: "proj_003", name: "凡人修仙传", type: "adaptation", episodes: 24, currentEpisode: 1, currentStage: 2, status: "running", updatedAt: "5 小时前", }, { id: "proj_004", name: "产品宣传 PV", type: "short", episodes: 1, currentEpisode: 1, currentStage: 4, status: "failed", updatedAt: "3 天前", }, ]; /* ───────────────────────────────────────────── CreateProjectModal ───────────────────────────────────────────── */ const PROJECT_TYPES = [ { key: "original", label: "原创动画", desc: "从零开始创作原创动画剧本" }, { key: "adaptation", label: "网文改编", desc: "将现有小说/文本改编为动画" }, { key: "short", label: "短片 / PV", desc: "产品宣传、MV 等单集短片" }, { key: "custom", label: "自定义", desc: "自由配置技能和流水线" }, ] as const; function CreateProjectModal({ open, onClose }: { open: boolean; onClose: () => void }) { const router = useRouter(); const [step, setStep] = useState(1); const [name, setName] = useState(""); const [type, setType] = useState("original"); const [episodes, setEpisodes] = useState("12"); if (!open) return null; const handleCreate = () => { // Mock: just navigate to new project detail router.push("/dashboard/proj_new"); }; return (
{/* Backdrop */}
{/* Modal */}
{/* Close */} {/* Header */}

创建新项目

{step === 1 ? "填写项目基本信息" : "选择项目类型和规模"}

{step === 1 ? (
setName(e.target.value)} placeholder="例:恐龙也是打工龙" className="w-full bg-white/[0.04] border border-white/10 rounded-lg px-4 py-3 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:border-accent/50 focus:ring-3 focus:ring-accent/15 motion-safe:transition-all" autoFocus />
{PROJECT_TYPES.map((t) => ( ))}
) : (
setEpisodes(e.target.value)} min={1} max={100} className="w-full bg-white/[0.04] border border-white/10 rounded-lg px-4 py-3 text-sm text-text-primary focus:outline-none focus:border-accent/50 focus:ring-3 focus:ring-accent/15 motion-safe:transition-all" />
{/* Skills preview */}
{["screenplay-skill", "storyboard-video-skill", "script-segmentation-skill"].map((s) => (
{s}
))}
)}
); } /* ───────────────────────────────────────────── Components ───────────────────────────────────────────── */ function StageProgress({ currentStage, status, }: { currentStage: number; status: Project["status"]; }) { return (
{STAGE_NAMES.map((name, i) => { const stageNum = i + 1; const isCompleted = stageNum < currentStage; const isCurrent = stageNum === currentStage; const isFailed = isCurrent && status === "failed"; let bgColor = "bg-white/[0.06]"; // pending if (isCompleted) bgColor = "bg-emerald-500/40"; if (isCurrent && status === "running") bgColor = "bg-blue-500/50 motion-safe:animate-pulse"; if (isCurrent && status === "completed") bgColor = "bg-emerald-500/40"; if (isFailed) bgColor = "bg-red-500/40"; return (
); })}
); } function ProjectCardMenu({ project }: { project: Project }) { const [open, setOpen] = useState(false); const menuRef = useRef(null); useEffect(() => { if (!open) return; const handleClick = (e: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { setOpen(false); } }; document.addEventListener("mousedown", handleClick); return () => document.removeEventListener("mousedown", handleClick); }, [open]); const MENU_ITEMS = [ { icon: Settings, label: "项目设置", action: () => {} }, { icon: Copy, label: "复制项目", action: () => {} }, { icon: Archive, label: "归档", action: () => {} }, { icon: Trash2, label: "删除", action: () => {}, danger: true }, ]; return (
{open && (
{MENU_ITEMS.map((item) => ( ))}
)}
); } function ProjectCard({ project }: { project: Project }) { const statusConf = STATUS_CONFIG[project.status]; const stageName = STAGE_NAMES[project.currentStage - 1] || ""; return ( {/* Header: type badge + menu */}
{TYPE_LABELS[project.type]}
{/* Title */}

{project.name}

{/* Meta: episodes + status */}
{project.episodes} 集 {statusConf.label}
{/* Stage progress bar */}
{/* Current stage label + timestamp */}
EP{String(project.currentEpisode).padStart(2, "0")} ·{" "} {project.currentStage > 0 ? `第${project.currentStage}阶段 — ${stageName}` : "未开始"} {project.updatedAt}
); } function EmptyState({ onCreate }: { onCreate: () => void }) { return (

还没有项目

创建你的第一个动画项目,开始 AI 驱动的创作之旅

); } /* ───────────────────────────────────────────── Page ───────────────────────────────────────────── */ export default function DashboardPage() { const [searchQuery, setSearchQuery] = useState(""); const [showCreateModal, setShowCreateModal] = useState(false); const projects = MOCK_PROJECTS; const filtered = projects.filter((p) => p.name.toLowerCase().includes(searchQuery.toLowerCase()) ); return (
{/* ─── Page Header ─── */}

项目

管理你的动画项目,查看流水线进度

{/* ─── Search & Stats ─── */}
setSearchQuery(e.target.value)} className="w-full bg-white/[0.04] border border-white/10 rounded-lg pl-10 pr-4 py-2.5 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:border-accent/50 focus:ring-3 focus:ring-accent/15 motion-safe:transition-all motion-safe:duration-200" />
{projects.length} 个项目 {projects.filter((p) => p.status === "running").length} 运行中
{/* ─── Project Grid ─── */} {filtered.length > 0 ? (
{filtered.map((project) => ( ))}
) : searchQuery ? (

没有找到匹配项

试试其他关键词

) : ( setShowCreateModal(true)} /> )} {/* Create Project Modal */} setShowCreateModal(false)} />
); }