import { useEffect, useState, useCallback } from 'react' import { useParams } from 'react-router-dom' import { getTasks } from '../api/project' import type { Task } from '../api/types' import StatusBadge from './StatusBadge' import PipelineStages from './PipelineStages' import Skeleton from './Skeleton' const ASSET_TYPE_LABELS: Record = { sprite: '精灵', background: '背景', ui: 'UI', animation: '动画', } function formatRelativeTime(dateStr: string): string { const now = Date.now() const then = new Date(dateStr).getTime() const diff = now - then const minutes = Math.floor(diff / 60000) if (minutes < 1) return '刚刚' if (minutes < 60) return `${minutes}分钟前` const hours = Math.floor(minutes / 60) if (hours < 24) return `${hours}小时前` const days = Math.floor(hours / 24) return `${days}天前` } export default function TaskListPanel() { const { projectId = '' } = useParams() const [tasks, setTasks] = useState([]) const [loading, setLoading] = useState(true) const fetchTasks = useCallback(async () => { if (!projectId) return try { const data = await getTasks(projectId) setTasks(data) } finally { setLoading(false) } }, [projectId]) useEffect(() => { fetchTasks() const timer = setInterval(fetchTasks, 15000) return () => clearInterval(timer) }, [fetchTasks]) if (loading) { return (
) } return (

任务列表 ({tasks.length})

{tasks.length === 0 ? (

暂无任务

) : ( tasks.map(task => ( { if (task.status === 'completed') (e.currentTarget as HTMLElement).style.background = 'var(--accent-dim)' }} onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = '' }} >
{ASSET_TYPE_LABELS[task.assetType] || task.assetType}

{task.prompt}

{formatRelativeTime(task.createdAt)} {task.progress !== undefined && task.status === 'running' && ( {task.progress}% )}
)) )}
) }