Files
kamidso-front/src/features/assistant/components/TaskPlanCard.tsx
T

77 lines
2.6 KiB
TypeScript

import { CheckCircle2, Circle, Loader2, MinusCircle } from 'lucide-react'
import { useState } from 'react'
import type { TaskItem } from '../types/chat'
function StatusIcon({ status }: { status: TaskItem['status'] }) {
if (status === 'completed') return <CheckCircle2 className="h-4 w-4 shrink-0 text-success" />
if (status === 'in_progress') return <Loader2 className="h-4 w-4 shrink-0 animate-spin text-accent" />
if (status === 'cancelled') return <MinusCircle className="h-4 w-4 shrink-0 text-ink-subtle" />
return <Circle className="h-4 w-4 shrink-0 text-ink-subtle" />
}
export function visibleTasks(tasks: TaskItem[]): TaskItem[] {
return tasks.filter((task) => task.status !== 'cancelled')
}
export function TaskPlanList({
tasks,
compact = false,
}: {
tasks: TaskItem[]
compact?: boolean
}) {
const items = visibleTasks(tasks)
if (!items.length) return null
return (
<ol className={compact ? 'space-y-1.5' : 'space-y-1'}>
{items.map((task, index) => {
const active = task.status === 'in_progress'
const done = task.status === 'completed'
return (
<li
key={`${index}-${task.content}`}
className={`flex items-start gap-2 ${
active ? 'text-ink' : done ? 'text-ink-muted' : 'text-ink-subtle'
}`}
>
<span className="mt-0.5">
<StatusIcon status={task.status} />
</span>
<span className={`${compact ? 'text-[13px] leading-6' : 'text-sm'} ${done ? 'line-through decoration-line' : ''}`}>
{task.content}
</span>
</li>
)
})}
</ol>
)
}
export function TaskPlanCard({ tasks }: { tasks: TaskItem[] }) {
const [collapsed, setCollapsed] = useState(false)
const items = visibleTasks(tasks)
if (!items.length) return null
const done = items.filter((task) => task.status === 'completed').length
return (
<div className="my-3 overflow-hidden rounded-xl border border-line bg-panel">
<button
type="button"
onClick={() => setCollapsed((value) => !value)}
className="flex w-full items-center justify-between px-3 py-2.5 text-sm font-medium text-ink hover:bg-surface-subtle"
>
<span>
برنامه کار ({done}/{items.length})
</span>
<span className="text-xs text-ink-muted">{collapsed ? 'نمایش' : 'پنهان'}</span>
</button>
{!collapsed ? (
<div className="border-t border-line px-3 py-2">
<TaskPlanList tasks={items} />
</div>
) : null}
</div>
)
}