Deepfake Authenticator
feat: split backend (HF) and frontend (Vercel)
1dfcfc7
import { useState } from 'react';
import type { AnalysisResult, AppState } from './types';
import { API_BASE } from './api';
import Background from './components/Background';
import RadioNav from './components/RadioNav';
import HeroSection from './components/HeroSection';
import UploadSection from './components/UploadSection';
import ProcessingSection from './components/ProcessingSection';
import ResultSection from './components/ResultSection';
import ErrorSection from './components/ErrorSection';
import Modal from './components/Modal';
const AGENTS = [
{ name: 'MetadataAgent', desc: 'Scans C2PA signatures and AI tool metadata in the first 512KB of the file.' },
{ name: 'FrameAnalyzerAgent', desc: 'Extracts up to 40 frames uniformly across the video duration.' },
{ name: 'FaceDetectorAgent', desc: 'Uses MediaPipe to detect and crop facial regions with 20% padding.' },
{ name: 'DecisionAgent (ViT)', desc: 'Ensemble of two ViT models (99.3% + 92.1% accuracy) with early exit.' },
{ name: 'AudioAuthenticator', desc: 'Wav2Vec2-based audio analysis with librosa heuristics for AV mismatch.' },
{ name: 'ReportGeneratorAgent',desc: 'Adaptive threshold + confidence calibration to produce the final verdict.' },
];
export default function App() {
const [state, setState] = useState<AppState>('hero');
const [result, setResult] = useState<AnalysisResult | null>(null);
const [error, setError] = useState('');
const [modal, setModal] = useState<string | null>(null);
async function handleAnalyze(file: File) {
setState('processing');
const fd = new FormData();
fd.append('file', file);
try {
const res = await fetch(`${API_BASE}/analyze`, { method: 'POST', body: fd });
if (!res.ok) {
const e = await res.json().catch(() => ({}));
throw new Error((e as { detail?: string }).detail || `Server error ${res.status}`);
}
const data: AnalysisResult = await res.json();
setResult(data);
setState('result');
} catch (err: unknown) {
setError(err instanceof Error ? err.message : 'Connection to analysis engine failed.');
setState('error');
}
}
const activeNav =
state === 'hero' ? 'dashboard' :
state === 'upload' ? 'analyze' :
state === 'processing' ? 'analyze' :
state === 'result' ? 'analyze' : 'dashboard';
const handleNav = (id: string) => {
if (id === 'dashboard') setState('hero');
else if (id === 'analyze') setState('upload');
else if (id === 'pricing') window.location.href = '/pricing';
else if (id === 'agents') setModal('agents');
else if (id === 'settings') setModal('network');
};
return (
<div className="min-h-screen flex flex-col relative overflow-x-hidden">
<Background />
<RadioNav active={activeNav} onNavigate={handleNav} />
{state === 'hero' && <HeroSection onAnalyze={() => setState('upload')} />}
{state === 'upload' && <UploadSection onAnalyze={handleAnalyze} onBack={() => setState('hero')} />}
{state === 'processing' && <ProcessingSection />}
{state === 'result' && result && <ResultSection result={result} onReset={() => setState('upload')} />}
{state === 'error' && <ErrorSection message={error} onRetry={() => setState('upload')} />}
{/* Agents Modal */}
{modal === 'agents' && (
<Modal title="Detection Agents" onClose={() => setModal(null)}>
<div className="flex flex-col gap-4">
{AGENTS.map((ag, i) => (
<div key={i} className="flex items-start gap-4 p-4 rounded-lg"
style={{ background: 'rgba(30,15,50,0.6)', border: '1px solid rgba(124,58,237,0.2)' }}>
<div className="w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 text-xs font-bold"
style={{ background: 'rgba(124,58,237,0.15)', border: '1px solid rgba(168,85,247,0.3)', color: '#a855f7' }}>
{i}
</div>
<div>
<div className="text-sm font-semibold mb-1" style={{ color: '#c084fc' }}>{ag.name}</div>
<div className="text-xs text-purple-300/50">{ag.desc}</div>
</div>
</div>
))}
</div>
</Modal>
)}
{/* Logs Modal */}
{modal === 'logs' && (
<Modal title="System Logs" onClose={() => setModal(null)}>
<div className="rounded-lg p-4 font-mono text-xs space-y-1 max-h-80 overflow-y-auto"
style={{ background: 'rgba(8,4,18,0.9)', color: '#a855f7' }}>
{[
'[BOOT] Authrix AI v2.2.0 initialized',
'[SYS] ViT ensemble models loaded',
'[SYS] MediaPipe face detector ready',
'[SYS] Wav2Vec2 audio model ready',
'[SYS] C2PA metadata scanner active',
'[NET] FastAPI server listening on :8000',
'[AUTH] API key validation enabled',
'[CACHE] SHA256 result cache initialized',
].map((line, i) => (
<div key={i} className="opacity-70">{line}</div>
))}
</div>
</Modal>
)}
{/* Network Modal */}
{modal === 'network' && (
<Modal title="Network Status" onClose={() => setModal(null)}>
<div className="grid grid-cols-2 gap-4">
{[
{ label: 'API Endpoint', value: window.location.origin },
{ label: 'HF Space', value: 'aarav13-authrix.hf.space' },
{ label: 'Max File Size', value: '100 MB' },
{ label: 'Request Timeout', value: '120s' },
{ label: 'Capture Duration', value: '8s' },
{ label: 'Cache', value: 'SHA256 (1MB)' },
].map(({ label, value }) => (
<div key={label} className="rounded-lg p-4"
style={{ background: 'rgba(20,10,35,0.6)', border: '1px solid rgba(88,28,135,0.25)' }}>
<div className="text-[10px] uppercase tracking-widest mb-1 text-purple-500/50">{label}</div>
<div className="text-sm font-bold font-mono" style={{ color: '#c084fc' }}>{value}</div>
</div>
))}
</div>
</Modal>
)}
</div>
);
}