| 'use client' |
|
|
| import { useEffect, useState } from 'react' |
| import { Sidebar } from '@/components/sidebar' |
| import { api, type Tool } from '@/lib/api' |
| import { Search, Play } from 'lucide-react' |
|
|
| export default function ToolsPage() { |
| const [tools, setTools] = useState<Tool[]>([]) |
| const [loading, setLoading] = useState(true) |
| const [search, setSearch] = useState('') |
|
|
| useEffect(() => { |
| api.get<Tool[]>('/api/tools') |
| .then((data) => { setTools(data); setLoading(false) }) |
| .catch(() => setLoading(false)) |
| }, []) |
|
|
| const filtered = tools.filter((t) => |
| !search || t.name.toLowerCase().includes(search.toLowerCase()) || t.description.toLowerCase().includes(search.toLowerCase()) |
| ) |
|
|
| return ( |
| <div className="flex min-h-screen"> |
| <Sidebar /> |
| <main className="flex-1 flex flex-col"> |
| <header className="h-14 bg-bg-secondary border-b border-border flex items-center px-6 justify-between"> |
| <h1 className="text-base font-medium">Tools</h1> |
| <div className="relative"> |
| <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-text-dim" /> |
| <input className="pl-9 pr-4 py-1.5 bg-bg-tertiary border border-border rounded-lg text-sm text-text-primary placeholder:text-text-dim focus:outline-none focus:border-accent-cyan w-64" placeholder="Search tools..." value={search} onChange={(e) => setSearch(e.target.value)} /> |
| </div> |
| </header> |
| <div className="flex-1 p-6 overflow-auto"> |
| {loading ? ( |
| <div className="space-y-2">{Array.from({ length: 10 }).map((_, i) => <div key={i} className="bg-bg-tertiary border border-border rounded-lg p-4 animate-pulse"><div className="h-3 bg-bg-hover rounded w-32 mb-2" /><div className="h-2 bg-bg-hover rounded w-full" /></div>)}</div> |
| ) : filtered.length === 0 ? ( |
| <div className="text-center py-20"><p className="text-text-muted">No tools found</p></div> |
| ) : ( |
| <div className="space-y-2"> |
| {filtered.map((t) => ( |
| <div key={t.id} className="bg-bg-tertiary border border-border rounded-lg p-4 flex items-center justify-between hover:border-border-focus transition-colors"> |
| <div className="flex items-center gap-4"> |
| <div className="w-8 h-8 bg-bg-secondary border border-border rounded-lg flex items-center justify-center"> |
| <Play className="w-3.5 h-3.5 text-text-muted" /> |
| </div> |
| <div> |
| <p className="text-sm font-medium">{t.name}</p> |
| <p className="text-xs text-text-muted">{t.description}</p> |
| </div> |
| </div> |
| <div className="flex items-center gap-3"> |
| <span className="text-[11px] bg-bg-secondary border border-border px-2 py-0.5 rounded text-text-muted">{t.integration_id}</span> |
| <span className="text-[11px] text-text-dim">{t.category}</span> |
| </div> |
| </div> |
| ))} |
| </div> |
| )} |
| </div> |
| </main> |
| </div> |
| ) |
| } |