admin08077 commited on
Commit
6b0e3cb
·
verified ·
1 Parent(s): 4c1f6b3

Upload App.tsx

Browse files
Files changed (1) hide show
  1. App.tsx +52 -194
App.tsx CHANGED
@@ -2,7 +2,8 @@ import React, { useState, useEffect, useCallback } from 'react';
2
  import { HashRouter, Routes, Route, Link, useLocation, Navigate, useNavigate } from 'react-router-dom';
3
  import {
4
  Bell, LogOut, Activity, ChevronRight, Cpu, Settings as SettingsIcon, Terminal, Loader2, Key,
5
- ShieldCheck, Zap, ArrowRight, ShieldAlert, Globe, Lock, Database, Shield, ZapOff, Fingerprint, Code
 
6
  } from 'lucide-react';
7
  import { routes } from './views/routes';
8
  import Login from './views/Login';
@@ -30,59 +31,6 @@ const SidebarItem: React.FC<{ icon: any, label: string, path: string, active: bo
30
  </Link>
31
  );
32
 
33
- const Header = ({ user, onLogout }: { user: UserSession, onLogout: () => void }) => {
34
- const location = useLocation();
35
- const currentRoute = routes.find(r => r.path === location.pathname);
36
- const [typedTitle, setTypedTitle] = useState('');
37
-
38
- useEffect(() => {
39
- if (!currentRoute) return;
40
- let i = 0;
41
- const fullText = currentRoute.label;
42
- setTypedTitle('');
43
- const timer = setInterval(() => {
44
- setTypedTitle(fullText.substring(0, i + 1));
45
- i++;
46
- if (i >= fullText.length) clearInterval(timer);
47
- }, 40);
48
- return () => clearInterval(timer);
49
- }, [location.pathname, currentRoute]);
50
-
51
- return (
52
- <header className="h-24 flex items-center justify-between px-10 bg-transparent relative z-50">
53
- <div className="flex items-center space-x-6">
54
- <div className="hidden md:flex flex-col">
55
- <h1 className="text-xl font-black tracking-tighter text-white italic leading-none uppercase">
56
- {typedTitle || 'CORE'} <span className="text-blue-500 not-italic">NODE</span>
57
- </h1>
58
- <p className="text-[10px] text-zinc-600 font-black uppercase tracking-[0.3em] mt-1 flex items-center gap-2">
59
- <Terminal size={10} />
60
- ROOT_IDENTIFIER: {user.name.toUpperCase()}
61
- </p>
62
- </div>
63
- </div>
64
-
65
- <div className="flex items-center space-x-8">
66
- <div className="flex items-center space-x-6">
67
- <button className="p-3 text-zinc-500 hover:text-white transition-all bg-zinc-950 rounded-xl border border-zinc-900 shadow-xl">
68
- <Bell size={18} />
69
- </button>
70
- <div className="h-8 w-px bg-zinc-900"></div>
71
- <div className="flex items-center space-x-4 group cursor-pointer" onClick={onLogout}>
72
- <div className="text-right">
73
- <p className="text-xs font-black text-white uppercase italic tracking-tighter">{user.name}</p>
74
- <p className="text-[9px] text-zinc-600 uppercase tracking-[0.2em] font-bold">{user.role}</p>
75
- </div>
76
- <div className="w-12 h-12 rounded-2xl bg-zinc-950 border border-zinc-900 flex items-center justify-center group-hover:border-rose-500/50 transition-all shadow-2xl">
77
- <LogOut size={18} className="text-zinc-600 group-hover:text-rose-500 transition-colors" />
78
- </div>
79
- </div>
80
- </div>
81
- </div>
82
- </header>
83
- );
84
- };
85
-
86
  const PrivateTerminal = ({ user, onLogout }: { user: UserSession, onLogout: () => void }) => {
87
  const location = useLocation();
88
  const navigate = useNavigate();
@@ -108,7 +56,26 @@ const PrivateTerminal = ({ user, onLogout }: { user: UserSession, onLogout: () =
108
  </div>
109
 
110
  <nav className="flex-1 space-y-2 overflow-y-auto custom-scrollbar pr-2 pb-10">
111
- <NavigationLinks />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  </nav>
113
 
114
  <div className="mt-auto pt-10 border-t border-zinc-900 space-y-4">
@@ -130,7 +97,25 @@ const PrivateTerminal = ({ user, onLogout }: { user: UserSession, onLogout: () =
130
  </aside>
131
 
132
  <main className="flex-1 ml-80 min-h-screen flex flex-col relative z-10">
133
- <Header user={user} onLogout={onLogout} />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  <div className="px-10 pb-20">
135
  <Routes>
136
  {routes.map((route) => (
@@ -144,131 +129,19 @@ const PrivateTerminal = ({ user, onLogout }: { user: UserSession, onLogout: () =
144
  );
145
  };
146
 
147
- const NavigationLinks = () => {
148
- const location = useLocation();
149
- const categories = ['core', 'registry', 'finance', 'intelligence', 'system', 'admin'];
150
- return (
151
- <div className="space-y-10">
152
- {categories.map(cat => {
153
- const catRoutes = routes.filter(r => r.showInSidebar && r.category === cat);
154
- if (catRoutes.length === 0) return null;
155
- return (
156
- <div key={cat} className="space-y-3">
157
- <p className="px-6 text-[8px] font-black uppercase text-zinc-700 tracking-[0.5em] mb-4">{cat.toUpperCase()}_SUITE</p>
158
- {catRoutes.map((route) => (
159
- <SidebarItem
160
- key={route.path}
161
- icon={route.icon}
162
- label={route.label}
163
- path={route.path}
164
- active={location.pathname === route.path}
165
- />
166
- ))}
167
- </div>
168
- );
169
- })}
170
- </div>
171
- );
172
- };
173
-
174
- const NeuralGate = ({ onAuthorized }: { onAuthorized: (tier: 'enterprise' | 'regular') => void }) => {
175
- const [loading, setLoading] = useState(false);
176
-
177
- const handleEnterpriseLink = async () => {
178
- setLoading(true);
179
- try {
180
- await window.aistudio.openSelectKey();
181
- onAuthorized('enterprise');
182
- } catch (e) {
183
- console.error("Enterprise gate refusal.");
184
- } finally {
185
- setLoading(false);
186
- }
187
- };
188
-
189
- const handleRegularLink = () => {
190
- onAuthorized('regular');
191
- };
192
-
193
- return (
194
- <div className="min-h-screen bg-black flex flex-col items-center justify-center p-12 relative overflow-hidden">
195
- <div className="absolute inset-0 z-0 opacity-20">
196
- <div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_50%_50%,_#1e1b4b_0%,_transparent_70%)]"></div>
197
- <div className="absolute inset-0 bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:80px_80px]"></div>
198
- </div>
199
-
200
- <div className="max-w-4xl w-full relative z-10 text-center space-y-16">
201
- <div className="relative inline-block group">
202
- <div className="absolute -inset-8 bg-blue-600/20 blur-3xl rounded-full opacity-50 group-hover:opacity-100 transition-opacity"></div>
203
- <div className="w-32 h-32 bg-white rounded-[3.5rem] flex items-center justify-center mx-auto shadow-[0_40px_80px_rgba(255,255,255,0.1)] group-hover:rotate-12 transition-transform duration-1000 border-4 border-zinc-900">
204
- <Lock size={64} className="text-black" />
205
- </div>
206
- </div>
207
-
208
- <div className="space-y-8">
209
- <h1 className="text-7xl lg:text-8xl font-black italic text-white uppercase tracking-tighter leading-none">
210
- Neural <span className="text-blue-500 not-italic">Gateway</span>
211
- </h1>
212
- <p className="text-zinc-500 font-bold text-2xl leading-relaxed italic max-w-2xl mx-auto">
213
- "To initialize the aibanking.dev ledger, establishing a secure neural link is mandatory. Select your protocol tier."
214
- </p>
215
- </div>
216
-
217
- <div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-3xl mx-auto">
218
- <button
219
- onClick={handleEnterpriseLink}
220
- disabled={loading}
221
- className="flex flex-col items-center gap-6 py-10 px-8 bg-blue-600 hover:bg-blue-500 text-white rounded-[3.5rem] transition-all shadow-[0_30px_60px_rgba(37,99,235,0.4)] group active:scale-95 border-2 border-transparent hover:border-white/20"
222
- >
223
- <Zap size={40} className="group-hover:scale-125 transition-transform" />
224
- <div className="text-center">
225
- <span className="block font-black text-sm uppercase tracking-[0.4em] mb-2">Enterprise Tier</span>
226
- <span className="block text-[10px] font-bold text-blue-100 uppercase tracking-widest opacity-60 italic">Requires Paid Google API Node</span>
227
- </div>
228
- <ArrowRight size={24} className="group-hover:translate-x-4 transition-transform" />
229
- </button>
230
-
231
- <button
232
- onClick={handleRegularLink}
233
- className="flex flex-col items-center gap-6 py-10 px-8 bg-zinc-900 hover:bg-zinc-800 text-white rounded-[3.5rem] transition-all shadow-2xl group active:scale-95 border-2 border-zinc-800 hover:border-zinc-700"
234
- >
235
- <Globe size={40} className="text-zinc-600 group-hover:text-blue-400 group-hover:scale-125 transition-all" />
236
- <div className="text-center">
237
- <span className="block font-black text-sm uppercase tracking-[0.4em] mb-2">Regular Tier</span>
238
- <span className="block text-[10px] font-bold text-zinc-500 uppercase tracking-widest opacity-60 italic">Free Local Instance Access</span>
239
- </div>
240
- <ArrowRight size={24} className="text-zinc-700 group-hover:text-zinc-500 group-hover:translate-x-4 transition-all" />
241
- </button>
242
- </div>
243
-
244
- <div className="pt-12 border-t border-zinc-900 space-y-6">
245
- <div className="flex flex-col md:flex-row items-center justify-center gap-10">
246
- <a href="https://ai.google.dev/gemini-api/docs/billing" target="_blank" rel="noreferrer" className="text-[10px] font-black text-zinc-600 hover:text-white uppercase tracking-widest transition-colors flex items-center gap-2">
247
- <Key size={12} /> Registry Documentation
248
- </a>
249
- <p className="text-[10px] font-black text-zinc-700 uppercase tracking-[0.4em]">v6.5.0 Institutional Registry • Secured via RSA-OAEP</p>
250
- </div>
251
- <div className="flex justify-center gap-12 opacity-20">
252
- <ShieldCheck size={32} /><Globe size={32} /><Database size={32} />
253
- </div>
254
- </div>
255
- </div>
256
- </div>
257
- );
258
- };
259
-
260
  const App: React.FC = () => {
261
- const [hasKey, setHasKey] = useState<boolean | null>(null);
262
- const [tier, setTier] = useState<'enterprise' | 'regular' | null>(null);
263
  const [currentUser, setCurrentUser] = useState<UserSession | null>(null);
264
  const [isAuthChecked, setIsAuthChecked] = useState<boolean>(false);
265
 
266
  const checkStatus = useCallback(async () => {
267
- const keySelected = await window.aistudio.hasSelectedApiKey();
268
- setHasKey(keySelected);
269
- const { user } = await apiClient.auth.me();
270
- setCurrentUser(user);
271
- setIsAuthChecked(true);
 
 
 
272
  }, []);
273
 
274
  useEffect(() => {
@@ -277,18 +150,7 @@ const App: React.FC = () => {
277
  return () => window.removeEventListener('auth-update', checkStatus);
278
  }, [checkStatus]);
279
 
280
- const handleLogout = async () => {
281
- await apiClient.auth.logout();
282
- setCurrentUser(null);
283
- };
284
-
285
- const onAuthorized = (selectedTier: 'enterprise' | 'regular') => {
286
- setTier(selectedTier);
287
- if (selectedTier === 'regular') setHasKey(true);
288
- else checkStatus();
289
- };
290
-
291
- if (!isAuthChecked || (hasKey === null && !tier)) {
292
  return (
293
  <div className="min-h-screen bg-black flex flex-col items-center justify-center space-y-12">
294
  <div className="relative">
@@ -300,20 +162,16 @@ const App: React.FC = () => {
300
  );
301
  }
302
 
303
- if (!hasKey && tier !== 'regular') {
304
- return <NeuralGate onAuthorized={onAuthorized} />;
305
- }
306
-
307
  return (
308
  <HashRouter>
309
  <Routes>
310
- <Route path="/" element={currentUser ? <Navigate to="/overview" replace /> : <Landing />} />
311
  <Route path="/login" element={currentUser ? <Navigate to="/overview" replace /> : <Login />} />
312
  <Route path="/airdrop" element={<Airdrop />} />
313
  <Route path="/manifesto" element={<PrivacyPolicy />} />
314
  <Route path="/documentation" element={<Documentation />} />
315
  <Route path="/*" element={currentUser ? (
316
- <PrivateTerminal user={currentUser} onLogout={handleLogout} />
317
  ) : (
318
  <Navigate to="/" replace />
319
  )} />
 
2
  import { HashRouter, Routes, Route, Link, useLocation, Navigate, useNavigate } from 'react-router-dom';
3
  import {
4
  Bell, LogOut, Activity, ChevronRight, Cpu, Settings as SettingsIcon, Terminal, Loader2, Key,
5
+ ShieldCheck, Zap, ArrowRight, ShieldAlert, Globe, Lock, Database, Shield, ZapOff, Fingerprint, Code,
6
+ Server, Layers, Network
7
  } from 'lucide-react';
8
  import { routes } from './views/routes';
9
  import Login from './views/Login';
 
31
  </Link>
32
  );
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  const PrivateTerminal = ({ user, onLogout }: { user: UserSession, onLogout: () => void }) => {
35
  const location = useLocation();
36
  const navigate = useNavigate();
 
56
  </div>
57
 
58
  <nav className="flex-1 space-y-2 overflow-y-auto custom-scrollbar pr-2 pb-10">
59
+ <div className="space-y-10">
60
+ {['core', 'registry', 'finance', 'intelligence', 'system', 'admin'].map(cat => {
61
+ const catRoutes = routes.filter(r => r.showInSidebar && r.category === cat);
62
+ if (catRoutes.length === 0) return null;
63
+ return (
64
+ <div key={cat} className="space-y-3">
65
+ <p className="px-6 text-[8px] font-black uppercase text-zinc-700 tracking-[0.5em] mb-4">{cat.toUpperCase()}_SUITE</p>
66
+ {catRoutes.map((route) => (
67
+ <SidebarItem
68
+ key={route.path}
69
+ icon={route.icon}
70
+ label={route.label}
71
+ path={route.path}
72
+ active={location.pathname === route.path}
73
+ />
74
+ ))}
75
+ </div>
76
+ );
77
+ })}
78
+ </div>
79
  </nav>
80
 
81
  <div className="mt-auto pt-10 border-t border-zinc-900 space-y-4">
 
97
  </aside>
98
 
99
  <main className="flex-1 ml-80 min-h-screen flex flex-col relative z-10">
100
+ <header className="h-24 flex items-center justify-between px-10 bg-transparent relative z-50">
101
+ <div className="flex items-center space-x-6">
102
+ <div className="flex flex-col">
103
+ <h1 className="text-xl font-black tracking-tighter text-white italic leading-none uppercase">SYSTEM <span className="text-blue-500 not-italic">CONSOLE</span></h1>
104
+ <p className="text-[10px] text-zinc-600 font-black uppercase tracking-[0.3em] mt-1 flex items-center gap-2">
105
+ <Terminal size={10} /> ROOT: {user.name.toUpperCase()}
106
+ </p>
107
+ </div>
108
+ </div>
109
+ <div className="flex items-center space-x-6">
110
+ <div className="text-right">
111
+ <p className="text-xs font-black text-white uppercase italic tracking-tighter">{user.name}</p>
112
+ <p className="text-[9px] text-zinc-600 uppercase tracking-[0.2em] font-bold">{user.role}</p>
113
+ </div>
114
+ <button onClick={handleTerminate} className="w-12 h-12 rounded-2xl bg-zinc-950 border border-zinc-900 flex items-center justify-center hover:border-rose-500/50 transition-all shadow-2xl">
115
+ <LogOut size={18} className="text-zinc-600" />
116
+ </button>
117
+ </div>
118
+ </header>
119
  <div className="px-10 pb-20">
120
  <Routes>
121
  {routes.map((route) => (
 
129
  );
130
  };
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  const App: React.FC = () => {
 
 
133
  const [currentUser, setCurrentUser] = useState<UserSession | null>(null);
134
  const [isAuthChecked, setIsAuthChecked] = useState<boolean>(false);
135
 
136
  const checkStatus = useCallback(async () => {
137
+ try {
138
+ const { user } = await apiClient.auth.me();
139
+ setCurrentUser(user);
140
+ } catch (e) {
141
+ console.error("Session sync failed.");
142
+ } finally {
143
+ setIsAuthChecked(true);
144
+ }
145
  }, []);
146
 
147
  useEffect(() => {
 
150
  return () => window.removeEventListener('auth-update', checkStatus);
151
  }, [checkStatus]);
152
 
153
+ if (!isAuthChecked) {
 
 
 
 
 
 
 
 
 
 
 
154
  return (
155
  <div className="min-h-screen bg-black flex flex-col items-center justify-center space-y-12">
156
  <div className="relative">
 
162
  );
163
  }
164
 
 
 
 
 
165
  return (
166
  <HashRouter>
167
  <Routes>
168
+ <Route path="/" element={<Landing />} />
169
  <Route path="/login" element={currentUser ? <Navigate to="/overview" replace /> : <Login />} />
170
  <Route path="/airdrop" element={<Airdrop />} />
171
  <Route path="/manifesto" element={<PrivacyPolicy />} />
172
  <Route path="/documentation" element={<Documentation />} />
173
  <Route path="/*" element={currentUser ? (
174
+ <PrivateTerminal user={currentUser} onLogout={async () => { await apiClient.auth.logout(); setCurrentUser(null); }} />
175
  ) : (
176
  <Navigate to="/" replace />
177
  )} />