refactor(research): replace hardcoded data with TanStack Query API integration
This commit is contained in:
parent
999f0aab4f
commit
cadd965796
1 changed files with 54 additions and 54 deletions
|
|
@ -1,74 +1,49 @@
|
|||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { IconBook, IconDatabase, IconCircleCheck, IconSparkles, IconShield, IconActivity, IconCpu, IconFileText, IconSettings } from "@tabler/icons-react"
|
||||
import { ResearchAgents } from "./research-agents"
|
||||
import { ResearchGraph } from "./research-graph"
|
||||
import { ResearchConfig } from "./research-config"
|
||||
import { ResearchReports } from "./research-reports"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { listResearchAgents, listResearchGraph, listResearchReports, ResearchAgent, ResearchNode, ResearchReport } from "@/api/research"
|
||||
|
||||
interface ResearchAgent {
|
||||
id: string
|
||||
name: string
|
||||
icon: React.ComponentType<{ className?: string }>
|
||||
active: boolean
|
||||
progress: number
|
||||
ram: string
|
||||
const agentIcons: Record<string, React.ComponentType<{ className?: string }>> = {
|
||||
literature: IconBook,
|
||||
extractor: IconDatabase,
|
||||
validator: IconCircleCheck,
|
||||
synthesizer: IconSparkles,
|
||||
}
|
||||
|
||||
interface ResearchReport {
|
||||
id: string
|
||||
title: string
|
||||
status: "in-progress" | "complete"
|
||||
timestamp: string
|
||||
pages?: number
|
||||
words?: number
|
||||
function mapAgentIcon(type: string): React.ComponentType<{ className?: string }> {
|
||||
return agentIcons[type] || IconBook
|
||||
}
|
||||
|
||||
interface ResearchNode {
|
||||
name: string
|
||||
abbr: string
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
|
||||
const defaultAgents: ResearchAgent[] = [
|
||||
{ id: "literature", name: "Literature Analyzer", icon: IconBook, active: true, progress: 94, ram: "2.4GB" },
|
||||
{ id: "extractor", name: "Data Extractor", icon: IconDatabase, active: true, progress: 87, ram: "1.8GB" },
|
||||
{ id: "validator", name: "Fact Validator", icon: IconCircleCheck, active: true, progress: 76, ram: "1.2GB" },
|
||||
{ id: "synthesizer", name: "Synthesizer", icon: IconSparkles, active: false, progress: 65, ram: "0.9GB" },
|
||||
]
|
||||
|
||||
const defaultReports: ResearchReport[] = [
|
||||
{ id: "1", title: "AI trends 2026", status: "in-progress", timestamp: "2 min ago", pages: 24, words: 7200 },
|
||||
{ id: "2", title: "Quantum computing", status: "complete", timestamp: "1 hour ago", pages: 45, words: 13500 },
|
||||
]
|
||||
|
||||
const defaultNodes: ResearchNode[] = [
|
||||
{ name: "Neural Networks", abbr: "NN", x: 150, y: 80 },
|
||||
{ name: "Transformers", abbr: "TR", x: 150, y: 120 },
|
||||
{ name: "LLM Optimization", abbr: "LO", x: 150, y: 160 },
|
||||
{ name: "Edge Computing", abbr: "EC", x: 150, y: 210 },
|
||||
{ name: "Multi-Agent Systems", abbr: "MA", x: 150, y: 260 },
|
||||
{ name: "Vision Models", abbr: "VM", x: 650, y: 100 },
|
||||
{ name: "RAG Systems", abbr: "RA", x: 650, y: 200 },
|
||||
{ name: "Knowledge Graphs", abbr: "KG", x: 400, y: 150 },
|
||||
{ name: "Agent Architecture", abbr: "AA", x: 400, y: 180 },
|
||||
{ name: "Fine-tuning Methods", abbr: "FT", x: 400, y: 250 },
|
||||
]
|
||||
|
||||
export function ResearchPage() {
|
||||
const [agents, setAgents] = useState<ResearchAgent[]>(defaultAgents)
|
||||
const [researchType, setResearchType] = useState<string>("1.5")
|
||||
const [depth, setDepth] = useState<string>("1.5")
|
||||
const [restrictToGraph, setRestrictToGraph] = useState(false)
|
||||
const [selectedNodes, setSelectedNodes] = useState<Set<string>>(new Set())
|
||||
|
||||
const { data: agents = [], isLoading: agentsLoading, error: agentsError } = useQuery({
|
||||
queryKey: ["researchAgents"],
|
||||
queryFn: listResearchAgents,
|
||||
})
|
||||
|
||||
const { data: nodes = [], isLoading: nodesLoading, error: nodesError } = useQuery({
|
||||
queryKey: ["researchGraph"],
|
||||
queryFn: listResearchGraph,
|
||||
})
|
||||
|
||||
const { data: reports = [], isLoading: reportsLoading, error: reportsError } = useQuery({
|
||||
queryKey: ["researchReports"],
|
||||
queryFn: listResearchReports,
|
||||
})
|
||||
|
||||
const handleToggleAgent = (id: string) => {
|
||||
setAgents(agents.map(agent =>
|
||||
agent.id === id ? { ...agent, active: !agent.active } : agent
|
||||
))
|
||||
console.log("Toggle agent:", id)
|
||||
}
|
||||
|
||||
const activeAgents = agents.filter(a => a.active)
|
||||
|
|
@ -76,6 +51,31 @@ export function ResearchPage() {
|
|||
? Math.round(activeAgents.reduce((sum, a) => sum + a.progress, 0) / activeAgents.length)
|
||||
: 0
|
||||
|
||||
const completedReports = reports.filter(r => r.status === "complete")
|
||||
|
||||
const isLoading = agentsLoading || nodesLoading || reportsLoading
|
||||
const hasError = agentsError || nodesError || reportsError
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="relative min-h-screen bg-[#050505] overflow-hidden">
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="text-[#F27D26] animate-pulse">Loading research data...</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (hasError) {
|
||||
return (
|
||||
<div className="relative min-h-screen bg-[#050505] overflow-hidden">
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="text-red-500">Failed to load research data</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative min-h-screen bg-[#050505] overflow-hidden">
|
||||
{/* Ghost Background Typography */}
|
||||
|
|
@ -116,7 +116,7 @@ export function ResearchPage() {
|
|||
<div className="flex items-center gap-2">
|
||||
<IconFileText className="w-4 h-4 text-white/40" />
|
||||
<span className="text-xs text-white/60">Reports:</span>
|
||||
<span className="text-sm font-semibold text-[#F2F2F2]">{defaultReports.filter(r => r.status === "complete").length}</span>
|
||||
<span className="text-sm font-semibold text-[#F2F2F2]">{completedReports.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -135,7 +135,7 @@ export function ResearchPage() {
|
|||
{/* Center Column - Graph */}
|
||||
<div className="flex-1 bg-[#050505] relative">
|
||||
<ResearchGraph
|
||||
nodes={defaultNodes}
|
||||
nodes={nodes}
|
||||
selectedNodes={selectedNodes}
|
||||
onNodeToggle={(name: string) => {
|
||||
setSelectedNodes(prev => {
|
||||
|
|
@ -162,7 +162,7 @@ export function ResearchPage() {
|
|||
setRestrictToGraph={setRestrictToGraph}
|
||||
/>
|
||||
<ResearchReports
|
||||
reports={defaultReports}
|
||||
reports={reports}
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
|
|
@ -173,7 +173,7 @@ export function ResearchPage() {
|
|||
<div className="flex items-center gap-4">
|
||||
<span>PicoClaw Research Engine v2.4.1</span>
|
||||
<span className="text-white/20">|</span>
|
||||
<span>Nodes: {defaultNodes.length}</span>
|
||||
<span>Nodes: {nodes.length}</span>
|
||||
<span className="text-white/20">|</span>
|
||||
<span>Agents: {activeAgents.length} active</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue