yusufcalisir's picture
deploy: Hugging Face space upload
eff6797
Raw History Blame Contribute Delete
11 kB
import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
BarChart3,
Layers,
Database,
ShieldCheck,
TrendingUp,
CheckCircle2,
Cpu,
ArrowRight,
} from 'lucide-react';
import { useModalA11y } from '../hooks/useModalA11y';
interface BenchmarkLaunchModalProps {
isOpen: boolean;
onClose?: () => void;
onComplete: () => void;
}
interface BenchmarkStageInfo {
id: number;
label: string;
subtext: string;
tag: string;
icon: typeof BarChart3;
color: string;
glow: string;
}
const BENCHMARK_STAGES: BenchmarkStageInfo[] = [
{
id: 1,
label: 'Kaggle & PaySim Baseline Ingestion',
subtext: 'Loading 284,807 real-world credit card transactions & 492 fraud cases',
tag: '284.8k Records · Loaded',
icon: Database,
color: '#6366f1',
glow: 'rgba(99, 102, 241, 0.4)',
},
{
id: 2,
label: 'Non-IID Dirichlet α=0.5 Cross-Bank Partition',
subtext: 'Synthesizing heterogeneous data skew across JPM, HSBC & DBK nodes',
tag: 'Dirichlet α=0.5 · Bounded',
icon: Layers,
color: '#8b5cf6',
glow: 'rgba(139, 92, 246, 0.4)',
},
{
id: 3,
label: 'Collaborative GNN vs Siloed Model Matrix',
subtext: 'Benchmarking PR-AUC (0.8420 vs 0.6940) & ROC-AUC (0.9120 vs 0.8350)',
tag: '+21.3% PR-AUC Gain',
icon: TrendingUp,
color: '#06b6d4',
glow: 'rgba(6, 182, 212, 0.4)',
},
{
id: 4,
label: 'Daily Cost & False Positive Reduction Audit',
subtext: 'Reconciling cross-bank laundering volume detection (+$836.3k detected volume)',
tag: '+55.59% Gain',
icon: Cpu,
color: '#10b981',
glow: 'rgba(16, 185, 129, 0.4)',
},
{
id: 5,
label: 'Launching Design Partner Benchmark Sandbox',
subtext: 'Attestation verified. Opening live interactive empirical metrics canvas',
tag: 'Sandbox Ready · v2.4',
icon: ShieldCheck,
color: '#38bdf8',
glow: 'rgba(56, 189, 248, 0.4)',
},
];
export default function BenchmarkLaunchModal({ isOpen, onClose, onComplete }: BenchmarkLaunchModalProps) {
const [currentStageIdx, setCurrentStageIdx] = useState(0);
const [progress, setProgress] = useState(10);
const { containerRef } = useModalA11y<HTMLDivElement>({
isOpen,
onClose: onClose || onComplete,
closeOnEscape: true,
trapFocus: true,
restoreFocus: true,
});
useEffect(() => {
if (!isOpen) {
setCurrentStageIdx(0);
setProgress(10);
return;
}
const TOTAL_DURATION_MS = 850;
const UPDATE_INTERVAL_MS = 15;
const startTime = Date.now();
let completionTimeout: ReturnType<typeof setTimeout> | null = null;
const timer = setInterval(() => {
const elapsed = Date.now() - startTime;
const rawPct = Math.min(100, 10 + (elapsed / TOTAL_DURATION_MS) * 90);
setProgress(rawPct);
const computedIdx = Math.min(
BENCHMARK_STAGES.length - 1,
Math.floor((elapsed / TOTAL_DURATION_MS) * BENCHMARK_STAGES.length)
);
setCurrentStageIdx(computedIdx);
if (elapsed >= TOTAL_DURATION_MS) {
clearInterval(timer);
setProgress(100);
completionTimeout = setTimeout(() => {
onComplete();
}, 100);
}
}, UPDATE_INTERVAL_MS);
return () => {
clearInterval(timer);
if (completionTimeout) {
clearTimeout(completionTimeout);
}
};
}, [isOpen, onComplete]);
if (!isOpen) return null;
const currentStage: BenchmarkStageInfo = BENCHMARK_STAGES[currentStageIdx] ?? (BENCHMARK_STAGES[0] as BenchmarkStageInfo);
const CurrentIcon = currentStage.icon;
return (
<AnimatePresence>
<div className="fixed inset-0 z-[200] flex items-center justify-center p-3 sm:p-6 overflow-x-hidden overflow-y-auto">
{/* Deep Backdrop with Ambient Glow */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-[#03030c]/90 backdrop-blur-2xl"
/>
{/* Modal Window Container */}
<motion.div
ref={containerRef}
role="dialog"
aria-modal="true"
aria-labelledby="benchmark-modal-title"
aria-describedby="benchmark-modal-desc"
tabIndex={-1}
initial={{ opacity: 0, scale: 0.94, y: 15 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.94, y: 15 }}
transition={{ type: 'spring', damping: 26, stiffness: 260 }}
className="relative w-full max-w-lg rounded-3xl bg-gradient-to-b from-[#0a0c28] via-[#07081a] to-[#04050e] border border-indigo-500/30 p-5 sm:p-7 shadow-[0_0_80px_rgba(99,102,241,0.25)] space-y-5 z-10 overflow-hidden focus:outline-none"
>
{/* Top Edge Glow */}
<div className="absolute top-0 inset-x-0 h-1 bg-gradient-to-r from-indigo-500 via-purple-500 to-cyan-400" />
{/* Header */}
<div className="flex items-center justify-between border-b border-white/10 pb-4 gap-2">
<div className="flex items-center gap-3 min-w-0">
<div className="w-10 h-10 rounded-2xl bg-indigo-500/20 border border-indigo-500/30 flex items-center justify-center text-indigo-300 shadow-inner shrink-0">
<BarChart3 className="w-5 h-5 animate-pulse" />
</div>
<div className="min-w-0">
<h3 id="benchmark-modal-title" className="text-base sm:text-lg font-bold text-white tracking-tight truncate">
Initializing Benchmark Sandbox
</h3>
<p id="benchmark-modal-desc" className="text-xs text-indigo-300/80 font-mono truncate">
Empirical Proof & Real Data Baseline Engine
</p>
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<span className="text-[10px] font-mono font-bold px-2.5 py-1 rounded-full bg-indigo-500/15 text-indigo-300 border border-indigo-500/30">
{Math.min(100, Math.round(progress))}%
</span>
<button
onClick={onComplete || onClose}
aria-label="Skip initialization and open benchmark hub"
className="px-2.5 py-1 rounded-lg text-[10px] sm:text-[11px] font-mono text-slate-400 hover:text-white bg-white/5 hover:bg-white/10 border border-white/10 transition-all cursor-pointer flex items-center gap-1 focus:outline-none focus:ring-2 focus:ring-indigo-400"
title="Direct jump to benchmark sandbox"
>
<span>Skip</span>
<ArrowRight className="w-3 h-3" />
</button>
</div>
</div>
{/* Active Stage Animated Card */}
<div className="p-4 rounded-2xl bg-[#02030a]/80 border border-white/10 space-y-3 relative overflow-hidden">
<div
className="absolute -right-8 -top-8 w-24 h-24 rounded-full blur-2xl pointer-events-none opacity-40"
style={{ backgroundColor: currentStage.color }}
/>
<div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-2.5 min-w-0">
<div
className="w-8 h-8 rounded-xl flex items-center justify-center shrink-0 border"
style={{
backgroundColor: `${currentStage.color}20`,
borderColor: `${currentStage.color}50`,
color: currentStage.color,
}}
>
<CurrentIcon className="w-4 h-4" />
</div>
<div className="min-w-0">
<span className="text-[10px] font-mono uppercase tracking-wider text-slate-400 block truncate">
Stage 0{currentStage.id} of 05
</span>
<h4 className="text-xs sm:text-sm font-bold text-slate-100 truncate">
{currentStage.label}
</h4>
</div>
</div>
<span
className="text-[9.5px] font-mono font-bold px-2.5 py-0.5 rounded-full border shrink-0"
style={{
backgroundColor: `${currentStage.color}15`,
borderColor: `${currentStage.color}40`,
color: currentStage.color,
}}
>
{currentStage.tag}
</span>
</div>
<p className="text-xs text-slate-300 leading-relaxed font-sans pl-1">
{currentStage.subtext}
</p>
</div>
{/* Step Progression Indicators */}
<div className="space-y-1.5">
{BENCHMARK_STAGES.map((s, idx) => {
const isCompleted = idx < currentStageIdx;
const isCurrent = idx === currentStageIdx;
return (
<div
key={s.id}
className={`flex items-center justify-between px-3 py-1.5 rounded-xl text-xs font-mono transition-all ${
isCurrent
? 'bg-indigo-600/15 border border-indigo-500/30 text-indigo-200'
: isCompleted
? 'text-slate-400 opacity-80'
: 'text-slate-600 opacity-40'
}`}
>
<div className="flex items-center gap-2 min-w-0">
{isCompleted ? (
<CheckCircle2 className="w-3.5 h-3.5 text-emerald-400 shrink-0" />
) : isCurrent ? (
<span className="w-2 h-2 rounded-full bg-indigo-400 animate-ping shrink-0" />
) : (
<span className="w-2 h-2 rounded-full bg-slate-700 shrink-0" />
)}
<span className="truncate">{s.label}</span>
</div>
<span className="text-[10px] opacity-75 shrink-0 ml-2">
{isCompleted ? '✓ Done' : isCurrent ? 'Active...' : 'Queued'}
</span>
</div>
);
})}
</div>
{/* Progress Bar */}
<div className="space-y-1.5 pt-1">
<div className="w-full bg-slate-900 rounded-full h-1.5 overflow-hidden p-0.5 border border-white/5">
<div
className="h-full rounded-full bg-gradient-to-r from-indigo-500 via-purple-500 to-cyan-400 transition-all duration-150"
style={{ width: `${progress}%` }}
/>
</div>
<div className="flex justify-between text-[10px] font-mono text-slate-500">
<span>Authenticating Secure Sandbox...</span>
<span>Redirecting to Benchmark Hub</span>
</div>
</div>
</motion.div>
</div>
</AnimatePresence>
);
}