File size: 2,707 Bytes
af980d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { AnimatePresence, motion } from 'framer-motion';
import Navbar from './components/Navbar';
import LandingPage from './components/LandingPage';
import AnalysisProgress from './components/AnalysisProgress';
import ForensicDashboard from './components/ForensicDashboard';
import { useAnalysis } from './hooks/useAnalysis';
import { useTheme } from './hooks/useTheme';
import styles from './App.module.css';

export default function App() {
  const { phase, currentStage, progress, result, file, previewUrl, error, analyze, reset } = useAnalysis();
  const { theme, toggleTheme } = useTheme();

  return (
    <div className={styles.app}>
      <Navbar theme={theme} onToggleTheme={toggleTheme} />

      <main className={styles.main}>
        <AnimatePresence mode="wait">
          {phase === 'idle' && (
            <motion.div
              key="landing"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              transition={{ duration: 0.25 }}
            >
              <LandingPage onFileSelect={analyze} error={error} />
            </motion.div>
          )}

          {(phase === 'uploading' || phase === 'analyzing') && (
            <motion.div
              key="progress"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              transition={{ duration: 0.25 }}
            >
              <AnalysisProgress
                phase={phase}
                currentStage={currentStage}
                progress={progress}
                file={file}
              />
            </motion.div>
          )}

          {phase === 'complete' && result && (
            <motion.div
              key="dashboard"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              transition={{ duration: 0.3 }}
              className={styles.dashboardWrap}
            >
              <ForensicDashboard
                result={result}
                previewUrl={previewUrl}
                onReset={reset}
              />
            </motion.div>
          )}
        </AnimatePresence>
      </main>

      <footer className={styles.footer}>
        <p>
          <span className={styles.footerBrand}>UAIDE</span>
          {' '}路 Unified AI Origin Detection Engine 路 Academic Defense Interface 路{' '}
          <span>For evaluators, researchers, and investigators</span>
        </p>
        <p className={styles.footerDisclaimer}>
          Detection outcomes are probabilistic and intended to support, not replace, expert human review.
        </p>
      </footer>
    </div>
  );
}