deeep-sec commited on
Commit
20db2c0
·
verified ·
1 Parent(s): 482e621

Upload frontend/src/App.tsx with huggingface_hub

Browse files
Files changed (1) hide show
  1. frontend/src/App.tsx +19 -188
frontend/src/App.tsx CHANGED
@@ -20,15 +20,7 @@ import { OfflineSelfCheck } from "./views/audit/OfflineSelfCheck";
20
  import { StudentPortal } from "./views/student/StudentPortal";
21
  import { RecruiterPortal } from "./views/recruiter/RecruiterPortal";
22
  import { AlertBanner } from "./components/common/AlertBanner";
23
- import { api } from "./api/client";
24
- import {
25
- WifiOff,
26
- CheckCircle2,
27
- Sparkles,
28
- Copy,
29
- Check,
30
- Radio,
31
- } from "lucide-react";
32
 
33
  const MainContent: React.FC = () => {
34
  const { user, login, studentLogin, error, clearError } = useAuth();
@@ -38,39 +30,12 @@ const MainContent: React.FC = () => {
38
 
39
  // Unauthenticated Login Form State
40
  const [authRole, setAuthRole] = useState<"officer" | "student" | "recruiter">("officer");
41
- const [username, setUsername] = useState("officer");
42
- const [password, setPassword] = useState("officer123");
43
- const [studentRoll, setStudentRoll] = useState("PIPE_001");
44
- const [studentCode, setStudentCode] = useState("123456");
45
  const [authLoading, setAuthLoading] = useState(false);
46
 
47
- // LAN Access Link
48
- const [lanUrl, setLanUrl] = useState<string>(() => {
49
- if (typeof window !== "undefined") {
50
- if (window.location.hostname !== "localhost" && window.location.hostname !== "127.0.0.1") {
51
- return `${window.location.protocol}//${window.location.hostname}:8000`;
52
- }
53
- }
54
- return "http://localhost:8000";
55
- });
56
- const [lanCopied, setLanCopied] = useState(false);
57
-
58
- useEffect(() => {
59
- api.get<any>("/api/lan-info").then((res) => {
60
- if (res?.primary_url) {
61
- setLanUrl(res.primary_url);
62
- }
63
- }).catch(() => {});
64
- }, []);
65
-
66
- const handleCopyLan = () => {
67
- if (navigator.clipboard) {
68
- navigator.clipboard.writeText(lanUrl);
69
- setLanCopied(true);
70
- setTimeout(() => setLanCopied(false), 2000);
71
- }
72
- };
73
-
74
  const handleTabSelect = (tab: string, driveId?: string) => {
75
  setActiveTab(tab as NavTabId);
76
  if (driveId) setActiveDriveId(driveId);
@@ -92,22 +57,6 @@ const MainContent: React.FC = () => {
92
  }
93
  };
94
 
95
- // Quick Preset Helper
96
- const setDemoPersona = (
97
- role: "officer" | "student" | "recruiter",
98
- userOrRoll: string,
99
- passOrCode: string
100
- ) => {
101
- setAuthRole(role);
102
- if (role === "student") {
103
- setStudentRoll(userOrRoll);
104
- setStudentCode(passOrCode);
105
- } else {
106
- setUsername(userOrRoll);
107
- setPassword(passOrCode);
108
- }
109
- };
110
-
111
  // If not logged in, render role-specific login portal
112
  if (!user) {
113
  return (
@@ -119,22 +68,18 @@ const MainContent: React.FC = () => {
119
  {/* Top Status Bar */}
120
  <div className="bg-[#040810]/90 backdrop-blur-md px-4 py-2 text-xs font-medium text-center border-b border-[#1b2b4d] flex items-center justify-center gap-3">
121
  <span className="flex items-center gap-1.5 text-emerald-400 font-mono text-[11px] font-bold">
122
- <WifiOff className="w-3.5 h-3.5" />
123
- 100% AIR-GAPPED OFFLINE LAN RUNTIME
124
  </span>
125
  <span className="text-slate-600 hidden sm:inline">•</span>
126
  <span className="text-slate-400 text-[11px] hidden sm:inline">
127
- Local SQLite WAL Engine • External Calls: 0
128
- </span>
129
- <span className="text-slate-600 hidden md:inline">•</span>
130
- <span className="text-emerald-300 text-[11px] font-mono font-bold hidden md:inline">
131
- LAN Host: {lanUrl}
132
  </span>
133
  </div>
134
 
135
  {/* Main Card Container */}
136
  <div className="flex-1 flex items-center justify-center p-4 sm:p-6 my-auto">
137
- <div className="w-full max-w-lg bg-[#0d1527]/95 backdrop-blur-xl rounded-3xl p-8 sm:p-10 shadow-2xl border border-[#1b2b4d] text-slate-100 space-y-6">
138
  {/* Header Branding */}
139
  <div className="text-center space-y-2">
140
  <div className="w-14 h-14 rounded-2xl bg-gradient-to-tr from-blue-700 via-teal-600 to-emerald-500 flex items-center justify-center text-white font-black text-2xl mx-auto shadow-xl shadow-emerald-500/20 ring-4 ring-emerald-500/20">PE</div>
@@ -153,121 +98,13 @@ const MainContent: React.FC = () => {
153
  <p className="text-xs text-slate-400 pt-1">
154
  One student, three drives, one Tuesday. Complete deterministic eligibility & constraint scheduling.
155
  </p>
156
-
157
- {/* Shareable LAN Pill */}
158
- <div className="pt-1 flex items-center justify-center">
159
- <button
160
- type="button"
161
- onClick={handleCopyLan}
162
- className="flex items-center gap-1.5 px-3 py-1 rounded-full bg-[#080e1c] hover:bg-[#111d38] border border-[#1b2b4d] hover:border-emerald-500/40 text-slate-300 text-[11px] font-mono transition-all cursor-pointer shadow-xs"
163
- title="Click to copy Wi-Fi / LAN link"
164
- >
165
- <Radio className="w-3 h-3 text-emerald-400 animate-pulse" />
166
- <span className="text-slate-400">LAN Host:</span>
167
- <span className="text-emerald-300 font-bold">{lanUrl}</span>
168
- {lanCopied ? (
169
- <Check className="w-3 h-3 text-emerald-400 ml-0.5" />
170
- ) : (
171
- <Copy className="w-3 h-3 text-slate-400 hover:text-white ml-0.5" />
172
- )}
173
- </button>
174
- </div>
175
- </div>
176
-
177
- {/* Quick Demo Persona Shortcuts */}
178
- <div className="space-y-2 bg-[#080e1c] p-3.5 rounded-2xl border border-[#1b2b4d]">
179
- <div className="flex items-center justify-between text-[11px] font-bold text-slate-400 uppercase tracking-wider">
180
- <span className="flex items-center gap-1 text-emerald-400">
181
- <Sparkles className="w-3 h-3 text-emerald-400" />
182
- 1-Click Demo Personas
183
- </span>
184
- <span className="text-[10px] text-slate-500 font-normal">Auto-fills credentials</span>
185
- </div>
186
- <div className="grid grid-cols-2 sm:grid-cols-3 gap-1.5 text-[11px] font-semibold">
187
- <button
188
- type="button"
189
- onClick={() => setDemoPersona("officer", "officer", "officer123")}
190
- className={`p-1.5 rounded-lg border text-left transition-all cursor-pointer ${
191
- authRole === "officer" && username === "officer"
192
- ? "bg-gradient-to-r from-blue-900/60 to-emerald-950/60 text-emerald-200 border-emerald-500/80 shadow-xs"
193
- : "bg-[#0d1527] text-slate-300 hover:bg-[#111d38] border-[#1b2b4d]"
194
- }`}
195
- >
196
- <div className="font-bold">TPO Officer</div>
197
- <div className="text-[9px] opacity-75 font-mono text-emerald-400">officer123</div>
198
- </button>
199
- <button
200
- type="button"
201
- onClick={() => setDemoPersona("officer", "coordinator", "coord123")}
202
- className={`p-1.5 rounded-lg border text-left transition-all cursor-pointer ${
203
- authRole === "officer" && username === "coordinator"
204
- ? "bg-gradient-to-r from-blue-900/60 to-emerald-950/60 text-emerald-200 border-emerald-500/80 shadow-xs"
205
- : "bg-[#0d1527] text-slate-300 hover:bg-[#111d38] border-[#1b2b4d]"
206
- }`}
207
- >
208
- <div className="font-bold">Coordinator</div>
209
- <div className="text-[9px] opacity-75 font-mono text-emerald-400">coord123</div>
210
- </button>
211
- <button
212
- type="button"
213
- onClick={() => setDemoPersona("student", "PIPE_001", "123456")}
214
- className={`p-1.5 rounded-lg border text-left transition-all cursor-pointer ${
215
- authRole === "student" && studentRoll === "PIPE_001"
216
- ? "bg-gradient-to-r from-blue-900/60 to-emerald-950/60 text-emerald-200 border-emerald-500/80 shadow-xs"
217
- : "bg-[#0d1527] text-slate-300 hover:bg-[#111d38] border-[#1b2b4d]"
218
- }`}
219
- >
220
- <div className="font-bold">Aryan (Eligible)</div>
221
- <div className="text-[9px] opacity-75 font-mono text-emerald-400">PIPE_001</div>
222
- </button>
223
- <button
224
- type="button"
225
- onClick={() => setDemoPersona("student", "PIPE_002", "123456")}
226
- className={`p-1.5 rounded-lg border text-left transition-all cursor-pointer ${
227
- authRole === "student" && studentRoll === "PIPE_002"
228
- ? "bg-gradient-to-r from-blue-900/60 to-emerald-950/60 text-emerald-200 border-emerald-500/80 shadow-xs"
229
- : "bg-[#0d1527] text-slate-300 hover:bg-[#111d38] border-[#1b2b4d]"
230
- }`}
231
- >
232
- <div className="font-bold">Priya (Lateral)</div>
233
- <div className="text-[9px] opacity-75 font-mono text-emerald-400">PIPE_002</div>
234
- </button>
235
- <button
236
- type="button"
237
- onClick={() => setDemoPersona("student", "PIPE_003", "123456")}
238
- className={`p-1.5 rounded-lg border text-left transition-all cursor-pointer ${
239
- authRole === "student" && studentRoll === "PIPE_003"
240
- ? "bg-gradient-to-r from-blue-900/60 to-emerald-950/60 text-emerald-200 border-emerald-500/80 shadow-xs"
241
- : "bg-[#0d1527] text-slate-300 hover:bg-[#111d38] border-[#1b2b4d]"
242
- }`}
243
- >
244
- <div className="font-bold">Rohan (Blocked)</div>
245
- <div className="text-[9px] opacity-75 font-mono text-emerald-400">PIPE_003</div>
246
- </button>
247
- <button
248
- type="button"
249
- onClick={() => setDemoPersona("recruiter", "recruiter_google", "recruiter123")}
250
- className={`p-1.5 rounded-lg border text-left transition-all cursor-pointer ${
251
- authRole === "recruiter" && username === "recruiter_google"
252
- ? "bg-gradient-to-r from-blue-900/60 to-emerald-950/60 text-emerald-200 border-emerald-500/80 shadow-xs"
253
- : "bg-[#0d1527] text-slate-300 hover:bg-[#111d38] border-[#1b2b4d]"
254
- }`}
255
- >
256
- <div className="font-bold">Google Recruiter</div>
257
- <div className="text-[9px] opacity-75 font-mono text-emerald-400">recruiter123</div>
258
- </button>
259
- </div>
260
  </div>
261
 
262
  {/* Role Switcher Tabs */}
263
  <div className="grid grid-cols-3 gap-1 bg-[#080e1c] p-1.5 rounded-2xl border border-[#1b2b4d]">
264
  <button
265
  type="button"
266
- onClick={() => {
267
- setAuthRole("officer");
268
- setUsername("officer");
269
- setPassword("officer123");
270
- }}
271
  className={`py-2 text-xs font-bold rounded-xl transition-all cursor-pointer ${
272
  authRole === "officer"
273
  ? "bg-gradient-to-r from-blue-700 to-emerald-600 text-white shadow-sm shadow-emerald-900/40"
@@ -278,11 +115,7 @@ const MainContent: React.FC = () => {
278
  </button>
279
  <button
280
  type="button"
281
- onClick={() => {
282
- setAuthRole("student");
283
- setStudentRoll("PIPE_001");
284
- setStudentCode("123456");
285
- }}
286
  className={`py-2 text-xs font-bold rounded-xl transition-all cursor-pointer ${
287
  authRole === "student"
288
  ? "bg-gradient-to-r from-blue-700 to-emerald-600 text-white shadow-sm shadow-emerald-900/40"
@@ -293,11 +126,7 @@ const MainContent: React.FC = () => {
293
  </button>
294
  <button
295
  type="button"
296
- onClick={() => {
297
- setAuthRole("recruiter");
298
- setUsername("recruiter_google");
299
- setPassword("recruiter123");
300
- }}
301
  className={`py-2 text-xs font-bold rounded-xl transition-all cursor-pointer ${
302
  authRole === "recruiter"
303
  ? "bg-gradient-to-r from-blue-700 to-emerald-600 text-white shadow-sm shadow-emerald-900/40"
@@ -323,12 +152,12 @@ const MainContent: React.FC = () => {
323
  value={studentRoll}
324
  onChange={(e) => setStudentRoll(e.target.value)}
325
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
326
- placeholder="e.g. PIPE_001"
327
  />
328
  </div>
329
  <div>
330
  <label className="block text-xs font-bold text-slate-300 uppercase tracking-wider mb-1">
331
- One-Time Access Code
332
  </label>
333
  <input
334
  type="password"
@@ -336,7 +165,7 @@ const MainContent: React.FC = () => {
336
  value={studentCode}
337
  onChange={(e) => setStudentCode(e.target.value)}
338
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
339
- placeholder="Default: 123456"
340
  />
341
  </div>
342
  </>
@@ -352,6 +181,7 @@ const MainContent: React.FC = () => {
352
  value={username}
353
  onChange={(e) => setUsername(e.target.value)}
354
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
 
355
  />
356
  </div>
357
  <div>
@@ -364,6 +194,7 @@ const MainContent: React.FC = () => {
364
  value={password}
365
  onChange={(e) => setPassword(e.target.value)}
366
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
 
367
  />
368
  </div>
369
  </>
@@ -374,7 +205,7 @@ const MainContent: React.FC = () => {
374
  disabled={authLoading}
375
  className="w-full py-3 bg-gradient-to-r from-blue-600 via-teal-600 to-emerald-600 hover:from-blue-500 hover:via-teal-500 hover:to-emerald-500 text-white font-bold text-sm rounded-xl shadow-lg shadow-emerald-900/30 border border-emerald-400/30 transition-all cursor-pointer disabled:opacity-50"
376
  >
377
- {authLoading ? "Authenticating on Local LAN..." : `Sign in as ${authRole}`}
378
  </button>
379
  </form>
380
  </div>
@@ -382,7 +213,7 @@ const MainContent: React.FC = () => {
382
 
383
  {/* Footer */}
384
  <div className="p-4 text-center text-xs text-slate-500 border-t border-[#1b2b4d] bg-[#040810]/80 backdrop-blur-md">
385
- Institutional Campus Placement Engine • 100% Offline SQLite + FastAPI Runtime
386
  </div>
387
  </div>
388
  );
 
20
  import { StudentPortal } from "./views/student/StudentPortal";
21
  import { RecruiterPortal } from "./views/recruiter/RecruiterPortal";
22
  import { AlertBanner } from "./components/common/AlertBanner";
23
+ import { CheckCircle2 } from "lucide-react";
 
 
 
 
 
 
 
 
24
 
25
  const MainContent: React.FC = () => {
26
  const { user, login, studentLogin, error, clearError } = useAuth();
 
30
 
31
  // Unauthenticated Login Form State
32
  const [authRole, setAuthRole] = useState<"officer" | "student" | "recruiter">("officer");
33
+ const [username, setUsername] = useState("");
34
+ const [password, setPassword] = useState("");
35
+ const [studentRoll, setStudentRoll] = useState("");
36
+ const [studentCode, setStudentCode] = useState("");
37
  const [authLoading, setAuthLoading] = useState(false);
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  const handleTabSelect = (tab: string, driveId?: string) => {
40
  setActiveTab(tab as NavTabId);
41
  if (driveId) setActiveDriveId(driveId);
 
57
  }
58
  };
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  // If not logged in, render role-specific login portal
61
  if (!user) {
62
  return (
 
68
  {/* Top Status Bar */}
69
  <div className="bg-[#040810]/90 backdrop-blur-md px-4 py-2 text-xs font-medium text-center border-b border-[#1b2b4d] flex items-center justify-center gap-3">
70
  <span className="flex items-center gap-1.5 text-emerald-400 font-mono text-[11px] font-bold">
71
+ <CheckCircle2 className="w-3.5 h-3.5" />
72
+ CAMPUS PLACEMENT ENGINE
73
  </span>
74
  <span className="text-slate-600 hidden sm:inline">•</span>
75
  <span className="text-slate-400 text-[11px] hidden sm:inline">
76
+ Deterministic Eligibility & Constraint Scheduling
 
 
 
 
77
  </span>
78
  </div>
79
 
80
  {/* Main Card Container */}
81
  <div className="flex-1 flex items-center justify-center p-4 sm:p-6 my-auto">
82
+ <div className="w-full max-w-md bg-[#0d1527]/95 backdrop-blur-xl rounded-3xl p-8 sm:p-10 shadow-2xl border border-[#1b2b4d] text-slate-100 space-y-6">
83
  {/* Header Branding */}
84
  <div className="text-center space-y-2">
85
  <div className="w-14 h-14 rounded-2xl bg-gradient-to-tr from-blue-700 via-teal-600 to-emerald-500 flex items-center justify-center text-white font-black text-2xl mx-auto shadow-xl shadow-emerald-500/20 ring-4 ring-emerald-500/20">PE</div>
 
98
  <p className="text-xs text-slate-400 pt-1">
99
  One student, three drives, one Tuesday. Complete deterministic eligibility & constraint scheduling.
100
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  </div>
102
 
103
  {/* Role Switcher Tabs */}
104
  <div className="grid grid-cols-3 gap-1 bg-[#080e1c] p-1.5 rounded-2xl border border-[#1b2b4d]">
105
  <button
106
  type="button"
107
+ onClick={() => setAuthRole("officer")}
 
 
 
 
108
  className={`py-2 text-xs font-bold rounded-xl transition-all cursor-pointer ${
109
  authRole === "officer"
110
  ? "bg-gradient-to-r from-blue-700 to-emerald-600 text-white shadow-sm shadow-emerald-900/40"
 
115
  </button>
116
  <button
117
  type="button"
118
+ onClick={() => setAuthRole("student")}
 
 
 
 
119
  className={`py-2 text-xs font-bold rounded-xl transition-all cursor-pointer ${
120
  authRole === "student"
121
  ? "bg-gradient-to-r from-blue-700 to-emerald-600 text-white shadow-sm shadow-emerald-900/40"
 
126
  </button>
127
  <button
128
  type="button"
129
+ onClick={() => setAuthRole("recruiter")}
 
 
 
 
130
  className={`py-2 text-xs font-bold rounded-xl transition-all cursor-pointer ${
131
  authRole === "recruiter"
132
  ? "bg-gradient-to-r from-blue-700 to-emerald-600 text-white shadow-sm shadow-emerald-900/40"
 
152
  value={studentRoll}
153
  onChange={(e) => setStudentRoll(e.target.value)}
154
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
155
+ placeholder="e.g. BT210001"
156
  />
157
  </div>
158
  <div>
159
  <label className="block text-xs font-bold text-slate-300 uppercase tracking-wider mb-1">
160
+ One-Time Access Code / Password
161
  </label>
162
  <input
163
  type="password"
 
165
  value={studentCode}
166
  onChange={(e) => setStudentCode(e.target.value)}
167
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
168
+ placeholder="Enter access code"
169
  />
170
  </div>
171
  </>
 
181
  value={username}
182
  onChange={(e) => setUsername(e.target.value)}
183
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
184
+ placeholder={authRole === "officer" ? "e.g. officer, coordinator" : "e.g. recruiter_google"}
185
  />
186
  </div>
187
  <div>
 
194
  value={password}
195
  onChange={(e) => setPassword(e.target.value)}
196
  className="w-full px-4 py-2.5 bg-[#080e1c] border border-[#1e3258] rounded-xl text-sm font-semibold text-white focus:bg-[#0d1527] focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
197
+ placeholder="Enter password"
198
  />
199
  </div>
200
  </>
 
205
  disabled={authLoading}
206
  className="w-full py-3 bg-gradient-to-r from-blue-600 via-teal-600 to-emerald-600 hover:from-blue-500 hover:via-teal-500 hover:to-emerald-500 text-white font-bold text-sm rounded-xl shadow-lg shadow-emerald-900/30 border border-emerald-400/30 transition-all cursor-pointer disabled:opacity-50"
207
  >
208
+ {authLoading ? "Authenticating..." : `Sign in as ${authRole === "officer" ? "Staff / Officer" : authRole === "student" ? "Student" : "Recruiter"}`}
209
  </button>
210
  </form>
211
  </div>
 
213
 
214
  {/* Footer */}
215
  <div className="p-4 text-center text-xs text-slate-500 border-t border-[#1b2b4d] bg-[#040810]/80 backdrop-blur-md">
216
+ Institutional Campus Placement Engine • High-Performance Deterministic Scheduling
217
  </div>
218
  </div>
219
  );