refactor: 前端重构为项目+任务双核心模型
- 新增 HomePage 项目画廊页,支持新建/删除工程 - 新增 ProjectDetailPage 三栏工作台(配置+生成+任务列表) - 新增 CustomTagsEditor 支持自定义风格标签(custom: 前缀存入 kvPairs) - 重构 project store 为 draft/commit 模式,支持手动保存/取消 - 新增 projectList store 管理工程列表 - 扩展 mock.ts 为多工程数据结构 - 扩展 api/project.ts 新增项目 CRUD API(mock-gated) - 简化 ResultPage,仅展示素材预览 - 删除 GeneratePage、ProjectPage 及未使用的 hooks - 更新 docs/ 文档(frontend.md、api.md、style-keys.md、_index.md)
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useProjectListStore } from '../stores/projectList'
|
||||
import { useToastStore } from '../stores/toast'
|
||||
import ProjectCard from '../components/ProjectCard'
|
||||
import CreateProjectModal from '../components/CreateProjectModal'
|
||||
import EmptyState from '../components/EmptyState'
|
||||
import Skeleton from '../components/Skeleton'
|
||||
|
||||
export default function HomePage() {
|
||||
const { projects, loading, loadProjects, createProject, deleteProject } =
|
||||
useProjectListStore()
|
||||
const addToast = useToastStore(s => s.addToast)
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
loadProjects()
|
||||
}, [loadProjects])
|
||||
|
||||
const handleCreate = async (name: string, style: Record<string, string>) => {
|
||||
await createProject(name, style)
|
||||
addToast({ type: 'success', message: '工程创建成功' })
|
||||
}
|
||||
|
||||
const handleDelete = async (projectId: string) => {
|
||||
if (!confirm('确定删除该工程?所有任务和素材将被永久删除。')) return
|
||||
await deleteProject(projectId)
|
||||
addToast({ type: 'success', message: '工程已删除' })
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="container page-enter" style={{ paddingTop: 32 }}>
|
||||
<Skeleton variant="card" />
|
||||
<div style={{ height: 16 }} />
|
||||
<Skeleton variant="card" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container page-enter" style={{ paddingTop: 32, paddingBottom: 32 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
|
||||
<h1 style={{ fontSize: 22 }}>我的工程</h1>
|
||||
<button className="btn-primary" onClick={() => setModalOpen(true)}>
|
||||
新建工程
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{projects.length === 0 ? (
|
||||
<EmptyState
|
||||
title="还没有工程"
|
||||
description="创建你的第一个工程,开始生成游戏素材"
|
||||
action={{ label: '新建工程', onClick: () => setModalOpen(true) }}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))',
|
||||
gap: 16,
|
||||
}}
|
||||
>
|
||||
{projects.map(project => (
|
||||
<ProjectCard
|
||||
key={project.id}
|
||||
project={project}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CreateProjectModal
|
||||
open={modalOpen}
|
||||
onClose={() => setModalOpen(false)}
|
||||
onSubmit={handleCreate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user