mlmihjaz commited on
Commit
3b51e2a
·
verified ·
1 Parent(s): e930e00

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +636 -199
index.html CHANGED
@@ -1,202 +1,592 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>EduConnect - Learning Management System</title>
7
-
8
  <!-- Google Fonts -->
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
12
-
13
  <!-- FontAwesome -->
14
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
15
 
16
  <style>
17
  :root {
18
- --primary: #008069; /* WhatsApp Green-ish */
19
  --primary-dark: #005c4b;
20
  --accent: #34b7f1;
21
- --bg-body: #e5ddd5; /* Chat background color */
 
22
  --bg-white: #ffffff;
23
  --text-dark: #111b21;
24
  --text-gray: #667781;
25
  --border: #e9edef;
26
- --shadow: 0 2px 5px rgba(0,0,0,0.05);
27
  --radius: 12px;
28
  --danger: #ef5350;
29
  }
30
 
31
- * { box-sizing: border-box; margin: 0; padding: 0; outline: none; }
32
- body { font-family: 'Inter', sans-serif; background-color: #f0f2f5; color: var(--text-dark); height: 100vh; overflow: hidden; }
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  /* --- Utilities --- */
35
- .hidden { display: none !important; }
36
- .flex { display: flex; }
37
- .flex-col { flex-direction: column; }
38
- .center { align-items: center; justify-content: center; }
39
- .btn { cursor: pointer; border: none; padding: 10px 20px; border-radius: 24px; font-weight: 600; transition: 0.2s; font-size: 0.9rem; }
40
- .btn-primary { background: var(--primary); color: white; }
41
- .btn-primary:hover { background: var(--primary-dark); }
42
- .btn-outline { background: transparent; border: 1px solid var(--primary); color: var(--primary); }
43
- .btn-icon { background: transparent; color: var(--text-gray); font-size: 1.2rem; padding: 8px; border-radius: 50%; }
44
- .btn-icon:hover { background: rgba(0,0,0,0.05); color: var(--primary); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
  /* --- Login Screen --- */
47
  #loginScreen {
48
- position: fixed; top: 0; left: 0; width: 100%; height: 100%;
 
 
 
 
49
  background: linear-gradient(135deg, var(--primary) 0%, #00a884 100%);
50
- z-index: 1000; display: flex; align-items: center; justify-content: center;
 
 
 
51
  }
 
52
  .login-card {
53
- background: white; padding: 3rem; border-radius: 20px; width: 90%; max-width: 400px;
54
- box-shadow: 0 20px 40px rgba(0,0,0,0.2); text-align: center;
 
 
 
 
 
55
  }
56
- .login-card h1 { color: var(--primary); margin-bottom: 1rem; }
 
 
 
 
 
57
  .role-btn {
58
- display: flex; align-items: center; gap: 10px; width: 100%; margin-bottom: 1rem;
59
- padding: 1rem; border: 2px solid #eee; border-radius: 12px; background: white;
60
- font-size: 1rem; color: #555; transition: 0.2s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
- .role-btn:hover { border-color: var(--primary); background: #f0fdf9; color: var(--primary); }
63
 
64
  /* --- App Layout --- */
65
- #appContainer { display: flex; height: 100vh; width: 100vw; }
66
-
 
 
 
 
67
  /* Sidebar (Categories) */
68
  .sidebar {
69
- width: 280px; background: white; border-right: 1px solid var(--border);
70
- display: flex; flex-direction: column; z-index: 10;
 
 
 
 
71
  }
72
- .brand { padding: 20px; font-size: 1.5rem; font-weight: 700; color: var(--primary); display: flex; align-items: center; gap: 10px; }
73
- .category-list { flex: 1; overflow-y: auto; padding: 10px; }
74
-
75
- /* Stack Buttons for Categories */
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  .cat-btn {
77
- width: 100%; text-align: left; padding: 12px 16px; margin-bottom: 5px;
78
- background: #f5f6f6; border: none; border-radius: 10px; color: var(--text-dark);
79
- font-weight: 500; display: flex; justify-content: space-between; align-items: center;
80
- transition: 0.2s; cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
- .cat-btn:hover { background: #e9edef; }
83
- .cat-btn.active { background: var(--primary); color: white; }
84
- .cat-btn .badge { font-size: 0.75rem; background: rgba(0,0,0,0.1); padding: 2px 6px; border-radius: 4px; }
85
 
86
  /* Main Content Area */
87
- .main-content { flex: 1; display: flex; flex-direction: column; background: #f0f2f5; position: relative; }
88
-
 
 
 
 
 
 
89
  /* Header */
90
  .top-header {
91
- height: 60px; background: white; border-bottom: 1px solid var(--border);
92
- display: flex; align-items: center; justify-content: space-between; padding: 0 20px;
 
 
 
 
 
93
  }
94
- .user-info { display: flex; align-items: center; gap: 10px; }
95
- .user-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; }
96
-
 
 
 
 
 
 
 
 
 
 
 
97
  /* Subcategories (Subjects) Strip */
98
  .subject-strip {
99
- padding: 15px 20px; background: white; overflow-x: auto; white-space: nowrap;
100
- border-bottom: 1px solid var(--border); display: flex; gap: 10px;
 
 
 
 
 
101
  }
 
102
  .subject-pill {
103
- padding: 8px 16px; background: #f0f2f5; border-radius: 20px; color: var(--text-dark);
104
- font-size: 0.9rem; cursor: pointer; transition: 0.2s; border: 1px solid transparent;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  }
106
- .subject-pill:hover { background: #e9edef; }
107
- .subject-pill.active { background: var(--primary); color: white; }
108
 
109
  /* Feed Area */
110
  .feed-container {
111
- flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 20px;
 
 
 
 
 
112
  background-image: url('https://user-images.githubusercontent.com/15075759/28719144-86dc0f70-73b1-11e7-911d-60d70fcded21.png');
113
- background-blend-mode: overlay; background-color: rgba(255,255,255,0.9);
 
114
  }
115
 
116
  /* Feed Card (WhatsApp Style) */
117
  .msg-bubble {
118
- max-width: 600px; align-self: flex-start; background: white;
119
- padding: 10px; border-radius: 8px; box-shadow: var(--shadow);
120
- position: relative; animation: slideUp 0.3s ease; width: 100%;
 
 
 
 
 
 
121
  }
122
- .msg-bubble.sent { align-self: flex-end; background: #d9fdd3; }
123
-
124
- .msg-meta { display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 0.8rem; color: var(--text-gray); }
125
- .msg-content { font-size: 1rem; line-height: 1.4; color: var(--text-dark); }
126
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  .media-preview {
128
- margin-top: 10px; border-radius: 8px; overflow: hidden; background: #000;
129
- max-width: 100%; position: relative; cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  }
131
- .media-preview video, .media-preview img { width: 100%; max-height: 300px; object-fit: contain; display: block; }
132
  .play-btn {
133
- position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
134
- color: white; font-size: 3rem; opacity: 0.8; text-shadow: 0 2px 5px rgba(0,0,0,0.5);
 
 
 
 
 
 
135
  }
 
136
  .file-attach {
137
- display: flex; align-items: center; gap: 15px; padding: 10px;
138
- background: #f9f9f9; border-radius: 8px; margin-top: 5px; cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
- .file-icon { font-size: 2rem; color: var(--danger); }
141
- .file-info h4 { font-size: 0.9rem; margin-bottom: 2px; }
142
- .file-info span { font-size: 0.75rem; color: #888; }
143
 
144
- /* Floating Action Button for Upload */
145
  .fab {
146
- position: absolute; bottom: 30px; right: 30px;
147
- width: 60px; height: 60px; background: var(--primary); color: white;
148
- border-radius: 50%; display: flex; align-items: center; justify-content: center;
149
- font-size: 1.5rem; box-shadow: 0 4px 10px rgba(0,128,105,0.4); cursor: pointer;
150
- transition: 0.3s; z-index: 50;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  }
152
- .fab:hover { transform: scale(1.1); }
153
 
154
- /* Chat Modal */
155
  .modal-overlay {
156
- position: fixed; top: 0; left: 0; width: 100%; height: 100%;
157
- background: rgba(0,0,0,0.5); z-index: 200; display: flex; align-items: center; justify-content: center;
158
- opacity: 0; pointer-events: none; transition: 0.3s;
 
 
 
 
 
 
 
 
 
 
159
  }
160
- .modal-overlay.open { opacity: 1; pointer-events: all; }
 
 
 
 
 
161
  .modal-box {
162
- background: white; width: 90%; max-width: 500px; height: 80vh; border-radius: 16px;
163
- display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
- .modal-header { padding: 15px; background: var(--primary); color: white; display: flex; justify-content: space-between; align-items: center; }
166
- .chat-area { flex: 1; padding: 15px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; background: #e5ddd5; }
167
- .chat-input-area { padding: 10px; background: #f0f0f0; display: flex; gap: 10px; }
168
- .chat-input-area input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 20px; }
169
 
170
- /* Upload Modal Content */
171
- .upload-options { padding: 20px; display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
172
  .upload-card {
173
- border: 2px dashed #ddd; border-radius: 12px; padding: 20px; text-align: center;
174
- cursor: pointer; transition: 0.2s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
176
- .upload-card:hover { border-color: var(--primary); background: #f0fdf9; }
177
 
178
  /* Sort Bar */
179
  .sort-bar {
180
- padding: 10px 20px; background: white; border-bottom: 1px solid var(--border);
181
- display: flex; align-items: center; gap: 10px; font-size: 0.9rem; color: var(--text-gray);
 
 
 
 
 
 
182
  }
183
- select { padding: 5px 10px; border-radius: 6px; border: 1px solid #ddd; }
184
 
185
- @keyframes slideUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
  /* Mobile Responsive */
188
  @media (max-width: 768px) {
189
- .sidebar { position: absolute; left: -280px; height: 100%; transition: 0.3s; box-shadow: 2px 0 10px rgba(0,0,0,0.1); }
 
 
 
 
 
 
190
  .sidebar.open { left: 0; }
191
  .menu-toggle { display: block; }
192
  }
193
  @media (min-width: 769px) { .menu-toggle { display: none; } }
194
 
195
  .anycoder-link {
196
- font-size: 0.8rem; color: #888; text-decoration: none; margin-top: 20px; display: inline-block;
 
 
 
 
197
  }
198
  </style>
199
  </head>
 
200
  <body>
201
 
202
  <!-- Login Screen -->
@@ -207,7 +597,7 @@
207
  </div>
208
  <h1>EduConnect</h1>
209
  <p style="color: #666; margin-bottom: 2rem;">Select your role to continue</p>
210
-
211
  <button class="role-btn" onclick="app.login('admin')">
212
  <i class="fa-solid fa-user-shield" style="color: var(--primary);"></i>
213
  <div style="text-align: left;">
@@ -223,7 +613,7 @@
223
  <span style="font-size: 0.8rem;">View assigned materials & chat</span>
224
  </div>
225
  </button>
226
-
227
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
228
  Built with anycoder
229
  </a>
@@ -232,7 +622,7 @@
232
 
233
  <!-- Main App Container -->
234
  <div id="appContainer" class="hidden">
235
-
236
  <!-- Sidebar: Categories (Grades) -->
237
  <aside class="sidebar" id="sidebar">
238
  <div class="brand">
@@ -250,7 +640,7 @@
250
 
251
  <!-- Main Content -->
252
  <main class="main-content">
253
-
254
  <!-- Top Header -->
255
  <header class="top-header">
256
  <div class="flex center" style="gap: 15px;">
@@ -283,6 +673,7 @@
283
  <option value="pdf">PDFs & Docs</option>
284
  <option value="text">Text Only</option>
285
  </select>
 
286
  </div>
287
 
288
  <!-- Feed Area (WhatsApp Style) -->
@@ -305,18 +696,40 @@
305
  <h3>Upload Content</h3>
306
  <button class="btn-icon" style="color: white;" onclick="app.closeModals()"><i class="fa-solid fa-times"></i></button>
307
  </div>
308
- <div class="upload-options">
309
- <div class="upload-card" onclick="app.simulateUpload('video')">
310
- <i class="fa-solid fa-video" style="font-size: 2rem; color: var(--primary); margin-bottom: 10px;"></i>
311
- <p>Upload Video</p>
312
- </div>
313
- <div class="upload-card" onclick="app.simulateUpload('pdf')">
314
- <i class="fa-solid fa-file-pdf" style="font-size: 2rem; color: var(--danger); margin-bottom: 10px;"></i>
315
- <p>Upload PDF</p>
 
 
 
 
 
 
 
316
  </div>
317
- <div class="upload-card" onclick="app.simulateUpload('text')">
318
- <i class="fa-solid fa-align-left" style="font-size: 2rem; color: var(--accent); margin-bottom: 10px;"></i>
319
- <p>Post Text</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  </div>
321
  </div>
322
  </div>
@@ -342,39 +755,28 @@
342
  <script>
343
  /**
344
  * EduConnect Application Logic
345
- * Simulates PHP/MySQL architecture using localStorage and JavaScript objects.
346
  */
347
  const app = {
348
- // Data Store (Simulating MySQL Tables)
349
  data: {
350
  currentUser: null,
351
  categories: [
352
- { id: 1, name: 'Grade 1' },
353
- { id: 2, name: 'Grade 2' },
354
- { id: 3, name: 'Grade 3' },
355
- { id: 4, name: 'Grade 4' },
356
- { id: 5, name: 'Grade 5' },
357
- { id: 6, name: 'Grade 6' },
358
- { id: 7, name: 'Grade 7' },
359
- { id: 8, name: 'Grade 8' },
360
- { id: 9, name: 'Grade 9' },
361
- { id: 10, name: 'Grade 10' },
362
- { id: 11, name: 'Grade 11' },
363
- { id: 12, name: 'Grade 12' }
364
  ],
365
  subcategories: [
366
- { id: 1, catId: 1, name: 'Mathematics' },
367
- { id: 2, catId: 1, name: 'English' },
368
- { id: 3, catId: 1, name: 'Science' },
369
- { id: 4, catId: 2, name: 'Mathematics' },
370
- { id: 5, catId: 2, name: 'English' },
371
- { id: 6, catId: 3, name: 'Physics' }, // Example for higher grades
372
  ],
373
  content: [
374
  { id: 1, subId: 1, type: 'video', url: 'https://picsum.photos/seed/vid1/600/300', title: 'Introduction to Addition', author: 'Admin', date: '10:00 AM' },
375
  { id: 2, subId: 1, type: 'pdf', title: 'Chapter 1 Exercises', author: 'Admin', date: '10:05 AM' },
376
- { id: 3, subId: 2, type: 'text', text: 'Please read pages 10-15 for homework.', author: 'Admin', date: 'Yesterday' },
377
- { id: 4, subId: 2, type: 'video', url: 'https://picsum.photos/seed/vid2/600/300', title: 'Vocabulary Lesson', author: 'Admin', date: 'Yesterday' }
378
  ],
379
  chat: [
380
  { sender: 'Admin', text: 'Welcome to the new semester!', time: '09:00 AM' }
@@ -388,11 +790,9 @@
388
 
389
  // --- Authentication ---
390
  login(role) {
391
- // Simulate User Session
392
  this.data.currentUser = {
393
  name: role === 'admin' ? 'Administrator' : 'Student User',
394
  role: role,
395
- // Students only have access to Grade 1 and 2 for demo purposes
396
  access: role === 'student' ? [1, 2] : null
397
  };
398
 
@@ -400,7 +800,6 @@
400
  document.getElementById('appContainer').classList.remove('hidden');
401
  document.getElementById('userName').textContent = this.data.currentUser.name;
402
 
403
- // Show FAB only for Admin
404
  if (role === 'admin') {
405
  document.getElementById('fab').classList.remove('hidden');
406
  }
@@ -410,15 +809,13 @@
410
  },
411
 
412
  logout() {
413
- location.reload(); // Simple reload to clear state for this demo
414
  },
415
 
416
  // --- Navigation & Rendering ---
417
  renderCategories() {
418
  const list = document.getElementById('categoryList');
419
  list.innerHTML = '';
420
-
421
- // Filter based on permissions
422
  const visibleCats = this.data.categories.filter(c => {
423
  if (this.data.currentUser.role === 'admin') return true;
424
  return this.data.currentUser.access.includes(c.id);
@@ -435,20 +832,17 @@
435
 
436
  selectCategory(cat) {
437
  this.state.selectedCatId = cat.id;
438
- this.state.selectedSubId = null; // Reset sub selection
439
-
440
- // UI Updates
441
  document.getElementById('pageTitle').textContent = cat.name;
442
- this.renderCategories(); // Re-render to update active class
443
 
444
- // Render Subcategories (Subjects)
445
  const strip = document.getElementById('subjectStrip');
446
  strip.innerHTML = '';
447
-
448
  const subs = this.data.subcategories.filter(s => s.catId === cat.id);
 
449
  if (subs.length === 0) {
450
  strip.innerHTML = '<span style="color:#888; padding:10px;">No subjects available.</span>';
451
- this.renderFeed(); // Clear feed
452
  return;
453
  }
454
 
@@ -460,26 +854,21 @@
460
  strip.appendChild(pill);
461
  });
462
 
463
- // Auto-select first subject
464
- this.selectSubject(subs[0], strip.children[0]);
465
  },
466
 
467
  selectSubject(sub, element) {
468
  this.state.selectedSubId = sub.id;
469
-
470
- // UI Highlight
471
  const pills = document.querySelectorAll('.subject-pill');
472
  pills.forEach(p => p.classList.remove('active'));
473
  if(element) element.classList.add('active');
474
-
475
  this.renderFeed();
476
  },
477
 
478
- // --- Feed Logic (WhatsApp Style) ---
479
  renderFeed() {
480
  const container = document.getElementById('feedContainer');
481
  container.innerHTML = '';
482
-
483
  const filterType = document.getElementById('sortSelect').value;
484
 
485
  // Filter Content
@@ -489,16 +878,23 @@
489
  return matchesSub && matchesType;
490
  });
491
 
 
 
492
  if (items.length === 0) {
493
  container.innerHTML = `
494
  <div style="text-align:center; margin-top:50px; color:#888;">
495
  <i class="fa-solid fa-box-open" style="font-size:3rem; margin-bottom:10px;"></i>
496
- <p>No content found for this selection.</p>
497
  </div>
498
  `;
499
  return;
500
  }
501
 
 
 
 
 
 
502
  items.forEach(item => {
503
  const bubble = document.createElement('div');
504
  bubble.className = 'msg-bubble';
@@ -534,34 +930,25 @@
534
  </div>
535
  ${mediaHtml}
536
  `;
537
- container.appendChild(bubble);
538
  });
 
 
539
  },
540
 
541
  // --- Chat System ---
542
- openChat() {
543
- document.getElementById('chatModal').classList.add('open');
544
- },
545
 
546
  sendMessage() {
547
  const input = document.getElementById('chatInput');
548
  const text = input.value.trim();
549
  if (!text) return;
550
-
551
- // Add User Message
552
  this.addChatMessage(this.data.currentUser.name, text);
553
  input.value = '';
554
-
555
- // Simulate Bot/Admin Reply
556
  setTimeout(() => {
557
- const replies = [
558
- "Thanks for your message! I'll check it.",
559
- "Please check the 'Grade 1' Mathematics section for the update.",
560
- "Got it.",
561
- "Have you finished the homework?"
562
- ];
563
- const randomReply = replies[Math.floor(Math.random() * replies.length)];
564
- this.addChatMessage('Admin', randomReply);
565
  }, 1000);
566
  },
567
 
@@ -569,20 +956,14 @@
569
  const area = document.getElementById('chatArea');
570
  const div = document.createElement('div');
571
  const isMe = sender === this.data.currentUser.name;
572
-
573
  div.className = `msg-bubble ${isMe ? 'sent' : ''}`;
574
- // Simplified chat bubble style
575
  div.style.maxWidth = '80%';
576
- div.innerHTML = `
577
- <div style="font-size:0.75rem; color:#666; margin-bottom:2px;">${sender}</div>
578
- <div>${text}</div>
579
- `;
580
  area.appendChild(div);
581
  area.scrollTop = area.scrollHeight;
582
  },
583
 
584
  renderChat() {
585
- // Initial load of chat history
586
  const area = document.getElementById('chatArea');
587
  area.innerHTML = '';
588
  this.data.chat.forEach(c => this.addChatMessage(c.sender, c.text));
@@ -594,12 +975,7 @@
594
  document.getElementById('uploadModal').classList.add('open');
595
  },
596
 
597
- closeModals() {
598
- document.querySelectorAll('.modal-overlay').forEach(el => el.classList.remove('open'));
599
- },
600
-
601
  simulateUpload(type) {
602
- // Simulate adding new content to the DB
603
  const newContent = {
604
  id: Date.now(),
605
  subId: this.state.selectedSubId,
@@ -614,26 +990,87 @@
614
  } else if (type === 'pdf') {
615
  newContent.title = 'Worksheet_' + Math.floor(Math.random() * 100) + '.pdf';
616
  } else {
617
- newContent.text = 'Notice: Please bring your notebooks tomorrow.';
618
  }
619
 
620
- this.data.content.unshift(newContent); // Add to top
621
  this.closeModals();
622
  this.renderFeed();
623
-
624
- // Show simple toast feedback (simulated)
625
- const fab = document.getElementById('fab');
626
- fab.style.background = '#4caf50';
627
- setTimeout(() => fab.style.background = '', 1000);
628
  },
629
 
630
  toggleSidebar() {
631
  document.getElementById('sidebar').classList.toggle('open');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
  }
633
  };
634
-
635
- // Initialize empty state or check login
636
- // (Login is handled by buttons on screen)
637
  </script>
638
  </body>
 
639
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
+
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <title>EduConnect - Learning Management System</title>
8
+
9
  <!-- Google Fonts -->
10
  <link rel="preconnect" href="https://fonts.googleapis.com">
11
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
12
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
13
+
14
  <!-- FontAwesome -->
15
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
16
 
17
  <style>
18
  :root {
19
+ --primary: #008069;
20
  --primary-dark: #005c4b;
21
  --accent: #34b7f1;
22
+ --chaos: #9c27b0; /* Color for the 'Lies' feature */
23
+ --bg-body: #e5ddd5;
24
  --bg-white: #ffffff;
25
  --text-dark: #111b21;
26
  --text-gray: #667781;
27
  --border: #e9edef;
28
+ --shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
29
  --radius: 12px;
30
  --danger: #ef5350;
31
  }
32
 
33
+ * {
34
+ box-sizing: border-box;
35
+ margin: 0;
36
+ padding: 0;
37
+ outline: none;
38
+ }
39
+
40
+ body {
41
+ font-family: 'Inter', sans-serif;
42
+ background-color: #f0f2f5;
43
+ color: var(--text-dark);
44
+ height: 100vh;
45
+ overflow: hidden;
46
+ }
47
 
48
  /* --- Utilities --- */
49
+ .hidden {
50
+ display: none !important;
51
+ }
52
+
53
+ .flex {
54
+ display: flex;
55
+ }
56
+
57
+ .flex-col {
58
+ flex-direction: column;
59
+ }
60
+
61
+ .center {
62
+ align-items: center;
63
+ justify-content: center;
64
+ }
65
+
66
+ .btn {
67
+ cursor: pointer;
68
+ border: none;
69
+ padding: 10px 20px;
70
+ border-radius: 24px;
71
+ font-weight: 600;
72
+ transition: 0.2s;
73
+ font-size: 0.9rem;
74
+ }
75
+
76
+ .btn-primary {
77
+ background: var(--primary);
78
+ color: white;
79
+ }
80
+
81
+ .btn-primary:hover {
82
+ background: var(--primary-dark);
83
+ }
84
+
85
+ .btn-outline {
86
+ background: transparent;
87
+ border: 1px solid var(--primary);
88
+ color: var(--primary);
89
+ }
90
+
91
+ .btn-chaos {
92
+ background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
93
+ color: white;
94
+ box-shadow: 0 4px 15px rgba(37, 117, 252, 0.3);
95
+ }
96
+
97
+ .btn-chaos:hover {
98
+ transform: translateY(-2px);
99
+ box-shadow: 0 6px 20px rgba(37, 117, 252, 0.4);
100
+ }
101
+
102
+ .btn-icon {
103
+ background: transparent;
104
+ color: var(--text-gray);
105
+ font-size: 1.2rem;
106
+ padding: 8px;
107
+ border-radius: 50%;
108
+ }
109
+
110
+ .btn-icon:hover {
111
+ background: rgba(0, 0, 0, 0.05);
112
+ color: var(--primary);
113
+ }
114
 
115
  /* --- Login Screen --- */
116
  #loginScreen {
117
+ position: fixed;
118
+ top: 0;
119
+ left: 0;
120
+ width: 100%;
121
+ height: 100%;
122
  background: linear-gradient(135deg, var(--primary) 0%, #00a884 100%);
123
+ z-index: 1000;
124
+ display: flex;
125
+ align-items: center;
126
+ justify-content: center;
127
  }
128
+
129
  .login-card {
130
+ background: white;
131
+ padding: 3rem;
132
+ border-radius: 20px;
133
+ width: 90%;
134
+ max-width: 400px;
135
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
136
+ text-align: center;
137
  }
138
+
139
+ .login-card h1 {
140
+ color: var(--primary);
141
+ margin-bottom: 1rem;
142
+ }
143
+
144
  .role-btn {
145
+ display: flex;
146
+ align-items: center;
147
+ gap: 10px;
148
+ width: 100%;
149
+ margin-bottom: 1rem;
150
+ padding: 1rem;
151
+ border: 2px solid #eee;
152
+ border-radius: 12px;
153
+ background: white;
154
+ font-size: 1rem;
155
+ color: #555;
156
+ transition: 0.2s;
157
+ }
158
+
159
+ .role-btn:hover {
160
+ border-color: var(--primary);
161
+ background: #f0fdf9;
162
+ color: var(--primary);
163
  }
 
164
 
165
  /* --- App Layout --- */
166
+ #appContainer {
167
+ display: flex;
168
+ height: 100vh;
169
+ width: 100vw;
170
+ }
171
+
172
  /* Sidebar (Categories) */
173
  .sidebar {
174
+ width: 280px;
175
+ background: white;
176
+ border-right: 1px solid var(--border);
177
+ display: flex;
178
+ flex-direction: column;
179
+ z-index: 10;
180
  }
181
+
182
+ .brand {
183
+ padding: 20px;
184
+ font-size: 1.5rem;
185
+ font-weight: 700;
186
+ color: var(--primary);
187
+ display: flex;
188
+ align-items: center;
189
+ gap: 10px;
190
+ }
191
+
192
+ .category-list {
193
+ flex: 1;
194
+ overflow-y: auto;
195
+ padding: 10px;
196
+ }
197
+
198
  .cat-btn {
199
+ width: 100%;
200
+ text-align: left;
201
+ padding: 12px 16px;
202
+ margin-bottom: 5px;
203
+ background: #f5f6f6;
204
+ border: none;
205
+ border-radius: 10px;
206
+ color: var(--text-dark);
207
+ font-weight: 500;
208
+ display: flex;
209
+ justify-content: space-between;
210
+ align-items: center;
211
+ transition: 0.2s;
212
+ cursor: pointer;
213
+ }
214
+
215
+ .cat-btn:hover {
216
+ background: #e9edef;
217
+ }
218
+
219
+ .cat-btn.active {
220
+ background: var(--primary);
221
+ color: white;
222
+ }
223
+
224
+ .cat-btn .badge {
225
+ font-size: 0.75rem;
226
+ background: rgba(0, 0, 0, 0.1);
227
+ padding: 2px 6px;
228
+ border-radius: 4px;
229
  }
 
 
 
230
 
231
  /* Main Content Area */
232
+ .main-content {
233
+ flex: 1;
234
+ display: flex;
235
+ flex-direction: column;
236
+ background: #f0f2f5;
237
+ position: relative;
238
+ }
239
+
240
  /* Header */
241
  .top-header {
242
+ height: 60px;
243
+ background: white;
244
+ border-bottom: 1px solid var(--border);
245
+ display: flex;
246
+ align-items: center;
247
+ justify-content: space-between;
248
+ padding: 0 20px;
249
  }
250
+
251
+ .user-info {
252
+ display: flex;
253
+ align-items: center;
254
+ gap: 10px;
255
+ }
256
+
257
+ .user-avatar {
258
+ width: 40px;
259
+ height: 40px;
260
+ border-radius: 50%;
261
+ object-fit: cover;
262
+ }
263
+
264
  /* Subcategories (Subjects) Strip */
265
  .subject-strip {
266
+ padding: 15px 20px;
267
+ background: white;
268
+ overflow-x: auto;
269
+ white-space: nowrap;
270
+ border-bottom: 1px solid var(--border);
271
+ display: flex;
272
+ gap: 10px;
273
  }
274
+
275
  .subject-pill {
276
+ padding: 8px 16px;
277
+ background: #f0f2f5;
278
+ border-radius: 20px;
279
+ color: var(--text-dark);
280
+ font-size: 0.9rem;
281
+ cursor: pointer;
282
+ transition: 0.2s;
283
+ border: 1px solid transparent;
284
+ }
285
+
286
+ .subject-pill:hover {
287
+ background: #e9edef;
288
+ }
289
+
290
+ .subject-pill.active {
291
+ background: var(--primary);
292
+ color: white;
293
  }
 
 
294
 
295
  /* Feed Area */
296
  .feed-container {
297
+ flex: 1;
298
+ overflow-y: auto;
299
+ padding: 20px;
300
+ display: flex;
301
+ flex-direction: column;
302
+ gap: 20px;
303
  background-image: url('https://user-images.githubusercontent.com/15075759/28719144-86dc0f70-73b1-11e7-911d-60d70fcded21.png');
304
+ background-blend-mode: overlay;
305
+ background-color: rgba(255, 255, 255, 0.9);
306
  }
307
 
308
  /* Feed Card (WhatsApp Style) */
309
  .msg-bubble {
310
+ max-width: 600px;
311
+ align-self: flex-start;
312
+ background: white;
313
+ padding: 10px;
314
+ border-radius: 8px;
315
+ box-shadow: var(--shadow);
316
+ position: relative;
317
+ animation: slideUp 0.3s ease;
318
+ width: 100%;
319
  }
320
+
321
+ .msg-bubble.sent {
322
+ align-self: flex-end;
323
+ background: #d9fdd3;
324
+ }
325
+
326
+ .msg-meta {
327
+ display: flex;
328
+ justify-content: space-between;
329
+ margin-bottom: 5px;
330
+ font-size: 0.8rem;
331
+ color: var(--text-gray);
332
+ }
333
+
334
+ .msg-content {
335
+ font-size: 1rem;
336
+ line-height: 1.4;
337
+ color: var(--text-dark);
338
+ }
339
+
340
  .media-preview {
341
+ margin-top: 10px;
342
+ border-radius: 8px;
343
+ overflow: hidden;
344
+ background: #000;
345
+ max-width: 100%;
346
+ position: relative;
347
+ cursor: pointer;
348
+ }
349
+
350
+ .media-preview video,
351
+ .media-preview img {
352
+ width: 100%;
353
+ max-height: 300px;
354
+ object-fit: contain;
355
+ display: block;
356
  }
357
+
358
  .play-btn {
359
+ position: absolute;
360
+ top: 50%;
361
+ left: 50%;
362
+ transform: translate(-50%, -50%);
363
+ color: white;
364
+ font-size: 3rem;
365
+ opacity: 0.8;
366
+ text-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
367
  }
368
+
369
  .file-attach {
370
+ display: flex;
371
+ align-items: center;
372
+ gap: 15px;
373
+ padding: 10px;
374
+ background: #f9f9f9;
375
+ border-radius: 8px;
376
+ margin-top: 5px;
377
+ cursor: pointer;
378
+ }
379
+
380
+ .file-icon {
381
+ font-size: 2rem;
382
+ color: var(--danger);
383
+ }
384
+
385
+ .file-info h4 {
386
+ font-size: 0.9rem;
387
+ margin-bottom: 2px;
388
+ }
389
+
390
+ .file-info span {
391
+ font-size: 0.75rem;
392
+ color: #888;
393
  }
 
 
 
394
 
395
+ /* Floating Action Button */
396
  .fab {
397
+ position: absolute;
398
+ bottom: 30px;
399
+ right: 30px;
400
+ width: 60px;
401
+ height: 60px;
402
+ background: var(--primary);
403
+ color: white;
404
+ border-radius: 50%;
405
+ display: flex;
406
+ align-items: center;
407
+ justify-content: center;
408
+ font-size: 1.5rem;
409
+ box-shadow: 0 4px 10px rgba(0, 128, 105, 0.4);
410
+ cursor: pointer;
411
+ transition: 0.3s;
412
+ z-index: 50;
413
+ }
414
+
415
+ .fab:hover {
416
+ transform: scale(1.1);
417
  }
 
418
 
419
+ /* Modals */
420
  .modal-overlay {
421
+ position: fixed;
422
+ top: 0;
423
+ left: 0;
424
+ width: 100%;
425
+ height: 100%;
426
+ background: rgba(0, 0, 0, 0.5);
427
+ z-index: 200;
428
+ display: flex;
429
+ align-items: center;
430
+ justify-content: center;
431
+ opacity: 0;
432
+ pointer-events: none;
433
+ transition: 0.3s;
434
  }
435
+
436
+ .modal-overlay.open {
437
+ opacity: 1;
438
+ pointer-events: all;
439
+ }
440
+
441
  .modal-box {
442
+ background: white;
443
+ width: 90%;
444
+ max-width: 500px;
445
+ height: 80vh;
446
+ border-radius: 16px;
447
+ display: flex;
448
+ flex-direction: column;
449
+ overflow: hidden;
450
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
451
+ }
452
+
453
+ .modal-header {
454
+ padding: 15px;
455
+ background: var(--primary);
456
+ color: white;
457
+ display: flex;
458
+ justify-content: space-between;
459
+ align-items: center;
460
+ }
461
+
462
+ .chat-area {
463
+ flex: 1;
464
+ padding: 15px;
465
+ overflow-y: auto;
466
+ display: flex;
467
+ flex-direction: column;
468
+ gap: 10px;
469
+ background: #e5ddd5;
470
+ }
471
+
472
+ .chat-input-area {
473
+ padding: 10px;
474
+ background: #f0f0f0;
475
+ display: flex;
476
+ gap: 10px;
477
+ }
478
+
479
+ .chat-input-area input {
480
+ flex: 1;
481
+ padding: 10px;
482
+ border: 1px solid #ddd;
483
+ border-radius: 20px;
484
+ }
485
+
486
+ /* Upload Options */
487
+ .upload-options {
488
+ padding: 20px;
489
+ display: grid;
490
+ grid-template-columns: 1fr 1fr;
491
+ gap: 15px;
492
  }
 
 
 
 
493
 
 
 
494
  .upload-card {
495
+ border: 2px dashed #ddd;
496
+ border-radius: 12px;
497
+ padding: 20px;
498
+ text-align: center;
499
+ cursor: pointer;
500
+ transition: 0.2s;
501
+ }
502
+
503
+ .upload-card:hover {
504
+ border-color: var(--primary);
505
+ background: #f0fdf9;
506
+ }
507
+
508
+ /* Lie Generator Section */
509
+ .lie-generator-section {
510
+ padding: 20px;
511
+ border-top: 1px solid #eee;
512
+ background: #fafafa;
513
+ }
514
+
515
+ .lie-generator-section h4 {
516
+ margin-bottom: 10px;
517
+ color: var(--chaos);
518
+ display: flex;
519
+ align-items: center;
520
+ gap: 8px;
521
+ }
522
+
523
+ .stats-display {
524
+ font-size: 0.8rem;
525
+ color: #666;
526
+ margin-bottom: 10px;
527
  }
 
528
 
529
  /* Sort Bar */
530
  .sort-bar {
531
+ padding: 10px 20px;
532
+ background: white;
533
+ border-bottom: 1px solid var(--border);
534
+ display: flex;
535
+ align-items: center;
536
+ gap: 10px;
537
+ font-size: 0.9rem;
538
+ color: var(--text-gray);
539
  }
 
540
 
541
+ select {
542
+ padding: 5px 10px;
543
+ border-radius: 6px;
544
+ border: 1px solid #ddd;
545
+ }
546
+
547
+ @keyframes slideUp {
548
+ from { opacity: 0; transform: translateY(10px); }
549
+ to { opacity: 1; transform: translateY(0); }
550
+ }
551
+
552
+ /* Loading Spinner */
553
+ .spinner {
554
+ border: 4px solid rgba(0, 0, 0, 0.1);
555
+ width: 36px;
556
+ height: 36px;
557
+ border-radius: 50%;
558
+ border-left-color: var(--chaos);
559
+ animation: spin 1s linear infinite;
560
+ display: none;
561
+ margin: 0 auto;
562
+ }
563
+
564
+ @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
565
 
566
  /* Mobile Responsive */
567
  @media (max-width: 768px) {
568
+ .sidebar {
569
+ position: absolute;
570
+ left: -280px;
571
+ height: 100%;
572
+ transition: 0.3s;
573
+ box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1);
574
+ }
575
  .sidebar.open { left: 0; }
576
  .menu-toggle { display: block; }
577
  }
578
  @media (min-width: 769px) { .menu-toggle { display: none; } }
579
 
580
  .anycoder-link {
581
+ font-size: 0.8rem;
582
+ color: #888;
583
+ text-decoration: none;
584
+ margin-top: 20px;
585
+ display: inline-block;
586
  }
587
  </style>
588
  </head>
589
+
590
  <body>
591
 
592
  <!-- Login Screen -->
 
597
  </div>
598
  <h1>EduConnect</h1>
599
  <p style="color: #666; margin-bottom: 2rem;">Select your role to continue</p>
600
+
601
  <button class="role-btn" onclick="app.login('admin')">
602
  <i class="fa-solid fa-user-shield" style="color: var(--primary);"></i>
603
  <div style="text-align: left;">
 
613
  <span style="font-size: 0.8rem;">View assigned materials & chat</span>
614
  </div>
615
  </button>
616
+
617
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
618
  Built with anycoder
619
  </a>
 
622
 
623
  <!-- Main App Container -->
624
  <div id="appContainer" class="hidden">
625
+
626
  <!-- Sidebar: Categories (Grades) -->
627
  <aside class="sidebar" id="sidebar">
628
  <div class="brand">
 
640
 
641
  <!-- Main Content -->
642
  <main class="main-content">
643
+
644
  <!-- Top Header -->
645
  <header class="top-header">
646
  <div class="flex center" style="gap: 15px;">
 
673
  <option value="pdf">PDFs & Docs</option>
674
  <option value="text">Text Only</option>
675
  </select>
676
+ <div style="margin-left:auto; font-size:0.8rem;" id="itemCount">0 items</div>
677
  </div>
678
 
679
  <!-- Feed Area (WhatsApp Style) -->
 
696
  <h3>Upload Content</h3>
697
  <button class="btn-icon" style="color: white;" onclick="app.closeModals()"><i class="fa-solid fa-times"></i></button>
698
  </div>
699
+
700
+ <div style="flex:1; overflow-y:auto;">
701
+ <div class="upload-options">
702
+ <div class="upload-card" onclick="app.simulateUpload('video')">
703
+ <i class="fa-solid fa-video" style="font-size: 2rem; color: var(--primary); margin-bottom: 10px;"></i>
704
+ <p>Upload Video</p>
705
+ </div>
706
+ <div class="upload-card" onclick="app.simulateUpload('pdf')">
707
+ <i class="fa-solid fa-file-pdf" style="font-size: 2rem; color: var(--danger); margin-bottom: 10px;"></i>
708
+ <p>Upload PDF</p>
709
+ </div>
710
+ <div class="upload-card" onclick="app.simulateUpload('text')">
711
+ <i class="fa-solid fa-align-left" style="font-size: 2rem; color: var(--accent); margin-bottom: 10px;"></i>
712
+ <p>Post Text</p>
713
+ </div>
714
  </div>
715
+
716
+ <!-- THE 2500 LIES GENERATOR -->
717
+ <div class="lie-generator-section">
718
+ <h4><i class="fa-solid fa-database"></i> Data Simulation</h4>
719
+ <p style="font-size:0.85rem; color:#666; margin-bottom:15px;">
720
+ Instantly populate the system with fake data entries.
721
+ </p>
722
+
723
+ <button class="btn btn-chaos" style="width:100%; margin-bottom:10px;" onclick="app.generate2500Lies()">
724
+ <i class="fa-solid fa-bolt"></i> Generate 2500 "Lies"
725
+ </button>
726
+
727
+ <button class="btn" style="width:100%; background:#f0f0f0; color:#555;" onclick="app.clearData()">
728
+ <i class="fa-solid fa-trash"></i> Clear All Data
729
+ </button>
730
+
731
+ <div class="spinner" id="loadingSpinner"></div>
732
+ <div id="generationStatus" style="text-align:center; margin-top:10px; font-size:0.8rem; color:var(--chaos);"></div>
733
  </div>
734
  </div>
735
  </div>
 
755
  <script>
756
  /**
757
  * EduConnect Application Logic
758
+ * Enhanced with "2500 Lies" Generator
759
  */
760
  const app = {
761
+ // Data Store
762
  data: {
763
  currentUser: null,
764
  categories: [
765
+ { id: 1, name: 'Grade 1' }, { id: 2, name: 'Grade 2' }, { id: 3, name: 'Grade 3' },
766
+ { id: 4, name: 'Grade 4' }, { id: 5, name: 'Grade 5' }, { id: 6, name: 'Grade 6' },
767
+ { id: 7, name: 'Grade 7' }, { id: 8, name: 'Grade 8' }, { id: 9, name: 'Grade 9' },
768
+ { id: 10, name: 'Grade 10' }, { id: 11, name: 'Grade 11' }, { id: 12, name: 'Grade 12' }
 
 
 
 
 
 
 
 
769
  ],
770
  subcategories: [
771
+ { id: 1, catId: 1, name: 'Mathematics' }, { id: 2, catId: 1, name: 'English' },
772
+ { id: 3, catId: 1, name: 'Science' }, { id: 4, catId: 2, name: 'Mathematics' },
773
+ { id: 5, catId: 2, name: 'English' }, { id: 6, catId: 3, name: 'Physics' },
774
+ { id: 7, catId: 4, name: 'History' }, { id: 8, catId: 5, name: 'Biology' }
 
 
775
  ],
776
  content: [
777
  { id: 1, subId: 1, type: 'video', url: 'https://picsum.photos/seed/vid1/600/300', title: 'Introduction to Addition', author: 'Admin', date: '10:00 AM' },
778
  { id: 2, subId: 1, type: 'pdf', title: 'Chapter 1 Exercises', author: 'Admin', date: '10:05 AM' },
779
+ { id: 3, subId: 2, type: 'text', text: 'Please read pages 10-15 for homework.', author: 'Admin', date: 'Yesterday' }
 
780
  ],
781
  chat: [
782
  { sender: 'Admin', text: 'Welcome to the new semester!', time: '09:00 AM' }
 
790
 
791
  // --- Authentication ---
792
  login(role) {
 
793
  this.data.currentUser = {
794
  name: role === 'admin' ? 'Administrator' : 'Student User',
795
  role: role,
 
796
  access: role === 'student' ? [1, 2] : null
797
  };
798
 
 
800
  document.getElementById('appContainer').classList.remove('hidden');
801
  document.getElementById('userName').textContent = this.data.currentUser.name;
802
 
 
803
  if (role === 'admin') {
804
  document.getElementById('fab').classList.remove('hidden');
805
  }
 
809
  },
810
 
811
  logout() {
812
+ location.reload();
813
  },
814
 
815
  // --- Navigation & Rendering ---
816
  renderCategories() {
817
  const list = document.getElementById('categoryList');
818
  list.innerHTML = '';
 
 
819
  const visibleCats = this.data.categories.filter(c => {
820
  if (this.data.currentUser.role === 'admin') return true;
821
  return this.data.currentUser.access.includes(c.id);
 
832
 
833
  selectCategory(cat) {
834
  this.state.selectedCatId = cat.id;
835
+ this.state.selectedSubId = null;
 
 
836
  document.getElementById('pageTitle').textContent = cat.name;
837
+ this.renderCategories();
838
 
 
839
  const strip = document.getElementById('subjectStrip');
840
  strip.innerHTML = '';
 
841
  const subs = this.data.subcategories.filter(s => s.catId === cat.id);
842
+
843
  if (subs.length === 0) {
844
  strip.innerHTML = '<span style="color:#888; padding:10px;">No subjects available.</span>';
845
+ this.renderFeed();
846
  return;
847
  }
848
 
 
854
  strip.appendChild(pill);
855
  });
856
 
857
+ if (subs.length > 0) this.selectSubject(subs[0], strip.children[0]);
 
858
  },
859
 
860
  selectSubject(sub, element) {
861
  this.state.selectedSubId = sub.id;
 
 
862
  const pills = document.querySelectorAll('.subject-pill');
863
  pills.forEach(p => p.classList.remove('active'));
864
  if(element) element.classList.add('active');
 
865
  this.renderFeed();
866
  },
867
 
868
+ // --- Feed Logic ---
869
  renderFeed() {
870
  const container = document.getElementById('feedContainer');
871
  container.innerHTML = '';
 
872
  const filterType = document.getElementById('sortSelect').value;
873
 
874
  // Filter Content
 
878
  return matchesSub && matchesType;
879
  });
880
 
881
+ document.getElementById('itemCount').textContent = `${items.length} items`;
882
+
883
  if (items.length === 0) {
884
  container.innerHTML = `
885
  <div style="text-align:center; margin-top:50px; color:#888;">
886
  <i class="fa-solid fa-box-open" style="font-size:3rem; margin-bottom:10px;"></i>
887
+ <p>No content found.</p>
888
  </div>
889
  `;
890
  return;
891
  }
892
 
893
+ // Render items
894
+ // Note: For 2500 items, direct DOM manipulation can be slow.
895
+ // For this demo, we'll use a document fragment for slightly better performance.
896
+ const fragment = document.createDocumentFragment();
897
+
898
  items.forEach(item => {
899
  const bubble = document.createElement('div');
900
  bubble.className = 'msg-bubble';
 
930
  </div>
931
  ${mediaHtml}
932
  `;
933
+ fragment.appendChild(bubble);
934
  });
935
+
936
+ container.appendChild(fragment);
937
  },
938
 
939
  // --- Chat System ---
940
+ openChat() { document.getElementById('chatModal').classList.add('open'); },
941
+ closeModals() { document.querySelectorAll('.modal-overlay').forEach(el => el.classList.remove('open')); },
 
942
 
943
  sendMessage() {
944
  const input = document.getElementById('chatInput');
945
  const text = input.value.trim();
946
  if (!text) return;
 
 
947
  this.addChatMessage(this.data.currentUser.name, text);
948
  input.value = '';
 
 
949
  setTimeout(() => {
950
+ const replies = ["I see.", "Interesting point.", "Check the new data uploads.", "Lies detected."];
951
+ this.addChatMessage('Admin', replies[Math.floor(Math.random() * replies.length)]);
 
 
 
 
 
 
952
  }, 1000);
953
  },
954
 
 
956
  const area = document.getElementById('chatArea');
957
  const div = document.createElement('div');
958
  const isMe = sender === this.data.currentUser.name;
 
959
  div.className = `msg-bubble ${isMe ? 'sent' : ''}`;
 
960
  div.style.maxWidth = '80%';
961
+ div.innerHTML = `<div style="font-size:0.75rem; color:#666; margin-bottom:2px;">${sender}</div><div>${text}</div>`;
 
 
 
962
  area.appendChild(div);
963
  area.scrollTop = area.scrollHeight;
964
  },
965
 
966
  renderChat() {
 
967
  const area = document.getElementById('chatArea');
968
  area.innerHTML = '';
969
  this.data.chat.forEach(c => this.addChatMessage(c.sender, c.text));
 
975
  document.getElementById('uploadModal').classList.add('open');
976
  },
977
 
 
 
 
 
978
  simulateUpload(type) {
 
979
  const newContent = {
980
  id: Date.now(),
981
  subId: this.state.selectedSubId,
 
990
  } else if (type === 'pdf') {
991
  newContent.title = 'Worksheet_' + Math.floor(Math.random() * 100) + '.pdf';
992
  } else {
993
+ newContent.text = 'Notice: Please check the portal.';
994
  }
995
 
996
+ this.data.content.unshift(newContent);
997
  this.closeModals();
998
  this.renderFeed();
 
 
 
 
 
999
  },
1000
 
1001
  toggleSidebar() {
1002
  document.getElementById('sidebar').classList.toggle('open');
1003
+ },
1004
+
1005
+ // --- THE "2500 LIES" GENERATOR ---
1006
+ generate2500Lies() {
1007
+ if (!this.state.selectedSubId) {
1008
+ alert("Please select a Subject first!");
1009
+ return;
1010
+ }
1011
+
1012
+ const spinner = document.getElementById('loadingSpinner');
1013
+ const status = document.getElementById('generationStatus');
1014
+
1015
+ spinner.style.display = 'block';
1016
+ status.textContent = "Fabricating 2500 fake entries...";
1017
+
1018
+ // Allow UI to update before heavy loop
1019
+ setTimeout(() => {
1020
+ const adjectives = ["Fake", "False", "Mythical", "Invisible", "Quantum", "Ancient", "Galactic", "Banana", "Impossible", "Theoretical"];
1021
+ const nouns = ["Cats", "Gravity", "History", "Math", "Physics", "Chemistry", "Biology", "Art", "Music", "Philosophy", "Computers", "Dinosaurs"];
1022
+ const types = ['video', 'pdf', 'text'];
1023
+
1024
+ const newEntries = [];
1025
+
1026
+ for (let i = 0; i < 2500; i++) {
1027
+ const adj = adjectives[Math.floor(Math.random() * adjectives.length)];
1028
+ const noun = nouns[Math.floor(Math.random() * nouns.length)];
1029
+ const type = types[Math.floor(Math.random() * types.length)];
1030
+
1031
+ const entry = {
1032
+ id: Date.now() + i,
1033
+ subId: this.state.selectedSubId, // Add to current subject
1034
+ type: type,
1035
+ date: new Date().toLocaleTimeString(),
1036
+ author: 'Bot_Liar_9000'
1037
+ };
1038
+
1039
+ if (type === 'video') {
1040
+ entry.url = `https://picsum.photos/seed/${Date.now() + i}/600/300`;
1041
+ entry.title = `The ${adj} History of ${noun}`;
1042
+ } else if (type === 'pdf') {
1043
+ entry.title = `${adj} ${noun} Theory.pdf`;
1044
+ } else {
1045
+ entry.text = `Did you know that ${noun} are actually ${adj.toLowerCase()}? It's a fact! (Just kidding)`;
1046
+ }
1047
+
1048
+ newEntries.push(entry);
1049
+ }
1050
+
1051
+ // Prepend to content
1052
+ this.data.content = [...newEntries, ...this.data.content];
1053
+
1054
+ spinner.style.display = 'none';
1055
+ status.textContent = "Generation Complete!";
1056
+
1057
+ setTimeout(() => {
1058
+ this.closeModals();
1059
+ this.renderFeed();
1060
+ status.textContent = ""; // Reset for next time
1061
+ }, 500);
1062
+
1063
+ }, 100);
1064
+ },
1065
+
1066
+ clearData() {
1067
+ if(confirm("Are you sure you want to delete all content?")) {
1068
+ this.data.content = [];
1069
+ this.renderFeed();
1070
+ }
1071
  }
1072
  };
 
 
 
1073
  </script>
1074
  </body>
1075
+
1076
  </html>