72 lines
3.0 KiB
TypeScript
72 lines
3.0 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import { Network, Code2, ListChecks, ArrowRight, ChevronRight } from 'lucide-react'
|
|
import { sidebarApi } from '@/api'
|
|
import { Skeleton } from '@/components/ui/Skeleton'
|
|
|
|
export function KnowledgeBaseCards() {
|
|
const navigate = useNavigate()
|
|
const [flowCount, setFlowCount] = useState(0)
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
sidebarApi.getStats()
|
|
.then((stats) => setFlowCount(stats.tree_counts.total))
|
|
.catch(() => {})
|
|
.finally(() => setLoading(false))
|
|
}, [])
|
|
|
|
const items = [
|
|
{ label: 'Flows', value: flowCount, icon: Network, color: '#a78bfa', href: '/trees' },
|
|
{ label: 'Scripts', value: '\u2014', icon: Code2, color: '#2dd4bf', href: '/scripts' },
|
|
{ label: 'Pending Review', value: '\u2014', icon: ListChecks, color: '#fbbf24', href: '/review-queue' },
|
|
]
|
|
|
|
return (
|
|
<div className="card-flat">
|
|
<div
|
|
className="flex items-center justify-between px-5 py-3"
|
|
style={{ borderBottom: '1px solid var(--color-border-default)' }}
|
|
>
|
|
<h3 className="font-heading text-sm font-bold text-foreground">Knowledge Base</h3>
|
|
<button
|
|
onClick={() => navigate('/trees')}
|
|
className="flex items-center gap-1 text-[0.6875rem] text-muted-foreground hover:text-foreground transition-colors"
|
|
>
|
|
Browse <ArrowRight size={10} />
|
|
</button>
|
|
</div>
|
|
<div className="py-1">
|
|
{loading ? Array.from({ length: 3 }).map((_, i) => (
|
|
<div key={i} className="flex items-center gap-3 px-5 py-3" style={{ borderBottom: i < 2 ? '1px solid var(--color-border-default)' : undefined }}>
|
|
<Skeleton className="h-8 w-8 rounded-md shrink-0" />
|
|
<Skeleton className="h-4 flex-1 max-w-24" />
|
|
<Skeleton className="h-5 w-8" />
|
|
</div>
|
|
)) : items.map((item, i) => (
|
|
<button
|
|
key={item.label}
|
|
onClick={() => navigate(item.href)}
|
|
className="flex w-full items-center gap-3 px-5 py-3 text-left hover:bg-[var(--color-bg-card-hover)] transition-colors group"
|
|
style={{
|
|
borderBottom: i < items.length - 1 ? '1px solid var(--color-border-default)' : undefined,
|
|
}}
|
|
>
|
|
<span
|
|
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md"
|
|
style={{ backgroundColor: `${item.color}15` }}
|
|
>
|
|
<item.icon size={15} style={{ color: item.color }} />
|
|
</span>
|
|
<span className="flex-1 text-sm font-medium text-foreground">{item.label}</span>
|
|
<span className="font-heading text-base font-bold text-foreground tabular-nums mr-1">
|
|
{item.value}
|
|
</span>
|
|
<ChevronRight size={14} className="text-muted-foreground opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all" />
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|