Gemma4-WebGPU / src /components /ResultPanel.tsx
BryanBradfo's picture
Gemma 4 multimodal WebGPU detection Space
576d07a
Raw
History Blame Contribute Delete
1.94 kB
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>
);
}