File size: 6,327 Bytes
70348ce
 
1dfcfc7
70348ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1dfcfc7
70348ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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>
  );
}