codev / desktop /src /components /tasks /TaskList.tsx
chenbhao's picture
feat: desktop
1f21206
Raw
History Blame
1.55 kB
import { useState } from 'react'
import type { CronTask } from '../../types/task'
import { TaskRow } from './TaskRow'
import { useTranslation } from '../../i18n'
type Props = {
tasks: CronTask[]
}
export function TaskList({ tasks }: Props) {
const t = useTranslation()
const enabledCount = tasks.filter((task) => task.enabled).length
const [expandedLogsId, setExpandedLogsId] = useState<string | null>(null)
return (
<div>
{/* Stats */}
<div className="grid grid-cols-3 gap-4 mb-6">
<StatCard label={t('tasks.totalTasks')} value={String(tasks.length)} />
<StatCard label={t('tasks.active')} value={String(enabledCount)} />
<StatCard label={t('tasks.disabled')} value={String(tasks.length - enabledCount)} />
</div>
{/* Task rows — accordion: only one logs panel open at a time */}
<div className="flex flex-col">
{tasks.map((task) => (
<TaskRow
key={task.id}
task={task}
showLogs={expandedLogsId === task.id}
onToggleLogs={() => setExpandedLogsId(expandedLogsId === task.id ? null : task.id)}
/>
))}
</div>
</div>
)
}
function StatCard({ label, value }: { label: string; value: string }) {
return (
<div className="px-4 py-3 rounded-[var(--radius-lg)] bg-[var(--color-surface-info)]">
<div className="text-2xl font-bold text-[var(--color-text-primary)]">{value}</div>
<div className="text-xs text-[var(--color-text-secondary)]">{label}</div>
</div>
)
}