"use client"; import { useState } from "react"; import { Zap, Settings, Users, Check, X, RefreshCw, ChevronRight, ChevronDown, Play, AlertTriangle, Pencil, Loader2, Info, FolderPlus, Search, ChevronsUpDown, Trash2, Hash, User, } from "lucide-react"; /* ───────────────────────────────────────────── Section wrapper ───────────────────────────────────────────── */ function Section({ title, children, }: { title: string; children: React.ReactNode; }) { return (

{title}

{children}
); } /* ───────────────────────────────────────────── Main Showcase Page ───────────────────────────────────────────── */ export default function ShowcasePage() { const [logOpen, setLogOpen] = useState(false); const [confirmCountdown, setConfirmCountdown] = useState(null); const [selectOpen, setSelectOpen] = useState(false); const [selectValue, setSelectValue] = useState("Original Animation"); const [activeTab, setActiveTab] = useState("overview"); const [activeSeg, setActiveSeg] = useState("Grid"); const [lang, setLang] = useState<"en" | "zh">("en"); const t = lang === "zh" ? { // Page title: "组件展示", subtitle: "Air Spark 设计系统 v0.4 — 视觉规范源文件", // Nav navProject: "T仔的上班日记 / 第一集", // Sections s2: "2. 色彩 & 玻璃层", bgLayers: "背景层", glassCards: "玻璃卡片", stdGlass: "标准玻璃", stdGlassDesc: "bg-white/[0.06] + 背景模糊", activeGlass: "激活玻璃", activeGlassDesc: "+ 品牌光晕边框", hoverGlass: "悬停玻璃", hoverGlassDesc: "悬停 → bg-white/[0.12]", accentColors: "品牌 & 状态色", s3: "3. 字体排版", typoDisplay: "Air Spark", typoH1: "流水线总览", typoH2: "第六阶段 — 视频生成", typoH3: "角色设计审核", typoBody: "导演与 AI 对话生成剧本,一键触发七阶段自动化流水线,输出成片视频。整个过程全并发执行,无需手动干预。", typoCn: "思源黑体用于中文正文排版,笔画均匀、重心稳定,与 DM Sans 在视觉密度上高度匹配。", s4: "4. 按钮", btnConfirm: "确认并启动", btnContinue: "继续编辑", btnWaiting: "等待中...", btnProcessing: "处理中...", s5: "5. 状态格子(第六阶段片段网格)", stageTitle: "第六阶段 — 视频生成", completed: "已完成", remaining: "56% — 预计剩余 ~8 分钟", done: "完成", running: "生成中", pending: "队列中", failed: "失败", seg08fail: "片段 08 — 重试 3 次后超时失败", editPrompt: "编辑提示词", retry: "重跑", s6: "6. 流水线步骤条", steps: ["剧本", "提示词提取", "图片资产", "分镜", "切分", "视频生成", "时间轴"], s7: "7. 审核卡片(图片资产审核)", charRef: "角色参考图", approved: "已通过", approveStatus: "3 / 4 角色已通过。请重跑失败角色后继续。", confirmAll: "全部确认 & 继续", cancel: "取消", launchIn: "即将启动", s8: "8. 骨架屏加载", s9: "9. 剧本确认(第一阶段)", scriptReady: "剧本已就绪", scriptInfo: "共 8 场景 / 预估 4 分 20 秒", confirmScript: "确认剧本,启动流水线", continueEdit: "继续修改剧本", s10: "10. 可折叠日志面板", sysLog: "系统日志", s11: "11. 模态框(内联演示)", regenTitle: "重新生成片段?", regenDesc: "将使用修改后的提示词重新提交片段 08 到 Seedance。之前的结果将被覆盖。", regenBtn: "重新生成", s12: "12. 表单元素", projectName: "项目名称", projectPlaceholder: "输入项目名称...", contentType: "内容类型", scriptPrompt: "剧本提示词", scriptPlaceholder: "描述你的故事...", apiKey: "API Key", apiError: "无效的 API Key 格式", s13: "13. Toast 通知(左边框)", toastSuccess: "保存成功", toastSuccessDesc: "剧本已保存为正式版本", toastError: "片段 08 失败", toastErrorDesc: "Seedance API 超时,已重试 3 次", toastWarning: "等待审核", toastWarningDesc: "角色设计需要导演审核", toastInfo: "流水线已启动", toastInfoDesc: "正在运行第二阶段 — 提示词提取", s14: "14. 空状态", noProjects: "还没有项目", noProjectsDesc: "创建你的第一个动画项目", createProject: "创建项目", noResults: "没有找到匹配项", noResultsDesc: "试试其他关键词或筛选条件", s15: "15. 徽章 / 标签", statusBadges: "状态徽章", contentTags: "内容标签", s16: "16. 头像", avatarGroup: "头像组", s17: "17. 导航路径", projects: "项目", pipeline: "流水线", s18: "18. 标签页 / 分段控制", underlineTabs: "下划线标签页", segCtrl: "分段控制", activeTabLabel: "当前标签页", tabs: ["概览", "资产", "设置"], s19: "19. 危险按钮 & 搜索框", dangerBtns: "危险按钮", deleteProject: "删除项目", confirmDelete: "确认删除", searchInput: "搜索框", searchPlaceholder: "搜索项目、剧集...", searchNote: "带前置搜索图标 — 左内边距 pl-10", s20: "20. 提示气泡", tooltipSettings: "项目设置", tooltipRetry: "重跑失败项", tooltipHint: "悬停图标查看提示气泡位置", s21: "21. 文字对比度验证", primaryContrast: "主文字 — #f1f0ff on #07070f", secondaryContrast: "次要文字 — #8b8ea8 on #07070f", mutedContrast: "弱化文字 — #4c4f6b on #07070f", mutedNote: "仅用于装饰", footer: "液态玻璃 · 影院暗色 · AI 原生 · 高端工具", selectOptions: ["原创动画", "网文改编", "短片 / PV", "自定义"], } : { title: "Component Showcase", subtitle: "Air Spark Design System v0.4 — Visual Source of Truth", navProject: "T仔的上班日记 / EP01", s2: "2. Colors & Glass Layers", bgLayers: "Background Layers", glassCards: "Glass Cards", stdGlass: "Standard Glass", stdGlassDesc: "bg-white/[0.06] + backdrop-blur-2xl", activeGlass: "Active Glass", activeGlassDesc: "+ accent glow border", hoverGlass: "Hover Glass", hoverGlassDesc: "hover → bg-white/[0.12]", accentColors: "Accent & Status Colors", s3: "3. Typography", typoDisplay: "Air Spark", typoH1: "Pipeline Overview", typoH2: "Stage 6 — Video Generation", typoH3: "Image Assets Review", typoBody: "Directors chat with AI to generate scripts, one-click triggers a 7-stage automated pipeline, and outputs finished video. Fully concurrent, no manual intervention needed.", typoCn: "Noto Sans SC for Chinese body text — even strokes, stable center of gravity, visually matched with DM Sans density.", s4: "4. Buttons", btnConfirm: "Confirm & Launch", btnContinue: "Continue Editing", btnWaiting: "Waiting...", btnProcessing: "Processing...", s5: "5. Status Tiles (Stage 6 Segment Grid)", stageTitle: "Stage 6 — Video Generation", completed: "completed", remaining: "56% — est. ~8 min remaining", done: "Done", running: "Running", pending: "Pending", failed: "Failed", seg08fail: "Segment 08 — Failed after 3 retries (timeout)", editPrompt: "Edit Prompt", retry: "Retry", s6: "6. Pipeline Stepper", steps: ["Script", "Prompt Extract", "Image Assets", "Keyshots", "Segments", "Video Gen", "Timeline"], s7: "7. Review Cards (Image Assets Approval)", charRef: "Character Reference Sheet", approved: "Approved", approveStatus: "3 / 4 characters approved. Retry failed character to proceed.", confirmAll: "Confirm All & Continue", cancel: "Cancel", launchIn: "Launching in", s8: "8. Skeleton Loading", s9: "9. Script Confirm CTA (Stage 1)", scriptReady: "Script Ready", scriptInfo: "8 scenes / estimated 4m 20s", confirmScript: "Confirm Script & Launch Pipeline", continueEdit: "Continue editing script", s10: "10. Collapsible Log Panel", sysLog: "System Log", s11: "11. Modal Dialog (Inline Demo)", regenTitle: "Regenerate Segment?", regenDesc: "This will re-submit segment 08 to Seedance with modified prompt. Previous result will be overwritten.", regenBtn: "Regenerate", s12: "12. Form Elements", projectName: "Project Name", projectPlaceholder: "Enter project name...", contentType: "Content Type", scriptPrompt: "Script Prompt", scriptPlaceholder: "Describe your story...", apiKey: "API Key", apiError: "Invalid API key format", s13: "13. Toast Notifications (Left Border)", toastSuccess: "Save successful", toastSuccessDesc: "Script saved as official version", toastError: "Segment 08 failed", toastErrorDesc: "Seedance API timeout after 3 retries", toastWarning: "Awaiting approval", toastWarningDesc: "Character designs need director review", toastInfo: "Pipeline started", toastInfoDesc: "Running Stage 2 — asset & keyshot planning", s14: "14. Empty States", noProjects: "No Projects Yet", noProjectsDesc: "Create your first animation project", createProject: "Create Project", noResults: "No Results Found", noResultsDesc: "Try different keywords or filters", s15: "15. Badge / Tag", statusBadges: "Status Badges", contentTags: "Content Tags", s16: "16. Avatar", avatarGroup: "Avatar Group", s17: "17. Breadcrumb", projects: "Projects", pipeline: "Pipeline", s18: "18. Tab / Segmented Control", underlineTabs: "Underline Tabs", segCtrl: "Segmented Control", activeTabLabel: "Active tab", tabs: ["overview", "assets", "settings"], s19: "19. Danger Button & Search Input", dangerBtns: "Danger Buttons", deleteProject: "Delete Project", confirmDelete: "Confirm Delete", searchInput: "Search Input", searchPlaceholder: "Search projects, episodes...", searchNote: "With leading search icon — prefix padding pl-10", s20: "20. Tooltip", tooltipSettings: "Project Settings", tooltipRetry: "Retry Failed", tooltipHint: "Hover the icons to see tooltip positions", s21: "21. Text Contrast Verification", primaryContrast: "Primary text — #f1f0ff on #07070f", secondaryContrast: "Secondary text — #8b8ea8 on #07070f", mutedContrast: "Muted text — #4c4f6b on #07070f", mutedNote: "decorative only", footer: "Liquid Glass · Cinematic Dark · AI Native · Premium Tool", selectOptions: ["Original Animation", "Web Novel Adaptation", "Short Film / PV", "Custom"], }; const handleConfirm = () => { setConfirmCountdown(3); const id = setInterval(() => { setConfirmCountdown((prev) => { if (prev === null || prev <= 1) { clearInterval(id); return null; } return prev - 1; }); }, 1000); }; return (
{/* ═══════════════════════════════════════ 1. TOP NAV BAR (Glass, fixed) ═══════════════════════════════════════ */} {/* Spacer for fixed nav */}
{/* Main content */}
{/* Page title */}

{t.title}

{t.subtitle}

{/* ═══════════════════════════════════════ 2. COLORS & GLASS ═══════════════════════════════════════ */}
{/* Background layers */}

{t.bgLayers}

{[ { name: "bg-base", color: "#07070f" }, { name: "bg-surface", color: "#0d0d1a" }, { name: "bg-elevated", color: "#12121f" }, ].map((item) => (

{item.name}

{item.color}

))}
{/* Glass cards */}

{t.glassCards}

{t.stdGlass}

{t.stdGlassDesc}

{t.activeGlass}

{t.activeGlassDesc}

{t.hoverGlass}

{t.hoverGlassDesc}

{/* Accent colors */}

{t.accentColors}

{[ { name: "Accent", color: "#6c63ff", tw: "bg-accent" }, { name: "Blue", color: "#3b82f6", tw: "bg-accent-blue" }, { name: "Completed", color: "#10b981", tw: "bg-emerald-500" }, { name: "Failed", color: "#ef4444", tw: "bg-red-500" }, { name: "Waiting", color: "#f59e0b", tw: "bg-amber-500" }, { name: "Pending", color: "#4b5563", tw: "bg-gray-600" }, ].map((item) => (

{item.name}

{item.color}

))}
{/* ═══════════════════════════════════════ 3. TYPOGRAPHY ═══════════════════════════════════════ */}

Display / 48px / Space Grotesk 700

{t.typoDisplay}

H1 / 32px / Space Grotesk 700

{t.typoH1}

H2 / 24px / Space Grotesk 600

{t.typoH2}

H3 / 18px / Space Grotesk 600

{t.typoH3}

Body / 15px / DM Sans 400

{t.typoBody}

CN Body / 15px / Noto Sans SC 400

{t.typoCn}

Small / 13px / DM Sans 400

seg_001 · 00:00.000 → 00:08.500 · scene_01

Mono / 13px / JetBrains Mono 400

cell_num = floor((seg_start - scene_start) / cell_duration) + 1

{/* ═══════════════════════════════════════ 4. BUTTONS ═══════════════════════════════════════ */}
{/* Primary CTA */} {/* Secondary */} {/* Disabled */} {/* Loading */} {/* Icon button */}
{/* ═══════════════════════════════════════ 5. STATUS TILES (Stage 6 Grid) ═══════════════════════════════════════ */}
{/* Progress bar */}
{t.stageTitle} 18 / 32 {t.completed}

{t.remaining}

{/* Segment grid */}
{Array.from({ length: 32 }, (_, i) => { const num = i + 1; let status: "done" | "running" | "pending" | "failed"; if (num === 8) status = "failed"; else if (num <= 12) status = "done"; else if (num <= 18) status = "running"; else status = "pending"; const styles = { done: "bg-emerald-500/15 border-emerald-400/30 text-emerald-400", running: "bg-blue-500/20 border-blue-400/40 text-blue-400 motion-safe:animate-pulse", pending: "bg-white/[0.03] border-white/[0.06] text-text-muted", failed: "bg-red-500/15 border-red-400/30 text-red-400", }; const icons = { done: , running: (
), pending: (
), failed: , }; return (
{String(num).padStart(2, "0")} {icons[status]}
); })}
{/* Legend */}
{t.done}
{t.running}
{t.pending} {t.failed}
{/* Failed segment action */}
{t.seg08fail}
{/* ═══════════════════════════════════════ 6. PIPELINE STEPPER ═══════════════════════════════════════ */}
{[ { num: 1, name: t.steps[0], status: "done" as const }, { num: 2, name: t.steps[1], status: "done" as const }, { num: 3, name: t.steps[2], status: "waiting" as const }, { num: 4, name: t.steps[3], status: "idle" as const }, { num: 5, name: t.steps[4], status: "idle" as const }, { num: 6, name: t.steps[5], status: "idle" as const }, { num: 7, name: t.steps[6], status: "idle" as const }, ].map((step, idx) => (
{step.status === "done" ? ( ) : ( step.num )}
{step.name}
{idx < 6 && ( )}
))}
{/* ═══════════════════════════════════════ 7. REVIEW CARDS (Stage 3 Character Approval) ═══════════════════════════════════════ */}
{[ { name: "T仔", status: "approved" as const }, { name: "特特", status: "approved" as const }, { name: "班长", status: "approved" as const }, { name: "路人甲", status: "failed" as const }, ].map((char) => (
{/* Image placeholder */}
{char.name[0]}

{char.name}

{t.charRef}

{char.status === "approved" ? ( ) : ( )}
))}
{/* Confirm CTA with countdown */}
{confirmCountdown !== null ? (

{t.launchIn} {confirmCountdown}s...

) : (

{t.approveStatus}

)}
{/* ═══════════════════════════════════════ 8. SKELETON LOADING ═══════════════════════════════════════ */}
{[1, 2, 3].map((i) => (
))}
{/* ═══════════════════════════════════════ 9. CONFIRM CTA (Stage 1 Script) ═══════════════════════════════════════ */}
{t.scriptReady}

{t.scriptInfo}

{/* ═══════════════════════════════════════ 10. COLLAPSIBLE LOG PANEL ═══════════════════════════════════════ */}
{logOpen && (

[14:32:01]{" "} OK Stage 2 completed — 3 characters, 5 scenes

[14:32:03]{" "} INFO Starting Stage 3 — Banana Pro batch (8 images)

[14:32:15]{" "} OK{" "} character_001_front.jpg generated

[14:32:28]{" "} ERR{" "} character_004 — Banana Pro 429, retrying in 4s

[14:32:32]{" "} WARN{" "} character_004 — retry 2/3

)}
{/* ═══════════════════════════════════════ 11. MODAL (Confirm Dialog) ═══════════════════════════════════════ */}
{/* Overlay simulation */}

{t.regenTitle}

{t.regenDesc}

{/* ═══════════════════════════════════════ 12. FORM ELEMENTS ═══════════════════════════════════════ */}
{/* Label + Input */}
{/* Custom Select */}
{selectOpen && (
{t.selectOptions.map((opt) => ( ))}
)}
{/* Textarea */}