feat: granular performance tracking and cache hit indicators for AI scans
This commit is contained in:
@@ -35,7 +35,14 @@ export default function ScanAndTasteFlow({ isOpen, onClose, imageFile }: ScanAnd
|
||||
const { locale } = useI18n();
|
||||
const supabase = createClient();
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
const [perfMetrics, setPerfMetrics] = useState<{ comp: number; ai: number; prep: number } | null>(null);
|
||||
const [perfMetrics, setPerfMetrics] = useState<{
|
||||
comp: number;
|
||||
aiTotal: number;
|
||||
aiApi: number;
|
||||
aiParse: number;
|
||||
uploadSize: number;
|
||||
prep: number
|
||||
} | null>(null);
|
||||
|
||||
// Admin Check
|
||||
useEffect(() => {
|
||||
@@ -107,7 +114,10 @@ export default function ScanAndTasteFlow({ isOpen, onClose, imageFile }: ScanAnd
|
||||
if (isAdmin) {
|
||||
setPerfMetrics({
|
||||
comp: endComp - startComp,
|
||||
ai: endAi - startAi,
|
||||
aiTotal: endAi - startAi,
|
||||
aiApi: result.perf?.apiDuration || 0,
|
||||
aiParse: result.perf?.parseDuration || 0,
|
||||
uploadSize: result.perf?.uploadSize || 0,
|
||||
prep: endPrep - startPrep
|
||||
});
|
||||
}
|
||||
@@ -228,18 +238,32 @@ export default function ScanAndTasteFlow({ isOpen, onClose, imageFile }: ScanAnd
|
||||
</motion.div>
|
||||
|
||||
{isAdmin && perfMetrics && (
|
||||
<div className="mt-8 p-4 bg-black/40 backdrop-blur-md rounded-2xl border border-orange-500/20 text-[10px] font-mono text-zinc-400 animate-in fade-in slide-in-from-bottom-2">
|
||||
<div className="grid grid-cols-3 gap-4 text-center">
|
||||
<div className="mt-8 p-6 bg-zinc-950/80 backdrop-blur-xl rounded-3xl border border-orange-500/20 text-[10px] font-mono text-zinc-400 animate-in fade-in slide-in-from-bottom-4 shadow-2xl">
|
||||
<div className="grid grid-cols-3 gap-6 text-center">
|
||||
<div>
|
||||
<p className="text-zinc-500 mb-1 uppercase tracking-widest text-[8px]">Comp</p>
|
||||
<p className="text-zinc-500 mb-2 uppercase tracking-widest text-[8px]">Client</p>
|
||||
<p className="text-orange-500 font-bold">{perfMetrics.comp.toFixed(0)}ms</p>
|
||||
<p className="text-[8px] opacity-40 mt-1">{(perfMetrics.uploadSize / 1024).toFixed(0)} KB</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-zinc-500 mb-1 uppercase tracking-widest text-[8px]">AI</p>
|
||||
<p className="text-orange-500 font-bold">{perfMetrics.ai.toFixed(0)}ms</p>
|
||||
<p className="text-zinc-500 mb-2 uppercase tracking-widest text-[8px]">AI Engine</p>
|
||||
{perfMetrics.aiApi === 0 ? (
|
||||
<div className="flex flex-col items-center">
|
||||
<p className="text-green-500 font-bold tracking-tighter">CACHE HIT</p>
|
||||
<p className="text-[7px] opacity-40 mt-1">DB RESULTS</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-orange-500 font-bold">{perfMetrics.aiTotal.toFixed(0)}ms</p>
|
||||
<div className="flex flex-col gap-0.5 mt-1 text-[7px] opacity-60">
|
||||
<span>API: {perfMetrics.aiApi.toFixed(0)}ms</span>
|
||||
<span>Parse: {perfMetrics.aiParse.toFixed(0)}ms</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-zinc-500 mb-1 uppercase tracking-widest text-[8px]">Prep</p>
|
||||
<p className="text-zinc-500 mb-2 uppercase tracking-widest text-[8px]">App Logic</p>
|
||||
<p className="text-orange-500 font-bold">{perfMetrics.prep.toFixed(0)}ms</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -289,14 +313,29 @@ export default function ScanAndTasteFlow({ isOpen, onClose, imageFile }: ScanAnd
|
||||
activeSessionId={activeSession?.id}
|
||||
/>
|
||||
{isAdmin && perfMetrics && (
|
||||
<div className="absolute top-24 left-6 z-50 p-2 bg-black/60 backdrop-blur-md rounded-lg border border-orange-500/30 text-[9px] font-mono text-white/90 pointer-events-none">
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock size={10} className="text-orange-500" />
|
||||
<span>Comp: {perfMetrics.comp.toFixed(0)}ms</span>
|
||||
<span className="opacity-30">|</span>
|
||||
<span>AI: {perfMetrics.ai.toFixed(0)}ms</span>
|
||||
<span className="opacity-30">|</span>
|
||||
<span>Prep: {perfMetrics.prep.toFixed(0)}ms</span>
|
||||
<div className="absolute top-24 left-6 right-6 z-50 p-3 bg-zinc-950/80 backdrop-blur-md rounded-2xl border border-orange-500/20 text-[9px] font-mono text-white/90 shadow-xl overflow-x-auto">
|
||||
<div className="flex items-center justify-between gap-4 whitespace-nowrap">
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock size={10} className="text-orange-500" />
|
||||
<span className="text-zinc-500">CLIENT:</span>
|
||||
<span className="text-orange-500 font-bold">{perfMetrics.comp.toFixed(0)}ms</span>
|
||||
<span className="text-zinc-600">({(perfMetrics.uploadSize / 1024).toFixed(0)}KB)</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-zinc-500">AI:</span>
|
||||
{perfMetrics.aiApi === 0 ? (
|
||||
<span className="text-green-500 font-bold tracking-tight">CACHE HIT ⚡</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-orange-500 font-bold">{perfMetrics.aiTotal.toFixed(0)}ms</span>
|
||||
<span className="text-zinc-600 ml-1">(API: {perfMetrics.aiApi.toFixed(0)}ms / Pars: {perfMetrics.aiParse.toFixed(0)}ms)</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-zinc-500">APP:</span>
|
||||
<span className="text-orange-500 font-bold">{perfMetrics.prep.toFixed(0)}ms</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user