"use client" import { ArrowRight,CheckCircle2, Circle, Loader2, Microscope, Search, AlertCircle } from "lucide-react" import * as React from "react" import { PageHeader, SectionHeader } from "@/components/page-header" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Tabs, TabsContent,TabsList, TabsTrigger } from "@/components/ui/tabs" import { Textarea } from "@/components/ui/textarea" const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"; interface SearchResult { id: string; score: number; smiles: string; target_seq: string; label: number; affinity_class: string; } export default function DiscoveryPage() { const [query, setQuery] = React.useState("") const [searchType, setSearchType] = React.useState("Similarity") const [isSearching, setIsSearching] = React.useState(false) const [step, setStep] = React.useState(0) const [results, setResults] = React.useState([]) const [error, setError] = React.useState(null) // Map UI search type to API type const getApiType = (uiType: string, query: string): string => { // If it looks like SMILES (contains chemistry chars), use drug encoding const looksLikeSmiles = /^[A-Za-z0-9@+\-\[\]\(\)\\\/=#$.]+$/.test(query.trim()) // If it looks like protein sequence (all caps amino acids) const looksLikeProtein = /^[ACDEFGHIKLMNPQRSTVWY]+$/i.test(query.trim()) && query.length > 20 if (uiType === "Similarity" || uiType === "Binding Affinity") { if (looksLikeSmiles && !looksLikeProtein) return "drug" if (looksLikeProtein) return "target" return "text" // Fallback to text search } return "text" } const handleSearch = async () => { if (!query.trim()) return; setIsSearching(true) setStep(1) setError(null) setResults([]) try { // Step 1: Input received setStep(1) // Step 2: Determine type and encode await new Promise(r => setTimeout(r, 300)) setStep(2) const apiType = getApiType(searchType, query) // Step 3: Actually search Qdrant via our API const response = await fetch(`${API_BASE}/api/search`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: query.trim(), type: apiType, limit: 10 }) }); setStep(3) if (!response.ok) { const errData = await response.json().catch(() => ({})); throw new Error(errData.detail || `API error: ${response.status}`); } const data = await response.json(); // Step 4: Process results await new Promise(r => setTimeout(r, 200)) setStep(4) setResults(data.results || []) } catch (err) { setError(err instanceof Error ? err.message : 'Search failed'); setStep(0) } finally { setIsSearching(false) } } const steps = [ { name: "Input", status: step > 0 ? "done" : "active" }, { name: "Encode", status: step > 1 ? "done" : (step === 1 ? "active" : "pending") }, { name: "Search", status: step > 2 ? "done" : (step === 2 ? "active" : "pending") }, { name: "Predict", status: step > 3 ? "done" : (step === 3 ? "active" : "pending") }, { name: "Results", status: step === 4 ? "active" : "pending" }, ] return (
} />
Search Query