Skip to content

Feature/blog cms admin UI#11

Open
vH192Hv wants to merge 10 commits into
floatboatai:mainfrom
vH192Hv:feature/blog-cms-admin-ui
Open

Feature/blog cms admin UI#11
vH192Hv wants to merge 10 commits into
floatboatai:mainfrom
vH192Hv:feature/blog-cms-admin-ui

Conversation

@vH192Hv

@vH192Hv vH192Hv commented Jul 11, 2026

Copy link
Copy Markdown

设计方案

页面路由

路由 页面 说明
/admin/blog BlogPostsPage 帖子列表(分页/过滤/搜索)
/admin/blog/new PostEditorPage 创建新帖子
/admin/blog/:id/edit PostEditorPage 编辑已有帖子

组件架构

BlogPostsPage
  ├── PostStatusBadge          # 彩色状态标签 (DRAFT/PUBLISHED/ARCHIVED)
  ├── 搜索栏 (useDebounce, 300ms)
  ├── 状态过滤器 + 标签过滤器
  ├── 帖子表格 (title, author, status, tags, date, actions)
  └── 分页控件

PostEditorPage
  ├── Breadcrumb
  └── PostForm
        ├── Title (slugg 自动生成)
        ├── Slug (可手动编辑)
        ├── Content (Markdown textarea)
        ├── Excerpt
        ├── Cover Image URL
        ├── TagSelector ──── 标签多选 + 内联创建
        ├── Status ──── 分段控件 (按转换规则限可用选项)
        └── Actions ──── Delete / Cancel / Save

关键实现细节

BlogPostsPage:

  • 搜索防抖 (useDebounce, 300ms),与 UsersTable 一致
  • 空状态区分:"数据库为空" vs "无匹配过滤器"
  • wasp/client/operations 导入操作函数
  • 接收 user: AuthUser prop,传入 DefaultLayout

PostEditorPage:

  • 通过路由 param :id 区分 create/edit 模式
  • useQuery(getPost, { enabled: isEditing }) 条件加载
  • 所有导航(save/cancel/delete)由页面级回调控制
  • handleCreateTag 捕获错误并打印日志

PostForm:

  • generateSlug()utils.ts 导入(浏览器安全)
  • getAllowedTransitions() 限制状态选项
  • onCancel/onDelete 回调 → 父组件控制导航
  • 表单级字段校验 (title, slug, content required)

TagSelector:

  • 已选标签: 主色背景 + X 移除按钮
  • 未选标签: 灰色背景 + ✓ 添加图标
  • 新建标签: 文本输入 + Enter/Add 按钮
  • 创建后自动选中新标签

PostStatusBadge:

  • DRAFT: 黄色, PUBLISHED: 绿色, ARCHIVED: 灰色
  • 使用 shadcn/ui 语义色彩 token (bg-*-100, text-*-800)
  • 支持 dark mode

侧边栏导航

在 admin sidebar MENU 区添加 "Blog" 导航项(FileText 图标),位于 Users 和 Settings 之间。

执行方案

  • 创建 PostStatusBadge.tsx 组件
  • 创建 TagSelector.tsx 组件
  • 创建 PostForm.tsx 共享表单组件
  • 创建 BlogPostsPage.tsx 列表页
  • 创建 PostEditorPage.tsx 编辑页
  • admin.wasp.ts 注册 3 条路由
  • Sidebar.tsx 添加 Blog 导航项

文件变更

文件 操作 行数
template/app/src/blog-cms/BlogPostsPage.tsx 新增 185
template/app/src/blog-cms/PostEditorPage.tsx 新增 128
template/app/src/blog-cms/components/PostForm.tsx 新增 245
template/app/src/blog-cms/components/TagSelector.tsx 新增 124
template/app/src/blog-cms/components/PostStatusBadge.tsx 新增 24
template/app/src/admin/admin.wasp.ts 修改 +17
template/app/src/admin/layout/Sidebar.tsx 修改 +21

🔽 依赖 PR2 (operations) — 合并顺序第 3(与 PR4 并行)

vH192Hv and others added 10 commits July 9, 2026 21:30
- Add Post model with title, slug, content, excerpt, coverImage, status, timestamps
- Add Tag model with name and slug
- Add PostTag join table for many-to-many relationship
- Add PostStatus enum (DRAFT, PUBLISHED, ARCHIVED)
- Add posts relation to User model

Co-Authored-By: Claude <noreply@anthropic.com>
- Add seedBlogPosts function with sample posts and tags
- Register seed in main.wasp.ts db.seeds array

Co-Authored-By: Claude <noreply@anthropic.com>
- Define getAllPosts, getPost, getPostBySlug, getPublishedPosts queries
- Define createPost, updatePost, deletePost actions
- Define getAllTags, createTag, deleteTag tag operations
- Register blogCmsSpec in main.wasp.ts

Co-Authored-By: Claude <noreply@anthropic.com>
- Add isValidSlug, generateSlug with regex format + length checks
- Add ALLOWED_TRANSITIONS map and transition validation helpers
- File is browser+server safe (no wasp/server imports)

Co-Authored-By: Claude <noreply@anthropic.com>
…rmissions)

- Post queries: getAllPosts (admin, paginated, filters), getPost (admin, by ID),
  getPostBySlug (public, PUBLISHED only), getPublishedPosts (public, paginated)
- Post mutations: createPost (slug gen/validate, status validation),
  updatePost (status transitions, tag replacement, publishedAt mgmt),
  deletePost (by ID with existence check)
- Tag operations: getAllTags (with post count), createTag (name/slug uniqueness),
  deleteTag (cascade removes PostTag entries)
- Permission guard: requireAdmin on all mutating + admin-read operations
- Slug helpers imported from shared utils.ts
- Status transitions validated via isAllowedTransition from utils.ts

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…tion

Co-Authored-By: Claude <noreply@anthropic.com>
- Auto-generates slug from title (overridable), imports from shared utils.ts
- Content field as Markdown textarea
- TagSelector integration for multi-select tags
- Status segmented control with valid transitions from getAllowedTransitions()
- onCancel/onDelete callbacks for parent-controlled navigation
- Delete confirmation dialog
- Field-level validation errors

Co-Authored-By: Claude <noreply@anthropic.com>
- BlogPostsPage: table view with pagination, search (debounced), status/tag filters
- PostEditorPage: create/edit form with tag management, navigation callbacks
- Both use DefaultLayout+user prop and Breadcrumb per admin conventions
- Imports operations from wasp/client/operations

Co-Authored-By: Claude <noreply@anthropic.com>
- Add AdminBlogRoute (/admin/blog) for post list
- Add AdminBlogNewRoute (/admin/blog/new) for creating posts
- Add AdminBlogEditRoute (/admin/blog/:id/edit) for editing posts
- Add Blog nav item with FileText icon in admin sidebar

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant