'use client'; import { useState } from 'react'; import { FiSearch, FiLoader, FiZap, FiTarget, FiDatabase, FiFileText, FiCheckCircle, FiAlertCircle, FiHelpCircle, FiMinusCircle, FiChevronRight, FiRefreshCw, FiCheck } from 'react-icons/fi'; import type { DiscoveryResult, TechnologyCandidate, DeepDiveResult, Technology, WorkflowStep, StepSearchResult, StepExtractionResult, StepEvaluationResult, TechnologyItem, SearchResultItem, } from './types'; type SearchMode = 'guided' | 'discover'; export default function Home() { const [query, setQuery] = useState(''); const [loading, setLoading] = useState(false); const [loadingStep, setLoadingStep] = useState(''); const [searchMode, setSearchMode] = useState('guided'); // Workflow state const [workflowStep, setWorkflowStep] = useState('input'); // Step results const [searchResult, setSearchResult] = useState(null); const [extractionResult, setExtractionResult] = useState(null); const [evaluationResult, setEvaluationResult] = useState(null); // Selection state for step 3 const [selectedTechIds, setSelectedTechIds] = useState>(new Set()); // Legacy discovery state const [result, setResult] = useState(null); const [selectedCandidate, setSelectedCandidate] = useState(null); // Detail view state const [selectedTechnology, setSelectedTechnology] = useState(null); // Deep dive state (shared) const [deepDiveLoading, setDeepDiveLoading] = useState(false); const [deepDiveResult, setDeepDiveResult] = useState(null); // Reset workflow const resetWorkflow = () => { setWorkflowStep('input'); setSearchResult(null); setExtractionResult(null); setEvaluationResult(null); setSelectedTechIds(new Set()); setSelectedTechnology(null); }; // Step 1: Search const handleStepSearch = async () => { if (!query.trim()) return; setLoading(true); setLoadingStep('Parsing capability need and searching sources...'); resetWorkflow(); try { const response = await fetch('http://localhost:8000/api/match/search', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Search failed'); } const data = await response.json(); if (data.result) { setSearchResult(data.result); setWorkflowStep('search'); } } catch (error) { console.error('Search failed:', error); if (error instanceof TypeError && error.message.includes('fetch')) { alert('Cannot connect to API server. Make sure to run launch.bat first!'); } else { alert(`Search failed: ${error}`); } } finally { setLoading(false); setLoadingStep(''); } }; // Step 2: Extract const handleStepExtract = async () => { if (!searchResult) return; setLoading(true); setLoadingStep('Extracting and grouping technologies...'); try { const response = await fetch('http://localhost:8000/api/match/extract', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ search_id: searchResult.id }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Extraction failed'); } const data = await response.json(); if (data.result) { setExtractionResult(data.result); setWorkflowStep('extract'); // Pre-select all technologies by default setSelectedTechIds(new Set(data.result.technologies.map((t: TechnologyItem) => t.id))); } } catch (error) { console.error('Extraction failed:', error); alert(`Extraction failed: ${error}`); } finally { setLoading(false); setLoadingStep(''); } }; // Step 3: Evaluate const handleStepEvaluate = async () => { if (!extractionResult || selectedTechIds.size === 0) return; setLoading(true); setLoadingStep(`Evaluating ${selectedTechIds.size} technologies against criteria...`); try { const response = await fetch('http://localhost:8000/api/match/evaluate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ extraction_id: extractionResult.id, technology_ids: Array.from(selectedTechIds), }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Evaluation failed'); } const data = await response.json(); if (data.result) { setEvaluationResult(data.result); setWorkflowStep('evaluate'); } } catch (error) { console.error('Evaluation failed:', error); alert(`Evaluation failed: ${error}`); } finally { setLoading(false); setLoadingStep(''); } }; // Legacy discovery const handleDiscover = async () => { if (!query.trim()) return; setLoading(true); setLoadingStep('Starting discovery...'); setResult(null); setSelectedCandidate(null); try { const response = await fetch('http://localhost:8000/api/discover', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Discovery failed'); } const data = await response.json(); if (data.result) { setResult(data.result); } } catch (error) { console.error('Discovery failed:', error); alert(`Discovery failed: ${error}`); } finally { setLoading(false); setLoadingStep(''); } }; const handleDeepDive = async (candidate: TechnologyCandidate) => { if (!candidate || !query) return; setDeepDiveLoading(true); setDeepDiveResult(null); try { const response = await fetch('http://localhost:8000/api/deepdive', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ organization: candidate.organization, technology: candidate.description, gap: query, }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Deep dive failed'); } const data = await response.json(); if (data.result) { setDeepDiveResult(data.result); } } catch (error) { console.error('Deep dive failed:', error); alert(`Deep dive failed: ${error}`); } finally { setDeepDiveLoading(false); } }; const toggleTechSelection = (id: string) => { const newSelected = new Set(selectedTechIds); if (newSelected.has(id)) { newSelected.delete(id); } else { newSelected.add(id); } setSelectedTechIds(newSelected); }; const selectAllTechs = () => { if (extractionResult) { setSelectedTechIds(new Set(extractionResult.technologies.map(t => t.id))); } }; const deselectAllTechs = () => { setSelectedTechIds(new Set()); }; const exampleQueries = [ "Need a technology that improves Space Domain Awareness for objects beyond the diffraction limit", "Looking for autonomous underwater vehicle navigation in GPS-denied environments", "Require hypersonic threat detection and tracking capabilities for missile defense", "Need secure tactical communications in contested electromagnetic environments", ]; return (
{/* Header */}

Technology Scout

Describe your capability need in natural language. TechScout will find technologies that could address it.

{/* Query Input */}
{/* Mode Toggle */}