Spaces:
Running
Running
| import { Loader2 } from "lucide-react"; | |
| import type { DetectionResult } from "../hooks/LLMContext"; | |
| interface ResultPanelProps { | |
| result: DetectionResult | null; | |
| isGenerating: boolean; | |
| tps: number; | |
| } | |
| export function ResultPanel({ result, isGenerating, tps }: ResultPanelProps) { | |
| if (!result && !isGenerating) return null; | |
| return ( | |
| <div className="rounded-2xl border border-white/10 bg-white/5 p-4 sm:p-5"> | |
| <div className="flex items-center justify-between mb-3"> | |
| <h3 className="text-sm font-medium text-white/60"> | |
| {isGenerating ? ( | |
| <span className="detection-shimmer">Analyzing image...</span> | |
| ) : ( | |
| `${result?.detections.length ?? 0} object(s) detected` | |
| )} | |
| </h3> | |
| {tps > 0 && ( | |
| <span className="text-xs text-white/50 font-mono"> | |
| {tps} tok/s | |
| </span> | |
| )} | |
| </div> | |
| {isGenerating && !result?.text && ( | |
| <div className="flex items-center gap-2 text-[#1a73e8]"> | |
| <Loader2 className="h-4 w-4 animate-spin" /> | |
| <span className="text-sm">Processing...</span> | |
| </div> | |
| )} | |
| {result?.text && ( | |
| <pre className="text-sm text-white/80 whitespace-pre-wrap break-words font-mono leading-relaxed bg-black/40 rounded-xl p-3 max-h-[200px] overflow-y-auto"> | |
| {result.text} | |
| </pre> | |
| )} | |
| {result && result.detections.length > 0 && !isGenerating && ( | |
| <div className="mt-3 flex flex-wrap gap-2"> | |
| {result.detections.map((det, i) => ( | |
| <span | |
| key={i} | |
| className="inline-flex items-center gap-1.5 rounded-lg bg-[#1a73e8]/15 border border-[#1a73e8]/40 px-2.5 py-1 text-xs font-medium text-[#8bb4f0]" | |
| > | |
| <span className="w-2 h-2 rounded-full bg-[#1a73e8]" /> | |
| {det.label} | |
| </span> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |