mikaelJ46 commited on
Commit
b755be3
Β·
verified Β·
1 Parent(s): d54df31

Rename app.jsx to app.py

Browse files
Files changed (2) hide show
  1. app.jsx +0 -651
  2. app.py +297 -0
app.jsx DELETED
@@ -1,651 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { BookOpen, Users, Lock, Key, LogOut, ExternalLink, ChevronRight, GraduationCap, Beaker, Globe, Calculator, BookText, Languages } from 'lucide-react';
3
-
4
- const UnifiedPlatform = () => {
5
- const [currentPage, setCurrentPage] = useState('home');
6
- const [isAuthenticated, setIsAuthenticated] = useState(false);
7
- const [userType, setUserType] = useState(null);
8
- const [schoolCode, setSchoolCode] = useState('');
9
- const [adminPassword, setAdminPassword] = useState('');
10
- const [loginError, setLoginError] = useState('');
11
- const [schoolCodes, setSchoolCodes] = useState([]);
12
- const [newCodeName, setNewCodeName] = useState('');
13
- const [generatedCode, setGeneratedCode] = useState('');
14
-
15
- const ADMIN_PASSWORD = '@mikaelJ46';
16
-
17
- // Platform links
18
- const platforms = [
19
- {
20
- id: 'chemistry-biology',
21
- name: 'Chemistry & Biology',
22
- description: 'Deep understanding focus with AI-powered learning',
23
- icon: <Beaker className="w-8 h-8" />,
24
- url: 'https://huggingface.co/spaces/YOUR_USERNAME/chemistry-biology',
25
- color: 'bg-green-500',
26
- subjects: ['Chemistry', 'Biology']
27
- },
28
- {
29
- id: 'geography-history-business',
30
- name: 'Geography, History & Business',
31
- description: 'Comprehensive humanities and business studies',
32
- icon: <Globe className="w-8 h-8" />,
33
- url: 'https://huggingface.co/spaces/YOUR_USERNAME/geography-history-business',
34
- color: 'bg-blue-500',
35
- subjects: ['Geography', 'History', 'Business']
36
- },
37
- {
38
- id: 'languages',
39
- name: 'French & EFL',
40
- description: 'Language learning with AI translation and dictionary',
41
- icon: <Languages className="w-8 h-8" />,
42
- url: 'https://huggingface.co/spaces/YOUR_USERNAME/languages',
43
- color: 'bg-purple-500',
44
- subjects: ['French', 'EFL']
45
- },
46
- {
47
- id: 'math-physics',
48
- name: 'Mathematics & Physics',
49
- description: 'Step-by-step problem solving and practice',
50
- icon: <Calculator className="w-8 h-8" />,
51
- url: 'https://huggingface.co/spaces/YOUR_USERNAME/math-physics',
52
- color: 'bg-orange-500',
53
- subjects: ['Mathematics', 'Physics']
54
- }
55
- ];
56
-
57
- // Load school codes from storage
58
- useEffect(() => {
59
- const loadCodes = async () => {
60
- try {
61
- const result = await window.storage.list('school_code:');
62
- if (result && result.keys) {
63
- const codes = [];
64
- for (const key of result.keys) {
65
- const data = await window.storage.get(key);
66
- if (data) {
67
- codes.push(JSON.parse(data.value));
68
- }
69
- }
70
- setSchoolCodes(codes);
71
- }
72
- } catch (error) {
73
- console.log('No codes yet or error loading:', error);
74
- }
75
- };
76
- loadCodes();
77
- }, []);
78
-
79
- // Generate random school code
80
- const generateCode = () => {
81
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
82
- let code = '';
83
- for (let i = 0; i < 8; i++) {
84
- code += chars.charAt(Math.floor(Math.random() * chars.length));
85
- }
86
- return code;
87
- };
88
-
89
- // Admin: Create new school code
90
- const handleCreateCode = async () => {
91
- if (!newCodeName.trim()) {
92
- alert('Please enter a school/code name');
93
- return;
94
- }
95
-
96
- const code = generateCode();
97
- const codeData = {
98
- code: code,
99
- name: newCodeName,
100
- createdAt: new Date().toISOString(),
101
- active: true
102
- };
103
-
104
- try {
105
- await window.storage.set(`school_code:${code}`, JSON.stringify(codeData));
106
- setSchoolCodes([...schoolCodes, codeData]);
107
- setGeneratedCode(code);
108
- setNewCodeName('');
109
- } catch (error) {
110
- alert('Error creating code: ' + error.message);
111
- }
112
- };
113
-
114
- // Admin: Toggle code active status
115
- const toggleCodeStatus = async (code) => {
116
- try {
117
- const result = await window.storage.get(`school_code:${code}`);
118
- if (result) {
119
- const codeData = JSON.parse(result.value);
120
- codeData.active = !codeData.active;
121
- await window.storage.set(`school_code:${code}`, JSON.stringify(codeData));
122
- setSchoolCodes(schoolCodes.map(c => c.code === code ? codeData : c));
123
- }
124
- } catch (error) {
125
- alert('Error updating code: ' + error.message);
126
- }
127
- };
128
-
129
- // Handle admin login
130
- const handleAdminLogin = () => {
131
- if (adminPassword === ADMIN_PASSWORD) {
132
- setIsAuthenticated(true);
133
- setUserType('admin');
134
- setCurrentPage('admin-dashboard');
135
- setLoginError('');
136
- } else {
137
- setLoginError('Incorrect admin password');
138
- }
139
- };
140
-
141
- // Handle student login
142
- const handleStudentLogin = async () => {
143
- if (!schoolCode.trim()) {
144
- setLoginError('Please enter a school code');
145
- return;
146
- }
147
-
148
- try {
149
- const result = await window.storage.get(`school_code:${schoolCode.toUpperCase()}`);
150
- if (result) {
151
- const codeData = JSON.parse(result.value);
152
- if (codeData.active) {
153
- setIsAuthenticated(true);
154
- setUserType('student');
155
- setCurrentPage('student-dashboard');
156
- setLoginError('');
157
- } else {
158
- setLoginError('This school code has been deactivated');
159
- }
160
- } else {
161
- setLoginError('Invalid school code');
162
- }
163
- } catch (error) {
164
- setLoginError('Invalid school code');
165
- }
166
- };
167
-
168
- // Handle logout
169
- const handleLogout = () => {
170
- setIsAuthenticated(false);
171
- setUserType(null);
172
- setCurrentPage('home');
173
- setSchoolCode('');
174
- setAdminPassword('');
175
- setLoginError('');
176
- };
177
-
178
- // Open platform in same tab
179
- const openPlatform = (url) => {
180
- window.location.href = url;
181
- };
182
-
183
- // HOME PAGE
184
- if (currentPage === 'home') {
185
- return (
186
- <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-purple-50">
187
- {/* Header */}
188
- <header className="bg-white shadow-sm border-b">
189
- <div className="max-w-7xl mx-auto px-4 py-6">
190
- <div className="flex items-center justify-between">
191
- <div className="flex items-center gap-3">
192
- <GraduationCap className="w-10 h-10 text-blue-600" />
193
- <div>
194
- <h1 className="text-3xl font-bold text-gray-900">IGCSE/GCSE Master</h1>
195
- <p className="text-sm text-gray-600">AI-Powered Learning Platform</p>
196
- </div>
197
- </div>
198
- <button
199
- onClick={() => setCurrentPage('login-choice')}
200
- className="flex items-center gap-2 px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold"
201
- >
202
- <Lock className="w-5 h-5" />
203
- Login
204
- </button>
205
- </div>
206
- </div>
207
- </header>
208
-
209
- {/* Hero Section */}
210
- <section className="max-w-7xl mx-auto px-4 py-16 text-center">
211
- <h2 className="text-5xl font-bold text-gray-900 mb-6">
212
- Master Your IGCSE & GCSE Exams with AI
213
- </h2>
214
- <p className="text-xl text-gray-600 mb-8 max-w-3xl mx-auto">
215
- Comprehensive learning platform covering all major subjects with AI tutors, practice questions, past papers, and deep understanding focus.
216
- </p>
217
- <div className="flex items-center justify-center gap-4 flex-wrap">
218
- <div className="flex items-center gap-2 px-4 py-2 bg-green-100 text-green-800 rounded-full font-semibold">
219
- <div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
220
- Multi-AI System Active
221
- </div>
222
- <div className="px-4 py-2 bg-blue-100 text-blue-800 rounded-full font-semibold">
223
- 8 Subjects Covered
224
- </div>
225
- <div className="px-4 py-2 bg-purple-100 text-purple-800 rounded-full font-semibold">
226
- IGCSE & GCSE
227
- </div>
228
- </div>
229
- </section>
230
-
231
- {/* Platforms Grid */}
232
- <section className="max-w-7xl mx-auto px-4 py-12">
233
- <h3 className="text-3xl font-bold text-gray-900 mb-8 text-center">Our Learning Platforms</h3>
234
- <div className="grid md:grid-cols-2 gap-6">
235
- {platforms.map((platform) => (
236
- <div
237
- key={platform.id}
238
- className="bg-white rounded-xl shadow-lg hover:shadow-xl transition-all p-6 border-2 border-gray-100 hover:border-blue-300"
239
- >
240
- <div className="flex items-start gap-4">
241
- <div className={`${platform.color} p-4 rounded-lg text-white`}>
242
- {platform.icon}
243
- </div>
244
- <div className="flex-1">
245
- <h4 className="text-xl font-bold text-gray-900 mb-2">{platform.name}</h4>
246
- <p className="text-gray-600 mb-4">{platform.description}</p>
247
- <div className="flex flex-wrap gap-2">
248
- {platform.subjects.map((subject) => (
249
- <span key={subject} className="px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm font-medium">
250
- {subject}
251
- </span>
252
- ))}
253
- </div>
254
- </div>
255
- </div>
256
- </div>
257
- ))}
258
- </div>
259
- </section>
260
-
261
- {/* Features */}
262
- <section className="max-w-7xl mx-auto px-4 py-16">
263
- <h3 className="text-3xl font-bold text-gray-900 mb-12 text-center">Platform Features</h3>
264
- <div className="grid md:grid-cols-3 gap-8">
265
- <div className="text-center">
266
- <div className="bg-blue-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
267
- <BookOpen className="w-8 h-8 text-blue-600" />
268
- </div>
269
- <h4 className="text-xl font-bold mb-2">AI Tutors</h4>
270
- <p className="text-gray-600">Get personalized help from AI tutors with deep understanding focus</p>
271
- </div>
272
- <div className="text-center">
273
- <div className="bg-green-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
274
- <BookText className="w-8 h-8 text-green-600" />
275
- </div>
276
- <h4 className="text-xl font-bold mb-2">Past Papers</h4>
277
- <p className="text-gray-600">Access and practice with real exam questions indexed by topic</p>
278
- </div>
279
- <div className="text-center">
280
- <div className="bg-purple-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
281
- <Key className="w-8 h-8 text-purple-600" />
282
- </div>
283
- <h4 className="text-xl font-bold mb-2">Practice Questions</h4>
284
- <p className="text-gray-600">Generate unlimited practice questions with detailed feedback</p>
285
- </div>
286
- </div>
287
- </section>
288
-
289
- {/* Footer */}
290
- <footer className="bg-gray-900 text-white py-8 mt-16">
291
- <div className="max-w-7xl mx-auto px-4 text-center">
292
- <p className="text-gray-400">Β© 2024 IGCSE/GCSE Master. Powered by Gemini AI, Cohere, Z.ai & MiniMax</p>
293
- <p className="text-sm text-gray-500 mt-2">Multi-AI fallback system ensures 24/7 availability</p>
294
- </div>
295
- </footer>
296
- </div>
297
- );
298
- }
299
-
300
- // LOGIN CHOICE PAGE
301
- if (currentPage === 'login-choice') {
302
- return (
303
- <div className="min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 flex items-center justify-center p-4">
304
- <div className="max-w-2xl w-full">
305
- <button
306
- onClick={() => setCurrentPage('home')}
307
- className="mb-6 text-blue-600 hover:text-blue-700 flex items-center gap-2"
308
- >
309
- ← Back to Home
310
- </button>
311
-
312
- <div className="bg-white rounded-xl shadow-2xl p-8 mb-6 text-center">
313
- <GraduationCap className="w-16 h-16 text-blue-600 mx-auto mb-4" />
314
- <h2 className="text-3xl font-bold text-gray-900 mb-2">Welcome Back!</h2>
315
- <p className="text-gray-600">Choose how you'd like to login</p>
316
- </div>
317
-
318
- <div className="grid md:grid-cols-2 gap-6">
319
- <button
320
- onClick={() => setCurrentPage('student-login')}
321
- className="bg-white rounded-xl shadow-lg hover:shadow-xl transition-all p-8 text-center group"
322
- >
323
- <Users className="w-16 h-16 text-blue-600 mx-auto mb-4 group-hover:scale-110 transition-transform" />
324
- <h3 className="text-2xl font-bold text-gray-900 mb-2">Student Login</h3>
325
- <p className="text-gray-600 mb-4">Login with your school code</p>
326
- <ChevronRight className="w-6 h-6 text-blue-600 mx-auto" />
327
- </button>
328
-
329
- <button
330
- onClick={() => setCurrentPage('admin-login')}
331
- className="bg-white rounded-xl shadow-lg hover:shadow-xl transition-all p-8 text-center group"
332
- >
333
- <Lock className="w-16 h-16 text-purple-600 mx-auto mb-4 group-hover:scale-110 transition-transform" />
334
- <h3 className="text-2xl font-bold text-gray-900 mb-2">Admin Login</h3>
335
- <p className="text-gray-600 mb-4">Manage school codes</p>
336
- <ChevronRight className="w-6 h-6 text-purple-600 mx-auto" />
337
- </button>
338
- </div>
339
- </div>
340
- </div>
341
- );
342
- }
343
-
344
- // STUDENT LOGIN PAGE
345
- if (currentPage === 'student-login') {
346
- return (
347
- <div className="min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 flex items-center justify-center p-4">
348
- <div className="max-w-md w-full">
349
- <button
350
- onClick={() => setCurrentPage('login-choice')}
351
- className="mb-6 text-blue-600 hover:text-blue-700 flex items-center gap-2"
352
- >
353
- ← Back
354
- </button>
355
-
356
- <div className="bg-white rounded-xl shadow-2xl p-8">
357
- <div className="text-center mb-8">
358
- <Users className="w-16 h-16 text-blue-600 mx-auto mb-4" />
359
- <h2 className="text-3xl font-bold text-gray-900 mb-2">Student Login</h2>
360
- <p className="text-gray-600">Enter your school code to access all platforms</p>
361
- </div>
362
-
363
- {loginError && (
364
- <div className="mb-4 p-3 bg-red-100 border border-red-300 text-red-700 rounded-lg text-sm">
365
- {loginError}
366
- </div>
367
- )}
368
-
369
- <div className="space-y-4">
370
- <div>
371
- <label className="block text-sm font-medium text-gray-700 mb-2">School Code</label>
372
- <input
373
- type="text"
374
- value={schoolCode}
375
- onChange={(e) => setSchoolCode(e.target.value.toUpperCase())}
376
- onKeyPress={(e) => e.key === 'Enter' && handleStudentLogin()}
377
- placeholder="Enter 8-character code"
378
- className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-center text-xl font-mono tracking-wider"
379
- maxLength={8}
380
- />
381
- </div>
382
-
383
- <button
384
- onClick={handleStudentLogin}
385
- className="w-full py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold text-lg"
386
- >
387
- Login to Dashboard
388
- </button>
389
- </div>
390
- </div>
391
- </div>
392
- </div>
393
- );
394
- }
395
-
396
- // ADMIN LOGIN PAGE
397
- if (currentPage === 'admin-login') {
398
- return (
399
- <div className="min-h-screen bg-gradient-to-br from-purple-50 to-pink-50 flex items-center justify-center p-4">
400
- <div className="max-w-md w-full">
401
- <button
402
- onClick={() => setCurrentPage('login-choice')}
403
- className="mb-6 text-purple-600 hover:text-purple-700 flex items-center gap-2"
404
- >
405
- ← Back
406
- </button>
407
-
408
- <div className="bg-white rounded-xl shadow-2xl p-8">
409
- <div className="text-center mb-8">
410
- <Lock className="w-16 h-16 text-purple-600 mx-auto mb-4" />
411
- <h2 className="text-3xl font-bold text-gray-900 mb-2">Admin Login</h2>
412
- <p className="text-gray-600">Enter admin password to manage school codes</p>
413
- </div>
414
-
415
- {loginError && (
416
- <div className="mb-4 p-3 bg-red-100 border border-red-300 text-red-700 rounded-lg text-sm">
417
- {loginError}
418
- </div>
419
- )}
420
-
421
- <div className="space-y-4">
422
- <div>
423
- <label className="block text-sm font-medium text-gray-700 mb-2">Admin Password</label>
424
- <input
425
- type="password"
426
- value={adminPassword}
427
- onChange={(e) => setAdminPassword(e.target.value)}
428
- onKeyPress={(e) => e.key === 'Enter' && handleAdminLogin()}
429
- placeholder="Enter password"
430
- className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent"
431
- />
432
- </div>
433
-
434
- <button
435
- onClick={handleAdminLogin}
436
- className="w-full py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold text-lg"
437
- >
438
- Login to Admin Panel
439
- </button>
440
- </div>
441
- </div>
442
- </div>
443
- </div>
444
- );
445
- }
446
-
447
- // STUDENT DASHBOARD
448
- if (currentPage === 'student-dashboard' && isAuthenticated && userType === 'student') {
449
- return (
450
- <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-purple-50">
451
- <header className="bg-white shadow-sm border-b">
452
- <div className="max-w-7xl mx-auto px-4 py-6">
453
- <div className="flex items-center justify-between">
454
- <div className="flex items-center gap-3">
455
- <GraduationCap className="w-10 h-10 text-blue-600" />
456
- <div>
457
- <h1 className="text-2xl font-bold text-gray-900">Student Dashboard</h1>
458
- <p className="text-sm text-gray-600">Code: {schoolCode}</p>
459
- </div>
460
- </div>
461
- <button
462
- onClick={handleLogout}
463
- className="flex items-center gap-2 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
464
- >
465
- <LogOut className="w-4 h-4" />
466
- Logout
467
- </button>
468
- </div>
469
- </div>
470
- </header>
471
-
472
- <div className="max-w-7xl mx-auto px-4 py-8">
473
- <h2 className="text-3xl font-bold text-gray-900 mb-8">Choose Your Subject Platform</h2>
474
-
475
- <div className="grid md:grid-cols-2 gap-6">
476
- {platforms.map((platform) => (
477
- <div
478
- key={platform.id}
479
- className="bg-white rounded-xl shadow-lg hover:shadow-xl transition-all p-6 border-2 border-gray-100 hover:border-blue-300"
480
- >
481
- <div className="flex items-start gap-4 mb-4">
482
- <div className={`${platform.color} p-4 rounded-lg text-white`}>
483
- {platform.icon}
484
- </div>
485
- <div className="flex-1">
486
- <h3 className="text-xl font-bold text-gray-900 mb-2">{platform.name}</h3>
487
- <p className="text-gray-600 mb-3">{platform.description}</p>
488
- <div className="flex flex-wrap gap-2 mb-4">
489
- {platform.subjects.map((subject) => (
490
- <span key={subject} className="px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm font-medium">
491
- {subject}
492
- </span>
493
- ))}
494
- </div>
495
- </div>
496
- </div>
497
-
498
- <button
499
- onClick={() => openPlatform(platform.url)}
500
- className="w-full py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold flex items-center justify-center gap-2"
501
- >
502
- Open Platform
503
- <ChevronRight className="w-5 h-5" />
504
- </button>
505
- </div>
506
- ))}
507
- </div>
508
-
509
- <div className="mt-12 bg-blue-50 rounded-xl p-6 border-2 border-blue-200">
510
- <h3 className="text-xl font-bold text-gray-900 mb-4">πŸ“š Platform Features Available:</h3>
511
- <ul className="grid md:grid-cols-2 gap-3">
512
- <li className="flex items-center gap-2">
513
- <div className="w-2 h-2 bg-blue-600 rounded-full"></div>
514
- <span>AI Tutors with deep understanding focus</span>
515
- </li>
516
- <li className="flex items-center gap-2">
517
- <div className="w-2 h-2 bg-blue-600 rounded-full"></div>
518
- <span>Past papers indexed by topic</span>
519
- </li>
520
- <li className="flex items-center gap-2">
521
- <div className="w-2 h-2 bg-blue-600 rounded-full"></div>
522
- <span>Unlimited practice questions</span>
523
- </li>
524
- <li className="flex items-center gap-2">
525
- <div className="w-2 h-2 bg-blue-600 rounded-full"></div>
526
- <span>Detailed feedback and marking</span>
527
- </li>
528
- <li className="flex items-center gap-2">
529
- <div className="w-2 h-2 bg-blue-600 rounded-full"></div>
530
- <span>Multi-AI fallback system</span>
531
- </li>
532
- <li className="flex items-center gap-2">
533
- <div className="w-2 h-2 bg-blue-600 rounded-full"></div>
534
- <span>24/7 availability</span>
535
- </li>
536
- </ul>
537
- </div>
538
- </div>
539
- </div>
540
- );
541
- }
542
-
543
- // ADMIN DASHBOARD
544
- if (currentPage === 'admin-dashboard' && isAuthenticated && userType === 'admin') {
545
- return (
546
- <div className="min-h-screen bg-gradient-to-br from-purple-50 via-white to-pink-50">
547
- <header className="bg-white shadow-sm border-b">
548
- <div className="max-w-7xl mx-auto px-4 py-6">
549
- <div className="flex items-center justify-between">
550
- <div className="flex items-center gap-3">
551
- <Lock className="w-10 h-10 text-purple-600" />
552
- <div>
553
- <h1 className="text-2xl font-bold text-gray-900">Admin Panel</h1>
554
- <p className="text-sm text-gray-600">Manage school access codes</p>
555
- </div>
556
- </div>
557
- <button
558
- onClick={handleLogout}
559
- className="flex items-center gap-2 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
560
- >
561
- <LogOut className="w-4 h-4" />
562
- Logout
563
- </button>
564
- </div>
565
- </div>
566
- </header>
567
-
568
- <div className="max-w-7xl mx-auto px-4 py-8">
569
- {/* Create New Code */}
570
- <div className="bg-white rounded-xl shadow-lg p-6 mb-8">
571
- <h2 className="text-2xl font-bold text-gray-900 mb-6">Generate New School Code</h2>
572
-
573
- <div className="flex gap-4 mb-4">
574
- <input
575
- type="text"
576
- value={newCodeName}
577
- onChange={(e) => setNewCodeName(e.target.value)}
578
- placeholder="Enter school or code name"
579
- className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500"
580
- />
581
- <button
582
- onClick={handleCreateCode}
583
- className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold flex items-center gap-2"
584
- >
585
- <Key className="w-5 h-5" />
586
- Generate Code
587
- </button>
588
- </div>
589
-
590
- {generatedCode && (
591
- <div className="p-4 bg-green-50 border-2 border-green-300 rounded-lg">
592
- <p className="text-sm text-green-800 mb-2 font-semibold">βœ… New code generated successfully!</p>
593
- <div className="flex items-center gap-2">
594
- <code className="flex-1 px-4 py-3 bg-white border-2 border-green-400 rounded-lg text-2xl font-mono font-bold text-center">
595
- {generatedCode}
596
- </code>
597
- <button
598
- onClick={() => {
599
- navigator.clipboard.writeText(generatedCode);
600
- alert('Code copied to clipboard!');
601
- }}
602
- className="px-4 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700"
603
- >
604
- Copy
605
- </button>
606
- </div>
607
- </div>
608
- )}
609
- </div>
610
-
611
- {/* Active Codes List */}
612
- <div className="bg-white rounded-xl shadow-lg p-6">
613
- <h2 className="text-2xl font-bold text-gray-900 mb-6">
614
- All School Codes ({schoolCodes.length})
615
- </h2>
616
-
617
- {schoolCodes.length === 0 ? (
618
- <div className="text-center py-12 text-gray-500">
619
- <Key className="w-16 h-16 mx-auto mb-4 opacity-50" />
620
- <p>No school codes generated yet</p>
621
- </div>
622
- ) : (
623
- <div className="space-y-3">
624
- {schoolCodes.map((codeData) => (
625
- <div
626
- key={codeData.code}
627
- className={`p-4 border-2 rounded-lg flex items-center justify-between ${
628
- codeData.active ? 'bg-green-50 border-green-300' : 'bg-gray-50 border-gray-300'
629
- }`}
630
- >
631
- <div className="flex items-center gap-4">
632
- <code className="px-4 py-2 bg-white border rounded font-mono font-bold text-lg">
633
- {codeData.code}
634
- </code>
635
- <div>
636
- <p className="font-semibold text-gray-900">{codeData.name}</p>
637
- <p className="text-sm text-gray-600">
638
- Created: {new Date(codeData.createdAt).toLocaleString()}
639
- </p>
640
- </div>
641
- </div>
642
-
643
- <button
644
- onClick={() => toggleCodeStatus(codeData.code)}
645
- className={`px-4 py-2 rounded-lg font-semibold transition-colors ${
646
- codeData.active
647
- ? 'bg-red-100 text-red-700 hover:bg-red-200'
648
- : 'bg-green-100 text-green-700 hover:bg-green-200'
649
- }`}
650
- >
651
- {codeData.active ? 'Deactivate' : 'Activate'}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import random
4
+ import string
5
+ from datetime import datetime
6
+ from pathlib import Path
7
+
8
+ # Admin password
9
+ ADMIN_PASSWORD = "@mikaelJ46"
10
+
11
+ # Storage file for school codes
12
+ STORAGE_FILE = Path("school_codes.json")
13
+
14
+ # Platform links - UPDATE THESE WITH YOUR ACTUAL HUGGINGFACE SPACE URLS
15
+ PLATFORMS = [
16
+ {
17
+ "name": "Chemistry & Biology",
18
+ "description": "Deep understanding focus with AI-powered learning",
19
+ "subjects": ["Chemistry", "Biology"],
20
+ "url": "https://huggingface.co/spaces/YOUR_USERNAME/chemistry-biology",
21
+ "emoji": "πŸ§ͺ"
22
+ },
23
+ {
24
+ "name": "Geography, History & Business",
25
+ "description": "Comprehensive humanities and business studies",
26
+ "subjects": ["Geography", "History", "Business"],
27
+ "url": "https://huggingface.co/spaces/YOUR_USERNAME/geography-history-business",
28
+ "emoji": "🌍"
29
+ },
30
+ {
31
+ "name": "French & EFL",
32
+ "description": "Language learning with AI translation and dictionary",
33
+ "subjects": ["French", "EFL"],
34
+ "url": "https://huggingface.co/spaces/YOUR_USERNAME/languages",
35
+ "emoji": "πŸ—£οΈ"
36
+ },
37
+ {
38
+ "name": "Mathematics & Physics",
39
+ "description": "Step-by-step problem solving and practice",
40
+ "subjects": ["Mathematics", "Physics"],
41
+ "url": "https://huggingface.co/spaces/YOUR_USERNAME/math-physics",
42
+ "emoji": "πŸ“"
43
+ }
44
+ ]
45
+
46
+ # Storage functions
47
+ def load_codes():
48
+ """Load school codes from storage file"""
49
+ if STORAGE_FILE.exists():
50
+ with open(STORAGE_FILE, 'r') as f:
51
+ return json.load(f)
52
+ return {}
53
+
54
+ def save_codes(codes):
55
+ """Save school codes to storage file"""
56
+ with open(STORAGE_FILE, 'w') as f:
57
+ json.dump(codes, f, indent=2)
58
+
59
+ def generate_code():
60
+ """Generate random 8-character school code"""
61
+ chars = string.ascii_uppercase + string.digits
62
+ return ''.join(random.choice(chars) for _ in range(8))
63
+
64
+ # Authentication functions
65
+ def verify_student(school_code):
66
+ """Verify student school code"""
67
+ codes = load_codes()
68
+ code = school_code.upper().strip()
69
+
70
+ if code in codes:
71
+ if codes[code]['active']:
72
+ return True, f"βœ… Welcome! Access granted with code: {code}"
73
+ else:
74
+ return False, "❌ This school code has been deactivated"
75
+ return False, "❌ Invalid school code"
76
+
77
+ def verify_admin(password):
78
+ """Verify admin password"""
79
+ if password == ADMIN_PASSWORD:
80
+ return True, "βœ… Admin access granted"
81
+ return False, "❌ Incorrect admin password"
82
+
83
+ def create_school_code(school_name, admin_password):
84
+ """Admin function to create new school code"""
85
+ if admin_password != ADMIN_PASSWORD:
86
+ return "❌ Invalid admin password", ""
87
+
88
+ if not school_name.strip():
89
+ return "❌ Please enter a school name", ""
90
+
91
+ codes = load_codes()
92
+ new_code = generate_code()
93
+
94
+ codes[new_code] = {
95
+ "name": school_name,
96
+ "code": new_code,
97
+ "active": True,
98
+ "created_at": datetime.now().isoformat()
99
+ }
100
+
101
+ save_codes(codes)
102
+ return f"βœ… Code generated successfully!\n\n**School Code:** `{new_code}`\n**School Name:** {school_name}", new_code
103
+
104
+ def get_all_codes(admin_password):
105
+ """Get list of all school codes for admin"""
106
+ if admin_password != ADMIN_PASSWORD:
107
+ return "❌ Invalid admin password"
108
+
109
+ codes = load_codes()
110
+ if not codes:
111
+ return "πŸ“‹ No school codes created yet"
112
+
113
+ output = f"# πŸ“‹ All School Codes ({len(codes)})\n\n"
114
+ for code, data in codes.items():
115
+ status = "🟒 Active" if data['active'] else "πŸ”΄ Inactive"
116
+ created = datetime.fromisoformat(data['created_at']).strftime("%Y-%m-%d %H:%M")
117
+ output += f"### {status} `{code}`\n"
118
+ output += f"- **School:** {data['name']}\n"
119
+ output += f"- **Created:** {created}\n\n"
120
+
121
+ return output
122
+
123
+ def toggle_code_status(school_code, admin_password):
124
+ """Toggle active status of a school code"""
125
+ if admin_password != ADMIN_PASSWORD:
126
+ return "❌ Invalid admin password"
127
+
128
+ codes = load_codes()
129
+ code = school_code.upper().strip()
130
+
131
+ if code not in codes:
132
+ return "❌ Code not found"
133
+
134
+ codes[code]['active'] = not codes[code]['active']
135
+ save_codes(codes)
136
+
137
+ status = "activated" if codes[code]['active'] else "deactivated"
138
+ return f"βœ… Code {code} has been {status}"
139
+
140
+ def create_platform_links():
141
+ """Create HTML for platform links"""
142
+ html = "<div style='display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin-top: 20px;'>"
143
+
144
+ for platform in PLATFORMS:
145
+ subjects = ", ".join(platform['subjects'])
146
+ html += f"""
147
+ <div style='border: 2px solid #e5e7eb; border-radius: 12px; padding: 20px; background: white;'>
148
+ <h3 style='margin: 0 0 10px 0;'>{platform['emoji']} {platform['name']}</h3>
149
+ <p style='color: #6b7280; font-size: 14px; margin: 10px 0;'>{platform['description']}</p>
150
+ <p style='font-size: 12px; color: #9ca3af; margin: 10px 0;'><strong>Subjects:</strong> {subjects}</p>
151
+ <a href='{platform['url']}' target='_blank' style='display: inline-block; background: #3b82f6; color: white; padding: 10px 20px; border-radius: 8px; text-decoration: none; margin-top: 10px;'>Open Platform β†’</a>
152
+ </div>
153
+ """
154
+
155
+ html += "</div>"
156
+ return html
157
+
158
+ # Create the Gradio interface
159
+ with gr.Blocks(title="IGCSE/GCSE Master Platform", theme=gr.themes.Soft()) as app:
160
+
161
+ # Header
162
+ gr.Markdown("""
163
+ # πŸŽ“ IGCSE/GCSE Master Platform
164
+ ### AI-Powered Learning Platform for All Subjects
165
+
166
+ **Features:** AI Tutors β€’ Past Papers β€’ Practice Questions β€’ Multi-AI System β€’ 24/7 Availability
167
+ """)
168
+
169
+ with gr.Tabs() as tabs:
170
+
171
+ # HOME TAB
172
+ with gr.Tab("🏠 Home"):
173
+ gr.Markdown("""
174
+ ## Welcome to IGCSE/GCSE Master!
175
+
176
+ Our comprehensive learning platform covers all major subjects with AI tutors, practice questions,
177
+ past papers, and deep understanding focus.
178
+
179
+ ### πŸ“š Available Platforms:
180
+ """)
181
+
182
+ gr.HTML(create_platform_links())
183
+
184
+ gr.Markdown("""
185
+ ---
186
+ ### ✨ Platform Features:
187
+ - πŸ€– **AI Tutors** - Get personalized help with deep understanding focus
188
+ - πŸ“ **Past Papers** - Access real exam questions indexed by topic
189
+ - 🎯 **Practice Questions** - Generate unlimited practice with detailed feedback
190
+ - πŸ”„ **Multi-AI System** - Fallback system ensures 24/7 availability
191
+ - πŸ’― **Detailed Marking** - Comprehensive feedback on all answers
192
+
193
+ ### πŸ” Access Required:
194
+ Students need a **school code** to access the platforms. Contact your teacher or administrator.
195
+ """)
196
+
197
+ # STUDENT LOGIN TAB
198
+ with gr.Tab("πŸ‘¨β€πŸŽ“ Student Login"):
199
+ gr.Markdown("## πŸ‘¨β€πŸŽ“ Student Access")
200
+
201
+ with gr.Row():
202
+ student_code_input = gr.Textbox(
203
+ label="Enter Your School Code",
204
+ placeholder="8-character code (e.g., ABC12345)",
205
+ max_lines=1
206
+ )
207
+
208
+ student_login_btn = gr.Button("πŸ”“ Verify Access", variant="primary", size="lg")
209
+ student_status = gr.Markdown("")
210
+
211
+ student_platforms = gr.HTML(visible=False)
212
+
213
+ def student_login(code):
214
+ success, message = verify_student(code)
215
+ if success:
216
+ return message, gr.HTML(create_platform_links(), visible=True)
217
+ return message, gr.HTML(visible=False)
218
+
219
+ student_login_btn.click(
220
+ student_login,
221
+ inputs=[student_code_input],
222
+ outputs=[student_status, student_platforms]
223
+ )
224
+
225
+ # ADMIN TAB
226
+ with gr.Tab("πŸ” Admin Panel"):
227
+ gr.Markdown("## πŸ” Administrator Panel")
228
+
229
+ admin_password_global = gr.Textbox(
230
+ label="Admin Password",
231
+ type="password",
232
+ placeholder="Enter admin password"
233
+ )
234
+
235
+ gr.Markdown("---")
236
+
237
+ # Create new code section
238
+ gr.Markdown("### βž• Generate New School Code")
239
+ with gr.Row():
240
+ school_name_input = gr.Textbox(
241
+ label="School/Institution Name",
242
+ placeholder="Enter school or group name"
243
+ )
244
+ create_code_btn = gr.Button("πŸ”‘ Generate Code", variant="primary")
245
+
246
+ create_status = gr.Markdown("")
247
+
248
+ create_code_btn.click(
249
+ create_school_code,
250
+ inputs=[school_name_input, admin_password_global],
251
+ outputs=[create_status, gr.Textbox(visible=False)]
252
+ )
253
+
254
+ gr.Markdown("---")
255
+
256
+ # View all codes section
257
+ gr.Markdown("### πŸ“‹ Manage School Codes")
258
+ view_codes_btn = gr.Button("πŸ” View All Codes", variant="secondary")
259
+ codes_display = gr.Markdown("")
260
+
261
+ view_codes_btn.click(
262
+ get_all_codes,
263
+ inputs=[admin_password_global],
264
+ outputs=[codes_display]
265
+ )
266
+
267
+ gr.Markdown("---")
268
+
269
+ # Toggle code status
270
+ gr.Markdown("### βš™οΈ Activate/Deactivate Code")
271
+ with gr.Row():
272
+ toggle_code_input = gr.Textbox(
273
+ label="School Code",
274
+ placeholder="Enter code to toggle"
275
+ )
276
+ toggle_btn = gr.Button("πŸ”„ Toggle Status", variant="secondary")
277
+
278
+ toggle_status = gr.Markdown("")
279
+
280
+ toggle_btn.click(
281
+ toggle_code_status,
282
+ inputs=[toggle_code_input, admin_password_global],
283
+ outputs=[toggle_status]
284
+ )
285
+
286
+ # Footer
287
+ gr.Markdown("""
288
+ ---
289
+ <div style='text-align: center; color: #6b7280; font-size: 14px;'>
290
+ Β© 2024 IGCSE/GCSE Master β€’ Powered by Gemini AI, Cohere, Z.ai & MiniMax<br>
291
+ Multi-AI fallback system ensures 24/7 availability
292
+ </div>
293
+ """)
294
+
295
+ # Launch the app
296
+ if __name__ == "__main__":
297
+ app.launch()