Krish Patel commited on
Commit
772d253
·
1 Parent(s): b6597a0

added frontend

Browse files
nexus-frontend/.gitignore ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
nexus-frontend/README.md ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # React + TypeScript + Vite
2
+
3
+ This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
+
5
+ Currently, two official plugins are available:
6
+
7
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8
+ - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
+
10
+ ## Expanding the ESLint configuration
11
+
12
+ If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13
+
14
+ - Configure the top-level `parserOptions` property like this:
15
+
16
+ ```js
17
+ export default tseslint.config({
18
+ languageOptions: {
19
+ // other options...
20
+ parserOptions: {
21
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
22
+ tsconfigRootDir: import.meta.dirname,
23
+ },
24
+ },
25
+ })
26
+ ```
27
+
28
+ - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
29
+ - Optionally add `...tseslint.configs.stylisticTypeChecked`
30
+ - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
31
+
32
+ ```js
33
+ // eslint.config.js
34
+ import react from 'eslint-plugin-react'
35
+
36
+ export default tseslint.config({
37
+ // Set the react version
38
+ settings: { react: { version: '18.3' } },
39
+ plugins: {
40
+ // Add the react plugin
41
+ react,
42
+ },
43
+ rules: {
44
+ // other rules...
45
+ // Enable its recommended rules
46
+ ...react.configs.recommended.rules,
47
+ ...react.configs['jsx-runtime'].rules,
48
+ },
49
+ })
50
+ ```
nexus-frontend/eslint.config.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import reactHooks from 'eslint-plugin-react-hooks'
4
+ import reactRefresh from 'eslint-plugin-react-refresh'
5
+ import tseslint from 'typescript-eslint'
6
+
7
+ export default tseslint.config(
8
+ { ignores: ['dist'] },
9
+ {
10
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
+ files: ['**/*.{ts,tsx}'],
12
+ languageOptions: {
13
+ ecmaVersion: 2020,
14
+ globals: globals.browser,
15
+ },
16
+ plugins: {
17
+ 'react-hooks': reactHooks,
18
+ 'react-refresh': reactRefresh,
19
+ },
20
+ rules: {
21
+ ...reactHooks.configs.recommended.rules,
22
+ 'react-refresh/only-export-components': [
23
+ 'warn',
24
+ { allowConstantExport: true },
25
+ ],
26
+ },
27
+ },
28
+ )
nexus-frontend/guide.txt ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 1. Website Implementation
2
+ Tech Stack:
3
+
4
+ Frontend Framework: React.js or Next.js
5
+ State Management: Redux or Zustand
6
+ Styling: Tailwind CSS
7
+ Real-time Processing: WebSockets (Socket.io)
8
+ Data Visualization: Recharts or D3.js
9
+
10
+ Implementation Approach:
11
+
12
+ Create a comprehensive dashboard with:
13
+
14
+ Real-time misinformation tracking
15
+ Confidence score visualizations
16
+ Fact-checking integration
17
+ Interactive knowledge graphs
18
+ User authentication system
19
+
20
+
21
+ Key Features:
22
+
23
+ Live broadcast content analysis
24
+ Instant claim verification
25
+ Source credibility tracking
26
+ Detailed impact analysis
27
+ Exportable reports
28
+
29
+
30
+
31
+ Deployment:
32
+
33
+ Cloud Platforms: AWS, Google Cloud
34
+ Containerization: Docker
35
+ Continuous Integration: GitHub Actions
36
+
37
+ 2. Web Browser Extension
38
+ Tech Stack:
39
+
40
+ Core Technology: React.js
41
+ Language: TypeScript
42
+ Browser APIs: Chrome/Firefox Extension API
43
+ AI Integration: TensorFlow.js
44
+ State Management: Redux Toolkit
45
+
46
+ Implementation Approach:
47
+
48
+ Develop modular extension components:
49
+
50
+ Content script for webpage scanning
51
+ Background script for processing
52
+ Popup interface for settings/alerts
53
+ Overlay mechanism for fact-checking
54
+
55
+
56
+ Key Features:
57
+
58
+ Hover-based claim verification
59
+ Instant risk scoring
60
+ Minimal, non-intrusive design
61
+ Cross-site functionality
62
+
63
+
64
+
65
+ Deployment:
66
+
67
+ Chrome Web Store
68
+ Firefox Add-ons
69
+ Microsoft Edge Add-ons
70
+
71
+ 3. Mobile App Extension
72
+ Tech Stack:
73
+
74
+ Framework: React Native
75
+ State Management: Redux
76
+ AI Integration: TensorFlow Lite
77
+ Backend: Node.js with Express
78
+ Mobile-specific APIs
79
+
80
+ Implementation Approach:
81
+
82
+ Create cross-platform mobile application
83
+ Features:
84
+
85
+ News feed fact-checking
86
+ Social media content analysis
87
+ Offline mode for saved checks
88
+ Push notifications for high-risk content
89
+
90
+
91
+
92
+ Deployment:
93
+
94
+ App Store
95
+ Google Play Store
96
+ Potential enterprise distribution
97
+
98
+ 4. Alternative Frontend Ideas
99
+ 4.1 Slack/Discord Bot
100
+ Tech Stack:
101
+
102
+ Node.js
103
+ Discord.js/Slack API
104
+ Machine Learning Integration
105
+
106
+ Approach:
107
+
108
+ Real-time message scanning
109
+ Automatic fact-checking in chat environments
110
+ Seamless integration with communication platforms
111
+
112
+ 4.2 Telegram/WhatsApp Extension
113
+ Tech Stack:
114
+
115
+ Language: Python or Node.js
116
+ Telegram/WhatsApp API
117
+ Serverless Functions
118
+
119
+ Approach:
120
+
121
+ Message content analysis
122
+ Inline fact-checking
123
+ Support for group chats
124
+ Multilingual support
125
+
126
+ 4.3 Desktop Application
127
+ Tech Stack:
128
+
129
+ Electron.js
130
+ React.js
131
+ Machine Learning Integration
132
+ Local data processing
133
+
134
+ Approach:
135
+
136
+ Standalone application
137
+ Background monitoring of browsing
138
+ Comprehensive reporting
139
+ Advanced visualization
140
+
141
+ Comparative Analysis
142
+ ApproachProsConsBest ForWebsiteComprehensive, AccessibleRequires active navigationDetailed analysis, Professional useWeb ExtensionNon-intrusive, InstantLimited complex UICasual browsing, Quick checksMobile AppPortable, Push NotificationsScreen limitationsOn-the-go fact-checkingSlack BotWorkplace IntegrationLimited to platformProfessional environmentsDesktop AppPowerful, Offline CapableResource-intensivePower users, Deep analysis
143
+ Recommended Implementation Strategy
144
+
145
+ Start with Web Extension
146
+
147
+ Fastest development
148
+ Immediate user value
149
+ Low barrier to entry
150
+ Iterative improvement
151
+
152
+
153
+ Parallel Development
154
+
155
+ Web Dashboard for comprehensive analysis
156
+ Mobile companion app
157
+ Bot integrations as stretch goals
158
+
159
+
160
+
161
+ Key Considerations
162
+
163
+ Privacy-first design
164
+ Lightweight AI models
165
+ Minimal data transmission
166
+ Cross-platform compatibility
167
+ User-friendly interfaces
168
+ Continuous model updating
169
+ Transparent verification process
170
+
171
+ Potential Challenges
172
+
173
+ Real-time processing speed
174
+ Accuracy of ML models
175
+ API integration complexities
176
+ User adoption and trust
177
+ Handling multilingual content
178
+
179
+ Long-term Vision
180
+
181
+ Expand to multiple platforms
182
+ Improve AI accuracy
183
+ Build community-driven verification
184
+ Educational components
185
+ Global misinformation tracking
nexus-frontend/index.html ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>NEXUS</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
nexus-frontend/package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
nexus-frontend/package.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "nexus-frontend",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc -b && vite build",
9
+ "lint": "eslint .",
10
+ "preview": "vite preview"
11
+ },
12
+ "dependencies": {
13
+ "@emotion/react": "^11.14.0",
14
+ "@emotion/styled": "^11.14.0",
15
+ "@fontsource/press-start-2p": "^5.1.0",
16
+ "@mui/icons-material": "^6.3.1",
17
+ "@mui/material": "^6.3.1",
18
+ "framer-motion": "^11.15.0",
19
+ "lucide-react": "^0.469.0",
20
+ "mui": "^0.0.1",
21
+ "react": "^18.3.1",
22
+ "react-dom": "^18.3.1",
23
+ "react-icons": "^5.4.0",
24
+ "react-router-dom": "^7.1.1"
25
+ },
26
+ "devDependencies": {
27
+ "@eslint/js": "^9.17.0",
28
+ "@types/react": "^18.3.18",
29
+ "@types/react-dom": "^18.3.5",
30
+ "@vitejs/plugin-react-swc": "^3.5.0",
31
+ "autoprefixer": "^10.4.20",
32
+ "eslint": "^9.17.0",
33
+ "eslint-plugin-react-hooks": "^5.0.0",
34
+ "eslint-plugin-react-refresh": "^0.4.16",
35
+ "globals": "^15.14.0",
36
+ "postcss": "^8.4.49",
37
+ "tailwindcss": "^3.4.17",
38
+ "typescript": "~5.6.2",
39
+ "typescript-eslint": "^8.18.2",
40
+ "vite": "^6.0.5"
41
+ }
42
+ }
nexus-frontend/postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
nexus-frontend/src/App.css ADDED
File without changes
nexus-frontend/src/App.tsx ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
2
+ import DeepfakeDetection from './pages/deepfake';
3
+ import "./App.css";
4
+
5
+ // Import your page components
6
+ import Home from "./pages/Home";
7
+ import SignIn from "./pages/SignIn";
8
+ import SignUp from "./pages/SignUp";
9
+ import Dashboard from "./pages/Dashboard";
10
+
11
+ function App() {
12
+ return (
13
+ <Router>
14
+ <Routes>
15
+ <Route path="/" element={<Home />} />
16
+ <Route path="/login" element={<SignIn />} />
17
+ <Route path="/register" element={<SignUp />} />
18
+ <Route path="/dashboard" element={<Dashboard />} />
19
+ <Route path="/deepfake" element={<DeepfakeDetection />} />
20
+ </Routes>
21
+ </Router>
22
+ );
23
+ }
24
+
25
+ export default App;
nexus-frontend/src/components/FactCheckStream.tsx ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useEffect, useState } from "react";
2
+
3
+ interface CorrectionSource {
4
+ text: string;
5
+ url: string;
6
+ }
7
+
8
+ interface Claim {
9
+ claim: string;
10
+ verification_status: string;
11
+ }
12
+
13
+ interface MetaAnalysis {
14
+ information_ecosystem_impact: string;
15
+ recommended_actions: string[];
16
+ }
17
+
18
+ interface OverallAnalysis {
19
+ key_findings: string[];
20
+ patterns_identified: string[];
21
+ reliability_assessment: string;
22
+ truth_score: number;
23
+ }
24
+
25
+ interface DetailedAnalysis {
26
+ claim_analysis: Claim[];
27
+ meta_analysis: MetaAnalysis;
28
+ overall_analysis: OverallAnalysis;
29
+ }
30
+
31
+ interface Result {
32
+ timestamp: string;
33
+ original_text: string;
34
+ detailed_analysis: DetailedAnalysis;
35
+ correction_sources: {
36
+ [key: string]: {
37
+ [key: string]: CorrectionSource[];
38
+ };
39
+ };
40
+ url: string;
41
+ title: string;
42
+ summary: string;
43
+ }
44
+
45
+ interface ApiResponse {
46
+ result: Result;
47
+ }
48
+
49
+ const FactCheckStream = () => {
50
+ const [factChecks, setFactChecks] = useState<ApiResponse[] | []>([]);
51
+
52
+ useEffect(() => {
53
+ const ws = new WebSocket("http://localhost:8000/ws/factcheck-stream");
54
+
55
+ ws.onmessage = (event) => {
56
+ const result = JSON.parse(event.data);
57
+ console.log(result);
58
+ setFactChecks((prev) => [result, ...prev]);
59
+ };
60
+
61
+ ws.onerror = (error) => {
62
+ console.error("WebSocket error:", error);
63
+ };
64
+
65
+ return () => {
66
+ ws.close();
67
+ };
68
+ }, []);
69
+
70
+ return (
71
+ <div>
72
+ <h2>Live Fact Checks</h2>
73
+ {factChecks.map((check, index) => (
74
+ <div key={index} className="fact-check-card">
75
+
76
+ </div>
77
+ ))}
78
+ </div>
79
+ );
80
+ };
81
+
82
+ export default FactCheckStream;
nexus-frontend/src/index.css ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
nexus-frontend/src/main.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { StrictMode } from 'react'
2
+ import { createRoot } from 'react-dom/client'
3
+ import './index.css'
4
+ import App from './App.tsx'
5
+
6
+ createRoot(document.getElementById('root')!).render(
7
+ <StrictMode>
8
+ <App />
9
+ </StrictMode>,
10
+ )
nexus-frontend/src/pages/Dashboard.tsx ADDED
@@ -0,0 +1,602 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, memo } from 'react';
2
+ import { FileCheck, Shield, Database, Newspaper, Search, CheckCircle, AlertTriangle, Lock, Unlock, MessageSquare } from 'lucide-react';
3
+
4
+ interface DetailedAnalysis {
5
+ gemini_analysis: {
6
+ predicted_classification: string;
7
+ confidence_score: string;
8
+ reasoning: string[];
9
+ };
10
+ text_classification: {
11
+ category: string;
12
+ writing_style: string;
13
+ target_audience: string;
14
+ content_type: string;
15
+ };
16
+ sentiment_analysis: {
17
+ primary_emotion: string;
18
+ emotional_intensity: string;
19
+ sensationalism_level: string;
20
+ bias_indicators: string[];
21
+ tone: {
22
+ formality: string;
23
+ style: string;
24
+ };
25
+ emotional_triggers: string[];
26
+ };
27
+ entity_recognition: {
28
+ source_credibility: string;
29
+ people: string[];
30
+ organizations: string[];
31
+ locations: string[];
32
+ dates: string[];
33
+ statistics: string[];
34
+ };
35
+ context: {
36
+ main_narrative: string;
37
+ supporting_elements: string[];
38
+ key_claims: string[];
39
+ narrative_structure: string;
40
+ };
41
+ fact_checking: {
42
+ verifiable_claims: string[];
43
+ evidence_present: string;
44
+ fact_check_score: string;
45
+ };
46
+ }
47
+
48
+ const AnimatedBackground = memo(() => {
49
+ const backgroundIcons = [
50
+ FileCheck, Shield, Database, Newspaper, Search, CheckCircle, AlertTriangle, Lock, Unlock, MessageSquare
51
+ ];
52
+
53
+ return (
54
+ <div className="fixed inset-0 overflow-hidden">
55
+ <div className="absolute inset-0 transition-colors duration-300 bg-gradient-to-br from-gray-900 via-blue-900 to-gray-900 animate-gradient-dark" />
56
+
57
+ <div className="absolute inset-0 opacity-10">
58
+ <div className="absolute inset-0" style={{
59
+ backgroundImage: `linear-gradient(#ffffff20 1px, transparent 1px), linear-gradient(90deg, #ffffff20 1px, transparent 1px)`,
60
+ backgroundSize: '50px 50px',
61
+ animation: 'moveGrid 15s linear infinite'
62
+ }} />
63
+ </div>
64
+
65
+ <div className="absolute inset-0">
66
+ {backgroundIcons.map((Icon, index) => (
67
+ <div key={index}
68
+ className="absolute text-blue-400 opacity-10 animate-float-rotate"
69
+ style={{
70
+ left: `${(index * 20) % 100}%`,
71
+ top: `${(index * 25) % 100}%`,
72
+ animationDelay: `${index * 2}s`,
73
+ animationDuration: `${20 + index * 5}s`,
74
+ transform: `scale(${0.8 + (index % 3) * 0.2})`
75
+ }}>
76
+ <Icon size={48} />
77
+ </div>
78
+ ))}
79
+ </div>
80
+
81
+ <div className="absolute inset-0">
82
+ {[...Array(5)].map((_, i) => (
83
+ <div key={`orb-${i}`}
84
+ className="absolute rounded-full bg-blue-400 blur-xl opacity-20 animate-pulse-float"
85
+ style={{
86
+ width: `${150 + i * 50}px`,
87
+ height: `${150 + i * 50}px`,
88
+ left: `${(i * 30) % 100}%`,
89
+ top: `${(i * 35) % 100}%`,
90
+ animationDelay: `${i * 2}s`,
91
+ animationDuration: `${10 + i * 2}s`
92
+ }} />
93
+ ))}
94
+ </div>
95
+
96
+ <div className="absolute inset-0">
97
+ {[...Array(20)].map((_, i) => (
98
+ <div key={`particle-${i}`}
99
+ className="absolute w-1 h-1 rounded-full bg-blue-300 opacity-30 animate-particle"
100
+ style={{
101
+ left: `${Math.random() * 100}%`,
102
+ top: `${Math.random() * 100}%`,
103
+ animationDelay: `${Math.random() * 5}s`,
104
+ animationDuration: `${5 + Math.random() * 10}s`
105
+ }} />
106
+ ))}
107
+ </div>
108
+ </div>
109
+ );
110
+ });
111
+
112
+ const Dashboard = () => {
113
+ const [inputText, setInputText] = useState('');
114
+ const [isProcessing, setIsProcessing] = useState(false);
115
+ const [result, setResult] = useState<{
116
+ prediction: string;
117
+ detailed_analysis: {
118
+ gemini_analysis: {
119
+ predicted_classification: string;
120
+ confidence_score: string;
121
+ reasoning: string[];
122
+ text_classification: {
123
+ category: string;
124
+ writing_style: string;
125
+ target_audience: string;
126
+ content_type: string;
127
+ };
128
+ sentiment_analysis: {
129
+ primary_emotion: string;
130
+ emotional_intensity: string;
131
+ sensationalism_level: string;
132
+ bias_indicators: string[];
133
+ tone: {
134
+ formality: string;
135
+ style: string;
136
+ };
137
+ emotional_triggers: string[];
138
+ };
139
+ entity_recognition: {
140
+ source_credibility: string;
141
+ people: string[];
142
+ organizations: string[];
143
+ locations: string[];
144
+ dates: string[];
145
+ statistics: string[];
146
+ };
147
+ context: {
148
+ main_narrative: string;
149
+ supporting_elements: string[];
150
+ key_claims: string[];
151
+ narrative_structure: string;
152
+ };
153
+ fact_checking: {
154
+ verifiable_claims: string[];
155
+ evidence_present: string;
156
+ fact_check_score: string;
157
+ };
158
+ };
159
+ };
160
+ } | null>(null);
161
+ const [showDetailedAnalysis, setShowDetailedAnalysis] = useState(false);
162
+
163
+ const processInput = async () => {
164
+ if (!inputText.trim()) return;
165
+ setIsProcessing(true);
166
+ setResult(null);
167
+ setShowDetailedAnalysis(false);
168
+
169
+ try {
170
+ const response = await fetch('http://localhost:8000/analyze', {
171
+ method: 'POST',
172
+ headers: {
173
+ 'Content-Type': 'application/json',
174
+ },
175
+ body: JSON.stringify({ text: inputText }),
176
+ });
177
+
178
+ const data = await response.json();
179
+ setResult(data);
180
+ } catch (err) {
181
+ console.error('Analysis error:', err);
182
+ } finally {
183
+ setIsProcessing(false);
184
+ }
185
+ };
186
+
187
+ return (
188
+ <div className="min-h-screen relative overflow-hidden">
189
+ <AnimatedBackground />
190
+ <div className="relative z-10 max-w-3xl mx-auto p-6">
191
+ <div className="bg-gray-800/80 rounded-lg p-6 backdrop-blur-lg">
192
+ <div className="mb-6">
193
+ <h1 className="text-3xl font-bold text-white">
194
+ TruthTell Analysis
195
+ </h1>
196
+ </div>
197
+
198
+ <div className="space-y-6">
199
+ <div className="relative">
200
+ <textarea
201
+ value={inputText}
202
+ onChange={(e) => setInputText(e.target.value)}
203
+ className="w-full h-40 p-4 rounded-xl bg-gray-700 text-white placeholder-gray-400 focus:outline-none"
204
+ placeholder="Enter text to analyze..."
205
+ />
206
+ <button
207
+ onClick={processInput}
208
+ disabled={isProcessing || !inputText.trim()}
209
+ className="absolute bottom-4 right-4 px-6 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white disabled:opacity-50"
210
+ >
211
+ Analyze
212
+ </button>
213
+ </div>
214
+
215
+ {isProcessing && (
216
+ <div className="text-center p-8">
217
+ <div className="text-blue-400">Processing...</div>
218
+ </div>
219
+ )}
220
+
221
+ {result && (
222
+ <div className="bg-gray-700/80 rounded-xl p-6">
223
+ <div className="text-center mb-4">
224
+ <h2 className="text-2xl font-bold text-white capitalize">
225
+ {result.prediction}
226
+ </h2>
227
+ </div>
228
+
229
+ <div className="space-y-4">
230
+ <div>
231
+ <div className="flex justify-between text-sm text-blue-300 mb-2">
232
+ <span>Confidence</span>
233
+ <span>{result.detailed_analysis.gemini_analysis.confidence_score}%</span>
234
+ </div>
235
+ <div className="h-2 bg-blue-900 rounded">
236
+ <div
237
+ style={{ width: `${result.detailed_analysis.gemini_analysis.confidence_score}%` }}
238
+ className="h-full bg-blue-500 rounded"
239
+ />
240
+ </div>
241
+ </div>
242
+
243
+ <button
244
+ onClick={() => setShowDetailedAnalysis(!showDetailedAnalysis)}
245
+ className="w-full mt-4 px-6 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white transition-colors"
246
+ >
247
+ {showDetailedAnalysis ? 'Hide Detailed Analysis' : 'View Detailed Analysis'}
248
+ </button>
249
+
250
+ {showDetailedAnalysis && (
251
+ <div className="mt-4 p-4 bg-gray-800 rounded-lg">
252
+ <h3 className="text-xl font-semibold text-white mb-3">Detailed Analysis</h3>
253
+ <div className="space-y-4 text-gray-300">
254
+ {result?.detailed_analysis?.text_classification && (
255
+ <div>
256
+ <h4 className="font-semibold text-blue-300">Text Classification</h4>
257
+ <p>Category: {result.detailed_analysis.text_classification.category || 'N/A'}</p>
258
+ <p>Writing Style: {result.detailed_analysis.text_classification.writing_style || 'N/A'}</p>
259
+ <p>Target Audience: {result.detailed_analysis.text_classification.target_audience || 'N/A'}</p>
260
+ <p>Content Type: {result.detailed_analysis.text_classification.content_type || 'N/A'}</p>
261
+ </div>
262
+ )}
263
+
264
+ {result?.detailed_analysis?.sentiment_analysis && (
265
+ <div>
266
+ <h4 className="font-semibold text-blue-300">Sentiment Analysis</h4>
267
+ <p>Primary Emotion: {result.detailed_analysis.sentiment_analysis.primary_emotion || 'N/A'}</p>
268
+ <p>Emotional Intensity: {result.detailed_analysis.sentiment_analysis.emotional_intensity || 'N/A'}</p>
269
+ <p>Sensationalism Level: {result.detailed_analysis.sentiment_analysis.sensationalism_level || 'N/A'}</p>
270
+ <p>Tone: {result.detailed_analysis.sentiment_analysis.tone?.formality || 'N/A'},
271
+ {result.detailed_analysis.sentiment_analysis.tone?.style || 'N/A'}</p>
272
+ </div>
273
+ )}
274
+
275
+ {result?.detailed_analysis?.entity_recognition && (
276
+ <div>
277
+ <h4 className="font-semibold text-blue-300">Entity Recognition</h4>
278
+ <p>Source Credibility: {result.detailed_analysis.entity_recognition.source_credibility || 'N/A'}</p>
279
+ <p>People: {result.detailed_analysis.entity_recognition.people?.join(', ') || 'None'}</p>
280
+ <p>Organizations: {result.detailed_analysis.entity_recognition.organizations?.join(', ') || 'None'}</p>
281
+ <p>Locations: {result.detailed_analysis.entity_recognition.locations?.join(', ') || 'None'}</p>
282
+ </div>
283
+ )}
284
+
285
+ {result?.detailed_analysis?.fact_checking && (
286
+ <div>
287
+ <h4 className="font-semibold text-blue-300">Fact Checking</h4>
288
+ <p>Evidence Present: {result.detailed_analysis.fact_checking.evidence_present || 'N/A'}</p>
289
+ <p>Fact Check Score: {result.detailed_analysis.fact_checking.fact_check_score || 'N/A'}</p>
290
+ <p>Verifiable Claims: {result.detailed_analysis.fact_checking.verifiable_claims?.join(', ') || 'None'}</p>
291
+ </div>
292
+ )}
293
+ </div>
294
+ </div>
295
+ )}
296
+
297
+
298
+ </div>
299
+ </div>
300
+ )}
301
+ </div>
302
+ </div>
303
+ </div>
304
+ {/* Keep the existing style tag */}
305
+ <style dangerouslySetInnerHTML={{ __html: `
306
+ @keyframes floatRotate {
307
+ 0% { transform: translate(0, 0) rotate(0deg); }
308
+ 50% { transform: translate(20px, -20px) rotate(180deg); }
309
+ 100% { transform: translate(0, 0) rotate(360deg); }
310
+ }
311
+ @keyframes pulseFloat {
312
+ 0% { transform: translate(0, 0) scale(1); opacity: 0.2; }
313
+ 50% { transform: translate(30px, -30px) scale(1.2); opacity: 0.3; }
314
+ 100% { transform: translate(0, 0) scale(1); opacity: 0.2; }
315
+ }
316
+ @keyframes moveGrid {
317
+ 0% { transform: translate(0, 0); }
318
+ 100% { transform: translate(50px, 50px); }
319
+ }
320
+ @keyframes particle {
321
+ 0% { transform: translate(0, 0) scale(1); opacity: 0.3; }
322
+ 50% { transform: translate(100px, -100px) scale(2); opacity: 0.6; }
323
+ 100% { transform: translate(0, 0) scale(1); opacity: 0
324
+
325
+ }
326
+ @keyframes gradientAnimation {
327
+ 0% { background-position: 0% 50%; }
328
+ 50% { background-position: 100% 50%; }
329
+ 100% { background-position: 0% 50%; }
330
+ }
331
+ .animate-float-rotate { animation: floatRotate 20s infinite linear; }
332
+ .animate-pulse-float { animation: pulseFloat 10s infinite ease-in-out; }
333
+ .animate-particle { animation: particle 8s infinite ease-in-out; }
334
+ .animate-gradient-dark { background-size: 400% 400%; animation: gradientAnimation 15s ease infinite; }
335
+ `}} />
336
+ </div>
337
+ );
338
+ };
339
+
340
+ export default Dashboard;
341
+
342
+ // import React, { useState, memo } from 'react';
343
+ // import { FileCheck, Shield, Database, Newspaper, Search, CheckCircle, AlertTriangle, Lock, Unlock, MessageSquare } from 'lucide-react';
344
+
345
+ // const AnimatedBackground = memo(() => {
346
+ // const backgroundIcons = [
347
+ // FileCheck, Shield, Database, Newspaper, Search, CheckCircle, AlertTriangle, Lock, Unlock, MessageSquare
348
+ // ];
349
+
350
+ // return (
351
+ // <div className="fixed inset-0 overflow-hidden">
352
+ // <div className="absolute inset-0 transition-colors duration-300 bg-gradient-to-br from-gray-900 via-blue-900 to-gray-900 animate-gradient-dark" />
353
+
354
+ // <div className="absolute inset-0 opacity-10">
355
+ // <div className="absolute inset-0" style={{
356
+ // backgroundImage: `linear-gradient(#ffffff20 1px, transparent 1px), linear-gradient(90deg, #ffffff20 1px, transparent 1px)`,
357
+ // backgroundSize: '50px 50px',
358
+ // animation: 'moveGrid 15s linear infinite'
359
+ // }} />
360
+ // </div>
361
+
362
+ // <div className="absolute inset-0">
363
+ // {backgroundIcons.map((Icon, index) => (
364
+ // <div key={index}
365
+ // className="absolute text-blue-400 opacity-10 animate-float-rotate"
366
+ // style={{
367
+ // left: `${(index * 20) % 100}%`,
368
+ // top: `${(index * 25) % 100}%`,
369
+ // animationDelay: `${index * 2}s`,
370
+ // animationDuration: `${20 + index * 5}s`,
371
+ // transform: `scale(${0.8 + (index % 3) * 0.2})`
372
+ // }}>
373
+ // <Icon size={48} />
374
+ // </div>
375
+ // ))}
376
+ // </div>
377
+
378
+ // <div className="absolute inset-0">
379
+ // {[...Array(5)].map((_, i) => (
380
+ // <div key={`orb-${i}`}
381
+ // className="absolute rounded-full bg-blue-400 blur-xl opacity-20 animate-pulse-float"
382
+ // style={{
383
+ // width: `${150 + i * 50}px`,
384
+ // height: `${150 + i * 50}px`,
385
+ // left: `${(i * 30) % 100}%`,
386
+ // top: `${(i * 35) % 100}%`,
387
+ // animationDelay: `${i * 2}s`,
388
+ // animationDuration: `${10 + i * 2}s`
389
+ // }} />
390
+ // ))}
391
+ // </div>
392
+
393
+ // <div className="absolute inset-0">
394
+ // {[...Array(20)].map((_, i) => (
395
+ // <div key={`particle-${i}`}
396
+ // className="absolute w-1 h-1 rounded-full bg-blue-300 opacity-30 animate-particle"
397
+ // style={{
398
+ // left: `${Math.random() * 100}%`,
399
+ // top: `${Math.random() * 100}%`,
400
+ // animationDelay: `${Math.random() * 5}s`,
401
+ // animationDuration: `${5 + Math.random() * 10}s`
402
+ // }} />
403
+ // ))}
404
+ // </div>
405
+ // </div>
406
+ // );
407
+ // });
408
+
409
+ // const Dashboard = () => {
410
+ // const [inputText, setInputText] = useState('');
411
+ // const [isProcessing, setIsProcessing] = useState(false);
412
+ // const [result, setResult] = useState<{
413
+ // detailed_analysis: {
414
+ // gemini_analysis: {
415
+ // predicted_classification: string;
416
+ // confidence_score: string;
417
+ // reasoning: string[];
418
+ // };
419
+ // text_classification: {
420
+ // category: string;
421
+ // writing_style: string;
422
+ // target_audience: string;
423
+ // content_type: string;
424
+ // };
425
+ // sentiment_analysis: {
426
+ // primary_emotion: string;
427
+ // emotional_intensity: string;
428
+ // sensationalism_level: string;
429
+ // bias_indicators: string[];
430
+ // tone: {
431
+ // formality: string;
432
+ // style: string;
433
+ // };
434
+ // emotional_triggers: string[];
435
+ // };
436
+ // fact_checking: {
437
+ // verifiable_claims: string[];
438
+ // evidence_present: string;
439
+ // fact_check_score: string;
440
+ // };
441
+ // };
442
+ // } | null>(null);
443
+ // const [showDetailedAnalysis, setShowDetailedAnalysis] = useState(false);
444
+
445
+ // const processInput = async () => {
446
+ // if (!inputText.trim()) return;
447
+ // setIsProcessing(true);
448
+ // setResult(null);
449
+ // setShowDetailedAnalysis(false);
450
+
451
+ // try {
452
+ // const response = await fetch('http://localhost:8000/analyze', {
453
+ // method: 'POST',
454
+ // headers: {
455
+ // 'Content-Type': 'application/json',
456
+ // },
457
+ // body: JSON.stringify({ text: inputText }),
458
+ // });
459
+
460
+ // const data = await response.json();
461
+ // setResult(data);
462
+ // } catch (err) {
463
+ // console.error('Analysis error:', err);
464
+ // } finally {
465
+ // setIsProcessing(false);
466
+ // }
467
+ // };
468
+
469
+ // return (
470
+ // <div className="min-h-screen relative overflow-hidden">
471
+ // <AnimatedBackground />
472
+ // <div className="relative z-10 max-w-3xl mx-auto p-6">
473
+ // <div className="bg-gray-800/80 rounded-lg p-6 backdrop-blur-lg">
474
+ // <div className="mb-6">
475
+ // <h1 className="text-3xl font-bold text-white">
476
+ // TruthTell Analysis
477
+ // </h1>
478
+ // </div>
479
+
480
+ // <div className="space-y-6">
481
+ // <div className="relative">
482
+ // <textarea
483
+ // value={inputText}
484
+ // onChange={(e) => setInputText(e.target.value)}
485
+ // className="w-full h-40 p-4 rounded-xl bg-gray-700 text-white placeholder-gray-400 focus:outline-none"
486
+ // placeholder="Enter text to analyze..."
487
+ // />
488
+ // <button
489
+ // onClick={processInput}
490
+ // disabled={isProcessing || !inputText.trim()}
491
+ // className="absolute bottom-4 right-4 px-6 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white disabled:opacity-50"
492
+ // >
493
+ // Analyze
494
+ // </button>
495
+ // </div>
496
+
497
+ // {isProcessing && (
498
+ // <div className="text-center p-8">
499
+ // <div className="text-blue-400">Processing...</div>
500
+ // </div>
501
+ // )}
502
+
503
+ // {result && (
504
+ // <div className="bg-gray-700/80 rounded-xl p-6">
505
+ // <div className="text-center mb-4">
506
+ // <h2 className="text-2xl font-bold text-white capitalize">
507
+ // {result.detailed_analysis.gemini_analysis.predicted_classification}
508
+ // </h2>
509
+ // </div>
510
+
511
+ // <div className="space-y-4">
512
+ // <div>
513
+ // <div className="flex justify-between text-sm text-blue-300 mb-2">
514
+ // <span>Confidence</span>
515
+ // <span>{result.detailed_analysis.gemini_analysis.confidence_score}%</span>
516
+ // </div>
517
+ // <div className="h-2 bg-blue-900 rounded">
518
+ // <div
519
+ // style={{ width: `${result.detailed_analysis.gemini_analysis.confidence_score}%` }}
520
+ // className="h-full bg-blue-500 rounded"
521
+ // />
522
+ // </div>
523
+ // </div>
524
+
525
+ // <button
526
+ // onClick={() => setShowDetailedAnalysis(!showDetailedAnalysis)}
527
+ // className="w-full mt-4 px-6 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white transition-colors"
528
+ // >
529
+ // {showDetailedAnalysis ? 'Hide Detailed Analysis' : 'View Detailed Analysis'}
530
+ // </button>
531
+
532
+ // {showDetailedAnalysis && (
533
+ // <div className="mt-4 p-4 bg-gray-800 rounded-lg">
534
+ // <h3 className="text-xl font-semibold text-white mb-3">Detailed Analysis</h3>
535
+ // <div className="space-y-4 text-gray-300">
536
+ // <div>
537
+ // <h4 className="font-semibold text-blue-300">Text Classification</h4>
538
+ // <p>Category: {result.detailed_analysis.text_classification.category || 'N/A'}</p>
539
+ // <p>Writing Style: {result.detailed_analysis.text_classification.writing_style || 'N/A'}</p>
540
+ // <p>Target Audience: {result.detailed_analysis.text_classification.target_audience || 'N/A'}</p>
541
+ // <p>Content Type: {result.detailed_analysis.text_classification.content_type || 'N/A'}</p>
542
+ // </div>
543
+
544
+ // <div>
545
+ // <h4 className="font-semibold text-blue-300">Sentiment Analysis</h4>
546
+ // <p>Primary Emotion: {result.detailed_analysis.sentiment_analysis.primary_emotion || 'N/A'}</p>
547
+ // <p>Emotional Intensity: {result.detailed_analysis.sentiment_analysis.emotional_intensity || 'N/A'}</p>
548
+ // <p>Sensationalism Level: {result.detailed_analysis.sentiment_analysis.sensationalism_level || 'N/A'}</p>
549
+ // <p>Tone: {result.detailed_analysis.sentiment_analysis.tone?.formality || 'N/A'},
550
+ // {result.detailed_analysis.sentiment_analysis.tone?.style || 'N/A'}</p>
551
+ // </div>
552
+
553
+ // <div>
554
+ // <h4 className="font-semibold text-blue-300">Fact Checking</h4>
555
+ // <p>Evidence Present: {result.detailed_analysis.fact_checking.evidence_present || 'N/A'}</p>
556
+ // <p>Fact Check Score: {result.detailed_analysis.fact_checking.fact_check_score || 'N/A'}</p>
557
+ // <p>Verifiable Claims: {result.detailed_analysis.fact_checking.verifiable_claims?.join(', ') || 'None'}</p>
558
+ // </div>
559
+ // </div>
560
+ // </div>
561
+ // )}
562
+ // </div>
563
+ // </div>
564
+ // )}
565
+ // </div>
566
+ // </div>
567
+ // </div>
568
+ // <style dangerouslySetInnerHTML={{ __html: `
569
+ // @keyframes floatRotate {
570
+ // 0% { transform: translate(0, 0) rotate(0deg); }
571
+ // 50% { transform: translate(20px, -20px) rotate(180deg); }
572
+ // 100% { transform: translate(0, 0) rotate(360deg); }
573
+ // }
574
+ // @keyframes pulseFloat {
575
+ // 0% { transform: translate(0, 0) scale(1); opacity: 0.2; }
576
+ // 50% { transform: translate(30px, -30px) scale(1.2); opacity: 0.3; }
577
+ // 100% { transform: translate(0, 0) scale(1); opacity: 0.2; }
578
+ // }
579
+ // @keyframes moveGrid {
580
+ // 0% { transform: translate(0, 0); }
581
+ // 100% { transform: translate(50px, 50px); }
582
+ // }
583
+ // @keyframes particle {
584
+ // 0% { transform: translate(0, 0) scale(1); opacity: 0.3; }
585
+ // 50% { transform: translate(100px, -100px) scale(2); opacity: 0.6; }
586
+ // 100% { transform: translate(0, 0) scale(1); opacity: 0.3; }
587
+ // }
588
+ // @keyframes gradientAnimation {
589
+ // 0% { background-position: 0% 50%; }
590
+ // 50% { background-position: 100% 50%; }
591
+ // 100% { background-position: 0% 50%; }
592
+ // }
593
+ // .animate-float-rotate { animation: floatRotate 20s infinite linear; }
594
+ // .animate-pulse-float { animation: pulseFloat 10s infinite ease-in-out; }
595
+ // .animate-particle { animation: particle 8s infinite ease-in-out; }
596
+ // .animate-gradient-dark { background-size: 400% 400%; animation: gradientAnimation 15s ease infinite; }
597
+ // `}} />
598
+ // </div>
599
+ // );
600
+ // };
601
+
602
+ // export default Dashboard;
nexus-frontend/src/pages/Home.css ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .retro-theme {
2
+ background: #0a0a2a;
3
+ color: #00ff41;
4
+ font-family: "Press Start 2P", monospace;
5
+ }
6
+
7
+ .hero-section {
8
+ text-align: center;
9
+ margin: 4rem 0;
10
+ }
11
+
12
+ .glitch-text {
13
+ text-shadow: 2px 2px #ff00ff;
14
+ animation: glitch 1s infinite;
15
+ }
16
+
17
+ .subtitle {
18
+ color: #00ff41;
19
+ margin: 1rem 0;
20
+ }
21
+
22
+ .cta-button {
23
+ background: #ff00ff;
24
+ color: white;
25
+ border: none;
26
+ padding: 1rem 2rem;
27
+ font-size: 1.2rem;
28
+ cursor: pointer;
29
+ border-radius: 4px;
30
+ font-family: inherit;
31
+ }
32
+
33
+ .features-grid {
34
+ display: grid;
35
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
36
+ gap: 2rem;
37
+ margin: 4rem 0;
38
+ }
39
+
40
+ .feature-card {
41
+ background: rgba(255, 255, 255, 0.05);
42
+ padding: 2rem;
43
+ border-radius: 8px;
44
+ border: 1px solid #00ff41;
45
+ text-align: center;
46
+ }
47
+
48
+ .feature-icon {
49
+ font-size: 2.5rem;
50
+ margin-bottom: 1rem;
51
+ color: #ff00ff;
52
+ }
53
+
54
+ .tech-stack {
55
+ text-align: center;
56
+ margin: 4rem 0;
57
+ }
58
+
59
+ .tech-badges {
60
+ display: flex;
61
+ flex-wrap: wrap;
62
+ justify-content: center;
63
+ gap: 1rem;
64
+ margin-top: 2rem;
65
+ }
66
+
67
+ .badge {
68
+ background: #ff00ff;
69
+ color: white;
70
+ padding: 0.5rem 1rem;
71
+ border-radius: 20px;
72
+ font-size: 0.9rem;
73
+ }
74
+
75
+ @keyframes glitch {
76
+ 0% {
77
+ text-shadow: 2px 2px #ff00ff;
78
+ }
79
+ 25% {
80
+ text-shadow: -2px 2px #00ff41;
81
+ }
82
+ 50% {
83
+ text-shadow: 2px -2px #ff00ff;
84
+ }
85
+ 75% {
86
+ text-shadow: -2px -2px #00ff41;
87
+ }
88
+ 100% {
89
+ text-shadow: 2px 2px #ff00ff;
90
+ }
91
+ }
nexus-frontend/src/pages/Home.tsx ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Link } from 'react-router-dom';
2
+ import { motion } from "framer-motion";
3
+ import { FaCheckCircle, FaBolt, FaDatabase, FaBrain } from "react-icons/fa";
4
+ import "./Home.css";
5
+
6
+ const Home = () => {
7
+ const features = [
8
+ {
9
+ icon: <FaBolt className="text-4xl text-fuchsia-500" />,
10
+ title: "Real-Time Detection",
11
+ description: "Instant fact-checking during live broadcasts",
12
+ },
13
+ {
14
+ icon: <FaBrain className="text-4xl text-fuchsia-500" />,
15
+ title: "AI-Powered Analysis",
16
+ description: "Advanced machine learning for accurate verification",
17
+ },
18
+ {
19
+ icon: <FaDatabase className="text-4xl text-fuchsia-500" />,
20
+ title: "Knowledge Graph",
21
+ description: "Comprehensive fact database with Neo4j",
22
+ },
23
+ {
24
+ icon: <FaCheckCircle className="text-4xl text-fuchsia-500" />,
25
+ title: "Truth Detection",
26
+ description: "Sophisticated NLP for misinformation detection",
27
+ },
28
+ ];
29
+
30
+ return (
31
+ <div className="min-h-screen retro-theme p-8">
32
+ <motion.div
33
+ className="text-center my-16"
34
+ initial={{ opacity: 0, y: 20 }}
35
+ animate={{ opacity: 1, y: 0 }}
36
+ transition={{ duration: 0.8 }}
37
+ >
38
+ <h1 className="text-5xl md:text-8xl font-bold mb-4 glitch-text">
39
+ NEXUS OF TRUTH
40
+ </h1>
41
+ <p className="text-xl md:text-2xl mb-8">
42
+ Real-Time Misinformation Detection System
43
+ </p>
44
+ <Link to="/dashboard">
45
+ <motion.button
46
+ className="bg-fuchsia-600 text-white px-8 py-4 rounded-lg text-lg font-bold hover:bg-fuchsia-700 transition-colors"
47
+ whileHover={{ scale: 1.05 }}
48
+ whileTap={{ scale: 0.95 }}
49
+ >
50
+ Get Started
51
+ </motion.button>
52
+ </Link>
53
+ </motion.div>
54
+
55
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 my-16">
56
+ {features.map((feature, index) => (
57
+ <motion.div
58
+ key={index}
59
+ className="p-6 rounded-xl border border-[#00ff41] bg-opacity-5 bg-white backdrop-blur-sm"
60
+ initial={{ opacity: 0, x: -20 }}
61
+ animate={{ opacity: 1, x: 0 }}
62
+ transition={{ delay: index * 0.2 }}
63
+ whileHover={{ scale: 1.05 }}
64
+ >
65
+ <div className="flex justify-center mb-4">{feature.icon}</div>
66
+ <h3 className="text-xl font-bold mb-2 text-center">
67
+ {feature.title}
68
+ </h3>
69
+ <p className="text-center text-sm">{feature.description}</p>
70
+ </motion.div>
71
+ ))}
72
+ </div>
73
+
74
+ <motion.div
75
+ className="text-center my-16"
76
+ initial={{ opacity: 0 }}
77
+ animate={{ opacity: 1 }}
78
+ transition={{ delay: 1 }}
79
+ >
80
+ <h2 className="text-3xl font-bold mb-8">
81
+ Powered by Advanced Technology
82
+ </h2>
83
+ <div className="flex flex-wrap justify-center gap-4">
84
+ {["Python", "TensorFlow", "PyTorch", "BERT", "Kafka", "Neo4j"].map(
85
+ (tech, index) => (
86
+ <span
87
+ key={index}
88
+ className="px-4 py-2 bg-fuchsia-600 text-white rounded-full text-sm"
89
+ >
90
+ {tech}
91
+ </span>
92
+ )
93
+ )}
94
+ </div>
95
+ </motion.div>
96
+ </div>
97
+ );
98
+ };
99
+
100
+ export default Home;
nexus-frontend/src/pages/SignIn.tsx ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ const SignIn = () => {
2
+ return <div>SignIn</div>;
3
+ };
4
+
5
+ export default SignIn;
nexus-frontend/src/pages/SignUp.tsx ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ const SignUp = () => {
2
+ return <div>SignUp</div>;
3
+ };
4
+
5
+ export default SignUp;
nexus-frontend/src/pages/deepfake.tsx ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, memo } from 'react';
2
+ import { FileCheck, Shield, Database, Newspaper, Search, CheckCircle, AlertTriangle, Lock, Unlock, MessageSquare } from 'lucide-react';
3
+ import CloudUploadIcon from '@mui/icons-material/CloudUpload';
4
+
5
+ const AnimatedBackground = memo(() => {
6
+ const backgroundIcons = [
7
+ FileCheck, Shield, Database, Newspaper, Search, CheckCircle, AlertTriangle, Lock, Unlock, MessageSquare
8
+ ];
9
+
10
+ return (
11
+ <div className="fixed inset-0 overflow-hidden">
12
+ <div className="absolute inset-0 transition-colors duration-300 bg-gradient-to-br from-gray-900 via-blue-900 to-gray-900 animate-gradient-dark" />
13
+
14
+ {/* Grid Background */}
15
+ <div className="absolute inset-0 opacity-10">
16
+ <div className="absolute inset-0" style={{
17
+ backgroundImage: `linear-gradient(#ffffff20 1px, transparent 1px), linear-gradient(90deg, #ffffff20 1px, transparent 1px)`,
18
+ backgroundSize: '50px 50px',
19
+ animation: 'moveGrid 15s linear infinite'
20
+ }} />
21
+ </div>
22
+
23
+ {/* Floating Icons */}
24
+ <div className="absolute inset-0">
25
+ {backgroundIcons.map((Icon, index) => (
26
+ <div key={index}
27
+ className="absolute text-blue-400 opacity-10 animate-float-rotate"
28
+ style={{
29
+ left: `${(index * 20) % 100}%`,
30
+ top: `${(index * 25) % 100}%`,
31
+ animationDelay: `${index * 2}s`,
32
+ animationDuration: `${20 + index * 5}s`,
33
+ transform: `scale(${0.8 + (index % 3) * 0.2})`
34
+ }}>
35
+ <Icon size={48} />
36
+ </div>
37
+ ))}
38
+ </div>
39
+
40
+ {/* Glowing Orbs */}
41
+ <div className="absolute inset-0">
42
+ {[...Array(5)].map((_, i) => (
43
+ <div key={`orb-${i}`}
44
+ className="absolute rounded-full bg-blue-400 blur-xl opacity-20 animate-pulse-float"
45
+ style={{
46
+ width: `${150 + i * 50}px`,
47
+ height: `${150 + i * 50}px`,
48
+ left: `${(i * 30) % 100}%`,
49
+ top: `${(i * 35) % 100}%`,
50
+ animationDelay: `${i * 2}s`,
51
+ animationDuration: `${10 + i * 2}s`
52
+ }} />
53
+ ))}
54
+ </div>
55
+ </div>
56
+ );
57
+ });
58
+
59
+ const DeepfakeDetection = () => {
60
+ const [selectedImage, setSelectedImage] = useState(null);
61
+ const [result, setResult] = useState(null);
62
+ const [loading, setLoading] = useState(false);
63
+
64
+ const handleImageSelect = (event) => {
65
+ const file = event.target.files[0];
66
+ setSelectedImage(file);
67
+ };
68
+
69
+ const handleUpload = async () => {
70
+ if (!selectedImage) return;
71
+ setLoading(true);
72
+ const formData = new FormData();
73
+ formData.append('image', selectedImage);
74
+
75
+ try {
76
+ const response = await fetch('http://localhost:8000/detect-deepfake', {
77
+ method: 'POST',
78
+ body: formData,
79
+ });
80
+ const data = await response.json();
81
+ setResult(data);
82
+ } catch (error) {
83
+ console.error('Error:', error);
84
+ } finally {
85
+ setLoading(false);
86
+ }
87
+ };
88
+
89
+ return (
90
+ <div className="min-h-screen relative overflow-hidden">
91
+ <AnimatedBackground />
92
+ <div className="relative z-10 max-w-3xl mx-auto p-6">
93
+ <div className="bg-gray-800/80 rounded-lg p-6 backdrop-blur-lg">
94
+ <div className="mb-6">
95
+ <h1 className="text-3xl font-bold text-white">
96
+ Deepfake Detection
97
+ </h1>
98
+ </div>
99
+
100
+ <div className="space-y-6">
101
+ <div className="flex flex-col items-center">
102
+ <input
103
+ accept="image/*"
104
+ className="hidden"
105
+ id="image-upload"
106
+ type="file"
107
+ onChange={handleImageSelect}
108
+ />
109
+ <label htmlFor="image-upload">
110
+ <div className="px-6 py-3 rounded-lg bg-blue-500 hover:bg-blue-600 text-white cursor-pointer flex items-center gap-2">
111
+ <CloudUploadIcon />
112
+ Upload Image
113
+ </div>
114
+ </label>
115
+
116
+ {selectedImage && (
117
+ <div className="mt-4 text-center">
118
+ <p className="text-blue-300">Selected: {selectedImage.name}</p>
119
+ <img
120
+ src={URL.createObjectURL(selectedImage)}
121
+ alt="Preview"
122
+ className="max-w-md mt-4 rounded-lg mx-auto"
123
+ />
124
+ </div>
125
+ )}
126
+
127
+ <button
128
+ onClick={handleUpload}
129
+ disabled={!selectedImage || loading}
130
+ className="mt-4 px-6 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white disabled:opacity-50"
131
+ >
132
+ Analyze
133
+ </button>
134
+ </div>
135
+
136
+ {loading && (
137
+ <div className="text-center p-8">
138
+ <div className="text-blue-400">Processing...</div>
139
+ </div>
140
+ )}
141
+
142
+ {result && (
143
+ <div className="bg-gray-700/80 rounded-xl p-6 mt-4">
144
+ <h2 className="text-xl font-semibold text-white mb-3">Detection Results:</h2>
145
+ <pre className="text-gray-300 overflow-auto p-4 bg-gray-800 rounded-lg">
146
+ {JSON.stringify(result, null, 2)}
147
+ </pre>
148
+ </div>
149
+ )}
150
+ </div>
151
+ </div>
152
+ </div>
153
+
154
+ <style dangerouslySetInnerHTML={{ __html: `
155
+ @keyframes floatRotate {
156
+ 0% { transform: translate(0, 0) rotate(0deg); }
157
+ 50% { transform: translate(20px, -20px) rotate(180deg); }
158
+ 100% { transform: translate(0, 0) rotate(360deg); }
159
+ }
160
+ @keyframes pulseFloat {
161
+ 0% { transform: translate(0, 0) scale(1); opacity: 0.2; }
162
+ 50% { transform: translate(30px, -30px) scale(1.2); opacity: 0.3; }
163
+ 100% { transform: translate(0, 0) scale(1); opacity: 0.2; }
164
+ }
165
+ @keyframes moveGrid {
166
+ 0% { transform: translate(0, 0); }
167
+ 100% { transform: translate(50px, 50px); }
168
+ }
169
+ .animate-float-rotate { animation: floatRotate 20s infinite linear; }
170
+ .animate-pulse-float { animation: pulseFloat 10s infinite ease-in-out; }
171
+ .animate-gradient-dark { background-size: 400% 400%; animation: gradientAnimation 15s ease infinite; }
172
+ `}} />
173
+ </div>
174
+ );
175
+ };
176
+
177
+ export default DeepfakeDetection;
nexus-frontend/src/vite-env.d.ts ADDED
@@ -0,0 +1 @@
 
 
1
+ /// <reference types="vite/client" />
nexus-frontend/tailwind.config.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ content: [
4
+ "./index.html",
5
+ "./src/**/*.{js,jsx,ts,tsx}",
6
+ ],
7
+ theme: {
8
+ extend: {
9
+ keyframes: {
10
+ 'scan-lines': {
11
+ '0%, 100%': { transform: 'translateY(-50%)' },
12
+ '50%': { transform: 'translateY(50%)' }
13
+ }
14
+ },
15
+ animation: {
16
+ 'scan-lines': 'scan-lines 2s linear infinite'
17
+ }
18
+ },
19
+ },
20
+ plugins: [],
21
+ }
nexus-frontend/tsconfig.app.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "ES2020",
5
+ "useDefineForClassFields": true,
6
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
+ "module": "ESNext",
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "isolatedModules": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+ "jsx": "react-jsx",
17
+
18
+ /* Linting */
19
+ "strict": true,
20
+ "noUnusedLocals": true,
21
+ "noUnusedParameters": true,
22
+ "noFallthroughCasesInSwitch": true,
23
+ "noUncheckedSideEffectImports": true
24
+ },
25
+ "include": ["src"]
26
+ }
nexus-frontend/tsconfig.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
nexus-frontend/tsconfig.node.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2022",
5
+ "lib": ["ES2023"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "isolatedModules": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+
16
+ /* Linting */
17
+ "strict": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedSideEffectImports": true
22
+ },
23
+ "include": ["vite.config.ts"]
24
+ }
nexus-frontend/vite.config.ts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from 'vite'
2
+ import react from '@vitejs/plugin-react-swc'
3
+
4
+ // https://vite.dev/config/
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ })