diff --git a/src/frontend/src/pages/TaskBoard.tsx b/src/frontend/src/pages/TaskBoard.tsx
new file mode 100644
index 0000000..138f554
--- /dev/null
+++ b/src/frontend/src/pages/TaskBoard.tsx
@@ -0,0 +1,74 @@
+// 任务看板页面
+
+import React from 'react';
+import { useTasks } from '../hooks/useApi';
+import type { Task } from '../types';
+
+interface Props {
+ projectId: string | null;
+ onSelectTask: (task: Task) => void;
+}
+
+const STATUS_ORDER = ['pending', 'working', 'review', 'blocked', 'done', 'failed'];
+
+export function TaskBoard({ projectId, onSelectTask }: Props) {
+ const { tasks, loading, error, refresh } = useTasks(projectId);
+
+ if (!projectId) {
+ return
请选择一个项目
;
+ }
+
+ if (loading) return 加载中...
;
+ if (error) return 加载失败: {error}
;
+
+ // 按状态分组
+ const grouped: Record = {};
+ for (const task of tasks) {
+ const status = task.status || 'pending';
+ if (!grouped[status]) grouped[status] = [];
+ grouped[status].push(task);
+ }
+
+ return (
+
+
+
任务看板
+
+
+
+ {STATUS_ORDER.map(status => {
+ const statusTasks = grouped[status] || [];
+ if (statusTasks.length === 0) return null;
+ return (
+
+
+ {status} ({statusTasks.length})
+
+
+ {statusTasks.map(task => (
+
onSelectTask(task)}
+ >
+
{task.title}
+
+ {status}
+ {task.assignee && 👤 {task.assignee}}
+ {task.risk_level && ⚠️ {task.risk_level}}
+
+
+ ))}
+
+
+ );
+ })}
+
+ {tasks.length === 0 && (
+
+
暂无任务。通过 API 或 CLI 创建任务。
+
+ )}
+
+ );
+}