ngwakomadikwe commited on
Commit
8e2b003
Β·
verified Β·
1 Parent(s): 97527b3

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +782 -123
templates/index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>ThutoAI - Student Login</title>
7
  <style>
8
  * {
9
  margin: 0;
@@ -13,183 +13,842 @@
13
 
14
  body {
15
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16
- background: linear-gradient(135deg, #1877f2 0%, #42a5f5 100%);
17
- height: 100vh;
18
  display: flex;
19
- justify-content: center;
20
- align-items: center;
21
  }
22
 
23
- .login-container {
24
- background: white;
25
- padding: 40px;
26
- border-radius: 15px;
27
- box-shadow: 0 8px 32px rgba(24, 119, 242, 0.3);
28
- width: 90%;
29
- max-width: 400px;
 
 
 
 
 
 
 
 
 
 
 
30
  text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
 
33
- .logo {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  font-size: 32px;
35
- font-weight: bold;
36
- color: #1877f2;
37
- margin-bottom: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
- .subtitle {
41
- color: #65676b;
 
 
 
42
  margin-bottom: 30px;
43
  }
44
 
45
- .form-group {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  margin-bottom: 20px;
47
- text-align: left;
48
  }
49
 
50
- .form-group label {
51
- display: block;
52
- margin-bottom: 5px;
53
- color: #1c1e21;
54
- font-weight: 500;
55
  }
56
 
57
- .form-group input {
58
- width: 100%;
59
- padding: 14px 16px;
60
- border: 1px solid #dddfe2;
61
- border-radius: 6px;
62
- font-size: 16px;
63
- transition: border-color 0.3s;
64
- background: #f5f6f7;
65
  }
66
 
67
- .form-group input:focus {
68
- outline: none;
69
- border-color: #1877f2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  background: white;
 
 
 
71
  }
72
 
73
- .login-btn {
74
- width: 100%;
75
- padding: 12px;
76
- background: #1877f2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  color: white;
78
  border: none;
79
- border-radius: 6px;
 
80
  font-size: 16px;
81
  font-weight: 600;
82
- cursor: pointer;
83
- transition: background 0.3s;
84
  }
85
 
86
- .login-btn:hover {
87
- background: #166fe5;
88
  }
89
 
90
- .login-btn:disabled {
91
- opacity: 0.7;
92
  cursor: not-allowed;
93
  }
94
 
95
- .error-message {
96
- color: #e41e3f;
97
- margin-top: 15px;
98
- padding: 10px;
99
- background: #ffebee;
100
- border-radius: 5px;
101
- display: none;
 
 
102
  }
103
 
104
- .demo-info {
105
- margin-top: 30px;
106
- padding: 20px;
107
- background: #e7f3ff;
108
- border-radius: 8px;
109
- border-left: 4px solid #1877f2;
110
- }
111
-
112
- .demo-info h4 {
113
- color: #1877f2;
114
- margin-bottom: 10px;
115
  }
116
 
117
- .demo-info p {
118
- color: #65676b;
119
- font-size: 14px;
120
- margin-bottom: 5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
  </style>
123
  </head>
124
  <body>
125
- <div class="login-container">
126
- <div class="logo">ThutoAI</div>
127
- <div class="subtitle">Your AI-Powered Student Portal</div>
128
-
129
- <form id="loginForm">
130
- <div class="form-group">
131
- <label for="username">Student ID</label>
132
- <input type="text" id="username" name="username" required>
133
  </div>
134
-
135
- <div class="form-group">
136
- <label for="password">Password</label>
137
- <input type="password" id="password" name="password" required>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  </div>
139
-
140
- <button type="submit" class="login-btn" id="loginBtn">
141
- Sign In
142
- </button>
143
-
144
- <div class="error-message" id="errorMessage"></div>
145
- </form>
146
-
147
- <div class="demo-info">
148
- <h4>Demo Credentials</h4>
149
- <p><strong>Username:</strong> student123</p>
150
- <p><strong>Password:</strong> password123</p>
151
- <p><em>Use these credentials to explore ThutoAI</em></p>
152
  </div>
153
  </div>
154
 
155
  <script>
156
- document.getElementById('loginForm').addEventListener('submit', async (e) => {
157
- e.preventDefault();
158
-
159
- const username = document.getElementById('username').value;
160
- const password = document.getElementById('password').value;
161
- const loginBtn = document.getElementById('loginBtn');
162
- const errorMessage = document.getElementById('errorMessage');
163
-
164
- loginBtn.disabled = true;
165
- loginBtn.textContent = 'Signing In...';
166
- errorMessage.style.display = 'none';
167
-
168
- try {
169
- const response = await fetch('/login', {
170
- method: 'POST',
171
- headers: {
172
- 'Content-Type': 'application/json',
173
- },
174
- body: JSON.stringify({ username, password })
 
 
 
 
175
  });
176
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  const data = await response.json();
178
 
179
  if (data.success) {
180
- window.location.href = data.redirect;
181
  } else {
182
- errorMessage.textContent = data.message;
183
- errorMessage.style.display = 'block';
184
  }
185
  } catch (error) {
186
- errorMessage.textContent = 'Login failed. Please try again.';
187
- errorMessage.style.display = 'block';
188
- } finally {
189
- loginBtn.disabled = false;
190
- loginBtn.textContent = 'Sign In';
191
  }
192
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  </script>
194
  </body>
195
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ThutoAI - Your Student Assistant</title>
7
  <style>
8
  * {
9
  margin: 0;
 
13
 
14
  body {
15
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ min-height: 100vh;
18
  display: flex;
 
 
19
  }
20
 
21
+ .app-container {
22
+ display: flex;
23
+ width: 100%;
24
+ min-height: 100vh;
25
+ }
26
+
27
+ /* Sidebar */
28
+ .sidebar {
29
+ width: 280px;
30
+ background: rgba(255, 255, 255, 0.95);
31
+ backdrop-filter: blur(10px);
32
+ box-shadow: 2px 0 20px rgba(0,0,0,0.1);
33
+ display: flex;
34
+ flex-direction: column;
35
+ }
36
+
37
+ .sidebar-header {
38
+ padding: 30px 20px;
39
  text-align: center;
40
+ border-bottom: 1px solid rgba(0,0,0,0.1);
41
+ }
42
+
43
+ .sidebar-header h1 {
44
+ color: #333;
45
+ font-size: 28px;
46
+ margin-bottom: 5px;
47
+ }
48
+
49
+ .sidebar-header p {
50
+ color: #666;
51
+ font-size: 14px;
52
  }
53
 
54
+ .sidebar-nav {
55
+ flex: 1;
56
+ padding: 20px 0;
57
+ }
58
+
59
+ .nav-item {
60
+ padding: 15px 25px;
61
+ margin: 5px 15px;
62
+ border-radius: 12px;
63
+ cursor: pointer;
64
+ transition: all 0.3s ease;
65
+ color: #555;
66
+ font-weight: 500;
67
+ }
68
+
69
+ .nav-item:hover {
70
+ background: rgba(102, 126, 234, 0.1);
71
+ color: #667eea;
72
+ }
73
+
74
+ .nav-item.active {
75
+ background: #667eea;
76
+ color: white;
77
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
78
+ }
79
+
80
+ .nav-item span {
81
+ font-size: 16px;
82
+ }
83
+
84
+ .sidebar-footer {
85
+ padding: 20px;
86
+ border-top: 1px solid rgba(0,0,0,0.1);
87
+ text-align: center;
88
+ }
89
+
90
+ .admin-link {
91
+ color: #667eea;
92
+ text-decoration: none;
93
+ font-size: 14px;
94
+ padding: 8px 16px;
95
+ border: 1px solid #667eea;
96
+ border-radius: 20px;
97
+ transition: all 0.3s ease;
98
+ }
99
+
100
+ .admin-link:hover {
101
+ background: #667eea;
102
+ color: white;
103
+ }
104
+
105
+ /* Main Content */
106
+ .main-content {
107
+ flex: 1;
108
+ display: flex;
109
+ flex-direction: column;
110
+ background: rgba(255, 255, 255, 0.9);
111
+ backdrop-filter: blur(10px);
112
+ }
113
+
114
+ .content-header {
115
+ padding: 30px 40px;
116
+ border-bottom: 1px solid rgba(0,0,0,0.1);
117
+ background: rgba(255, 255, 255, 0.8);
118
+ }
119
+
120
+ .content-header h2 {
121
+ color: #333;
122
  font-size: 32px;
123
+ margin-bottom: 8px;
124
+ }
125
+
126
+ .content-header p {
127
+ color: #666;
128
+ font-size: 16px;
129
+ }
130
+
131
+ .content-body {
132
+ flex: 1;
133
+ padding: 40px;
134
+ overflow-y: auto;
135
+ }
136
+
137
+ /* Views */
138
+ .view {
139
+ display: block;
140
+ }
141
+
142
+ .view.hidden {
143
+ display: none;
144
  }
145
 
146
+ /* Dashboard Cards */
147
+ .dashboard-grid {
148
+ display: grid;
149
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
150
+ gap: 25px;
151
  margin-bottom: 30px;
152
  }
153
 
154
+ .dashboard-card {
155
+ background: white;
156
+ border-radius: 20px;
157
+ padding: 25px;
158
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
159
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
160
+ }
161
+
162
+ .dashboard-card:hover {
163
+ transform: translateY(-5px);
164
+ box-shadow: 0 20px 40px rgba(0,0,0,0.15);
165
+ }
166
+
167
+ .card-header {
168
+ display: flex;
169
+ align-items: center;
170
  margin-bottom: 20px;
 
171
  }
172
 
173
+ .card-icon {
174
+ font-size: 24px;
175
+ margin-right: 12px;
 
 
176
  }
177
 
178
+ .card-title {
179
+ font-size: 18px;
180
+ font-weight: 600;
181
+ color: #333;
 
 
 
 
182
  }
183
 
184
+ .card-content {
185
+ color: #666;
186
+ }
187
+
188
+ .card-item {
189
+ padding: 12px 0;
190
+ border-bottom: 1px solid #f0f0f0;
191
+ }
192
+
193
+ .card-item:last-child {
194
+ border-bottom: none;
195
+ }
196
+
197
+ .item-title {
198
+ font-weight: 600;
199
+ color: #333;
200
+ margin-bottom: 4px;
201
+ }
202
+
203
+ .item-details {
204
+ font-size: 14px;
205
+ color: #666;
206
+ }
207
+
208
+ /* Chat Interface */
209
+ .chat-container {
210
+ display: flex;
211
+ flex-direction: column;
212
+ height: 600px;
213
  background: white;
214
+ border-radius: 20px;
215
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
216
+ overflow: hidden;
217
  }
218
 
219
+ .chat-messages {
220
+ flex: 1;
221
+ padding: 25px;
222
+ overflow-y: auto;
223
+ background: #f8f9fa;
224
+ }
225
+
226
+ .welcome-message {
227
+ text-align: center;
228
+ padding: 40px 20px;
229
+ background: white;
230
+ border-radius: 15px;
231
+ margin-bottom: 20px;
232
+ box-shadow: 0 5px 15px rgba(0,0,0,0.05);
233
+ }
234
+
235
+ .welcome-message h3 {
236
+ color: #333;
237
+ margin-bottom: 15px;
238
+ font-size: 24px;
239
+ }
240
+
241
+ .welcome-message p {
242
+ color: #666;
243
+ margin-bottom: 10px;
244
+ }
245
+
246
+ .message {
247
+ margin-bottom: 20px;
248
+ display: flex;
249
+ align-items: flex-start;
250
+ }
251
+
252
+ .message.user {
253
+ justify-content: flex-end;
254
+ }
255
+
256
+ .message-content {
257
+ max-width: 70%;
258
+ padding: 15px 20px;
259
+ border-radius: 20px;
260
+ word-wrap: break-word;
261
+ }
262
+
263
+ .message.user .message-content {
264
+ background: #667eea;
265
+ color: white;
266
+ border-bottom-right-radius: 5px;
267
+ }
268
+
269
+ .message.assistant .message-content {
270
+ background: white;
271
+ color: #333;
272
+ border-bottom-left-radius: 5px;
273
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
274
+ }
275
+
276
+ .chat-input-container {
277
+ padding: 25px;
278
+ background: white;
279
+ border-top: 1px solid #e0e0e0;
280
+ }
281
+
282
+ .chat-input-form {
283
+ display: flex;
284
+ gap: 15px;
285
+ }
286
+
287
+ .chat-input {
288
+ flex: 1;
289
+ padding: 15px 20px;
290
+ border: 2px solid #e0e0e0;
291
+ border-radius: 25px;
292
+ font-size: 16px;
293
+ outline: none;
294
+ transition: border-color 0.3s ease;
295
+ }
296
+
297
+ .chat-input:focus {
298
+ border-color: #667eea;
299
+ }
300
+
301
+ .send-button {
302
+ padding: 15px 25px;
303
+ background: #667eea;
304
  color: white;
305
  border: none;
306
+ border-radius: 25px;
307
+ cursor: pointer;
308
  font-size: 16px;
309
  font-weight: 600;
310
+ transition: background 0.3s ease;
 
311
  }
312
 
313
+ .send-button:hover {
314
+ background: #5a6fd8;
315
  }
316
 
317
+ .send-button:disabled {
318
+ background: #ccc;
319
  cursor: not-allowed;
320
  }
321
 
322
+ /* Loading Animation */
323
+ .loading {
324
+ display: inline-block;
325
+ width: 20px;
326
+ height: 20px;
327
+ border: 3px solid #f3f3f3;
328
+ border-top: 3px solid #667eea;
329
+ border-radius: 50%;
330
+ animation: spin 1s linear infinite;
331
  }
332
 
333
+ @keyframes spin {
334
+ 0% { transform: rotate(0deg); }
335
+ 100% { transform: rotate(360deg); }
 
 
 
 
 
 
 
 
336
  }
337
 
338
+ /* Responsive Design */
339
+ @media (max-width: 768px) {
340
+ .app-container {
341
+ flex-direction: column;
342
+ }
343
+
344
+ .sidebar {
345
+ width: 100%;
346
+ height: auto;
347
+ }
348
+
349
+ .sidebar-nav {
350
+ display: flex;
351
+ overflow-x: auto;
352
+ padding: 10px 0;
353
+ }
354
+
355
+ .nav-item {
356
+ white-space: nowrap;
357
+ min-width: 120px;
358
+ margin: 0 5px;
359
+ }
360
+
361
+ .content-body {
362
+ padding: 20px;
363
+ }
364
+
365
+ .dashboard-grid {
366
+ grid-template-columns: 1fr;
367
+ }
368
  }
369
  </style>
370
  </head>
371
  <body>
372
+ <div class="app-container">
373
+ <!-- Sidebar -->
374
+ <div class="sidebar">
375
+ <div class="sidebar-header">
376
+ <h1>πŸŽ“ ThutoAI</h1>
377
+ <p>Your Student Assistant</p>
 
 
378
  </div>
379
+ <div class="sidebar-nav">
380
+ <div class="nav-item active" data-view="dashboard">
381
+ <span>πŸ“Š Dashboard</span>
382
+ </div>
383
+ <div class="nav-item" data-view="chat">
384
+ <span>πŸ’¬ AI Chat</span>
385
+ </div>
386
+ <div class="nav-item" data-view="announcements">
387
+ <span>πŸ“’ Announcements</span>
388
+ </div>
389
+ <div class="nav-item" data-view="exams">
390
+ <span>πŸ“ Exams</span>
391
+ </div>
392
+ <div class="nav-item" data-view="grades">
393
+ <span>πŸ“Š Grades</span>
394
+ </div>
395
+ </div>
396
+ <div class="sidebar-footer">
397
+ <a href="/admin/login" class="admin-link">πŸ” Admin Panel</a>
398
+ </div>
399
+ </div>
400
+
401
+ <!-- Main Content -->
402
+ <div class="main-content">
403
+ <!-- Dashboard View -->
404
+ <div id="dashboard-view" class="view">
405
+ <div class="content-header">
406
+ <h2>Student Dashboard</h2>
407
+ <p>Your academic overview and important updates</p>
408
+ </div>
409
+ <div class="content-body">
410
+ <div class="dashboard-grid" id="dashboardGrid">
411
+ <div class="loading">Loading your dashboard...</div>
412
+ </div>
413
+ </div>
414
+ </div>
415
+
416
+ <!-- Chat View -->
417
+ <div id="chat-view" class="view hidden">
418
+ <div class="content-header">
419
+ <h2>AI Chat Assistant</h2>
420
+ <p>Ask me anything about your studies, school, or get academic help</p>
421
+ </div>
422
+ <div class="content-body">
423
+ <div class="chat-container">
424
+ <div class="chat-messages" id="chatMessages">
425
+ <div class="welcome-message">
426
+ <h3>πŸ‘‹ Hello! I'm your ThutoAI Assistant</h3>
427
+ <p>I can help you with:</p>
428
+ <ul style="text-align: left; display: inline-block; margin-top: 10px;">
429
+ <li>πŸ“š Study questions and academic help</li>
430
+ <li>πŸ“… Information about exams and assignments</li>
431
+ <li>πŸ“Š Your grades and academic performance</li>
432
+ <li>πŸ“’ School announcements and events</li>
433
+ <li>πŸ’‘ Study tips and motivation</li>
434
+ </ul>
435
+ <p style="margin-top: 15px;">What would you like to know?</p>
436
+ </div>
437
+ </div>
438
+ <div class="chat-input-container">
439
+ <form class="chat-input-form" id="chatForm">
440
+ <input type="text" class="chat-input" id="chatInput" placeholder="Ask me anything about your studies..." required>
441
+ <button type="submit" class="send-button" id="sendButton">Send</button>
442
+ </form>
443
+ </div>
444
+ </div>
445
+ </div>
446
+ </div>
447
+
448
+ <!-- Announcements View -->
449
+ <div id="announcements-view" class="view hidden">
450
+ <div class="content-header">
451
+ <h2>School Announcements</h2>
452
+ <p>Latest news and updates from your school</p>
453
+ </div>
454
+ <div class="content-body">
455
+ <div class="dashboard-grid" id="announcementsGrid">
456
+ <div class="loading">Loading announcements...</div>
457
+ </div>
458
+ </div>
459
+ </div>
460
+
461
+ <!-- Exams View -->
462
+ <div id="exams-view" class="view hidden">
463
+ <div class="content-header">
464
+ <h2>Upcoming Exams</h2>
465
+ <p>Your examination schedule and important details</p>
466
+ </div>
467
+ <div class="content-body">
468
+ <div class="dashboard-grid" id="examsGrid">
469
+ <div class="loading">Loading exams...</div>
470
+ </div>
471
+ </div>
472
+ </div>
473
+
474
+ <!-- Grades View -->
475
+ <div id="grades-view" class="view hidden">
476
+ <div class="content-header">
477
+ <h2>Your Grades</h2>
478
+ <p>Academic performance and assessment results</p>
479
+ </div>
480
+ <div class="content-body">
481
+ <div class="dashboard-grid" id="gradesGrid">
482
+ <div class="loading">Loading grades...</div>
483
+ </div>
484
+ </div>
485
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  </div>
487
  </div>
488
 
489
  <script>
490
+ // Global variables
491
+ let currentView = 'dashboard';
492
+
493
+ // DOM elements
494
+ const navItems = document.querySelectorAll('.nav-item');
495
+ const views = document.querySelectorAll('.view');
496
+ const chatForm = document.getElementById('chatForm');
497
+ const chatInput = document.getElementById('chatInput');
498
+ const chatMessages = document.getElementById('chatMessages');
499
+ const sendButton = document.getElementById('sendButton');
500
+
501
+ // Initialize app
502
+ document.addEventListener('DOMContentLoaded', () => {
503
+ setupNavigation();
504
+ loadDashboard();
505
+ });
506
+
507
+ // Navigation setup
508
+ function setupNavigation() {
509
+ navItems.forEach(item => {
510
+ item.addEventListener('click', () => {
511
+ const viewName = item.dataset.view;
512
+ switchView(viewName);
513
  });
514
+ });
515
+ }
516
+
517
+ // Switch between views
518
+ function switchView(viewName) {
519
+ // Update navigation
520
+ navItems.forEach(item => {
521
+ item.classList.toggle('active', item.dataset.view === viewName);
522
+ });
523
+
524
+ // Update views
525
+ views.forEach(view => {
526
+ view.classList.toggle('hidden', !view.id.startsWith(viewName));
527
+ });
528
+
529
+ currentView = viewName;
530
+
531
+ // Load view-specific data
532
+ switch(viewName) {
533
+ case 'dashboard':
534
+ loadDashboard();
535
+ break;
536
+ case 'announcements':
537
+ loadAnnouncements();
538
+ break;
539
+ case 'exams':
540
+ loadExams();
541
+ break;
542
+ case 'grades':
543
+ loadGrades();
544
+ break;
545
+ }
546
+ }
547
+
548
+ // Load dashboard data
549
+ async function loadDashboard() {
550
+ try {
551
+ const response = await fetch('/dashboard');
552
  const data = await response.json();
553
 
554
  if (data.success) {
555
+ renderDashboard(data.data);
556
  } else {
557
+ console.error('Dashboard error:', data.error);
 
558
  }
559
  } catch (error) {
560
+ console.error('Dashboard fetch error:', error);
 
 
 
 
561
  }
562
+ }
563
+
564
+ // Render dashboard
565
+ function renderDashboard(data) {
566
+ const grid = document.getElementById('dashboardGrid');
567
+ grid.innerHTML = '';
568
+
569
+ // Recent announcements card
570
+ if (data.announcements && data.announcements.length > 0) {
571
+ grid.appendChild(createDashboardCard('πŸ“’', 'Recent Announcements', data.announcements, 'announcements'));
572
+ }
573
+
574
+ // Upcoming exams card
575
+ if (data.upcoming_exams && data.upcoming_exams.length > 0) {
576
+ grid.appendChild(createDashboardCard('πŸ“', 'Upcoming Exams', data.upcoming_exams, 'exams'));
577
+ }
578
+
579
+ // Upcoming tests card
580
+ if (data.upcoming_tests && data.upcoming_tests.length > 0) {
581
+ grid.appendChild(createDashboardCard('πŸ“š', 'Upcoming Tests', data.upcoming_tests, 'tests'));
582
+ }
583
+
584
+ // Recent grades card
585
+ if (data.recent_grades && data.recent_grades.length > 0) {
586
+ grid.appendChild(createDashboardCard('πŸ“Š', 'Recent Grades', data.recent_grades, 'grades'));
587
+ }
588
+
589
+ // Upcoming events card
590
+ if (data.upcoming_events && data.upcoming_events.length > 0) {
591
+ grid.appendChild(createDashboardCard('πŸŽ‰', 'Upcoming Events', data.upcoming_events, 'events'));
592
+ }
593
+
594
+ if (grid.children.length === 0) {
595
+ grid.innerHTML = '<div class="welcome-message"><h3>Welcome to ThutoAI!</h3><p>Your dashboard will show information as it becomes available.</p></div>';
596
+ }
597
+ }
598
+
599
+ function createDashboardCard(icon, title, items, type) {
600
+ const card = document.createElement('div');
601
+ card.className = 'dashboard-card';
602
+
603
+ const header = document.createElement('div');
604
+ header.className = 'card-header';
605
+ header.innerHTML = `
606
+ <span class="card-icon">${icon}</span>
607
+ <span class="card-title">${title}</span>
608
+ `;
609
+
610
+ const content = document.createElement('div');
611
+ content.className = 'card-content';
612
+
613
+ items.slice(0, 3).forEach(item => {
614
+ const itemDiv = document.createElement('div');
615
+ itemDiv.className = 'card-item';
616
+
617
+ let itemContent = '';
618
+ switch(type) {
619
+ case 'announcements':
620
+ itemContent = `
621
+ <div class="item-title">${item.title}</div>
622
+ <div class="item-details">${item.content.substring(0, 100)}...</div>
623
+ `;
624
+ break;
625
+ case 'exams':
626
+ itemContent = `
627
+ <div class="item-title">${item.name}</div>
628
+ <div class="item-details">${item.subject} - ${item.date} at ${item.time}</div>
629
+ `;
630
+ break;
631
+ case 'tests':
632
+ itemContent = `
633
+ <div class="item-title">${item.title}</div>
634
+ <div class="item-details">${item.subject} - Due: ${item.due_date}</div>
635
+ `;
636
+ break;
637
+ case 'grades':
638
+ itemContent = `
639
+ <div class="item-title">${item.subject}</div>
640
+ <div class="item-details">${item.percentage}% (${item.grade}) - ${item.name}</div>
641
+ `;
642
+ break;
643
+ case 'events':
644
+ itemContent = `
645
+ <div class="item-title">${item.name}</div>
646
+ <div class="item-details">${item.date} - ${item.location}</div>
647
+ `;
648
+ break;
649
+ }
650
+
651
+ itemDiv.innerHTML = itemContent;
652
+ content.appendChild(itemDiv);
653
+ });
654
+
655
+ card.appendChild(header);
656
+ card.appendChild(content);
657
+ return card;
658
+ }
659
+
660
+ // Load announcements
661
+ async function loadAnnouncements() {
662
+ try {
663
+ const response = await fetch('/announcements');
664
+ const data = await response.json();
665
+
666
+ if (data.success) {
667
+ renderAnnouncements(data.announcements);
668
+ }
669
+ } catch (error) {
670
+ console.error('Announcements fetch error:', error);
671
+ }
672
+ }
673
+
674
+ function renderAnnouncements(announcements) {
675
+ const grid = document.getElementById('announcementsGrid');
676
+ grid.innerHTML = '';
677
+
678
+ if (announcements.length === 0) {
679
+ grid.innerHTML = '<div class="welcome-message"><h3>No Announcements</h3><p>No announcements available at the moment.</p></div>';
680
+ return;
681
+ }
682
+
683
+ announcements.forEach(ann => {
684
+ const card = document.createElement('div');
685
+ card.className = 'dashboard-card';
686
+ card.innerHTML = `
687
+ <div class="card-header">
688
+ <span class="card-icon">πŸ“’</span>
689
+ <span class="card-title">${ann.title}</span>
690
+ </div>
691
+ <div class="card-content">
692
+ <p>${ann.content}</p>
693
+ <div class="item-details" style="margin-top: 10px;">
694
+ Priority: ${ann.priority} | Date: ${new Date(ann.date).toLocaleDateString()}
695
+ </div>
696
+ </div>
697
+ `;
698
+ grid.appendChild(card);
699
+ });
700
+ }
701
+
702
+ // Load exams
703
+ async function loadExams() {
704
+ try {
705
+ const response = await fetch('/exams');
706
+ const data = await response.json();
707
+
708
+ if (data.success) {
709
+ renderExams(data.exams);
710
+ }
711
+ } catch (error) {
712
+ console.error('Exams fetch error:', error);
713
+ }
714
+ }
715
+
716
+ function renderExams(exams) {
717
+ const grid = document.getElementById('examsGrid');
718
+ grid.innerHTML = '';
719
+
720
+ if (exams.length === 0) {
721
+ grid.innerHTML = '<div class="welcome-message"><h3>No Upcoming Exams</h3><p>No exams scheduled at the moment.</p></div>';
722
+ return;
723
+ }
724
+
725
+ exams.forEach(exam => {
726
+ const card = document.createElement('div');
727
+ card.className = 'dashboard-card';
728
+ card.innerHTML = `
729
+ <div class="card-header">
730
+ <span class="card-icon">πŸ“</span>
731
+ <span class="card-title">${exam.name}</span>
732
+ </div>
733
+ <div class="card-content">
734
+ <div class="card-item">
735
+ <div class="item-title">Subject: ${exam.subject}</div>
736
+ </div>
737
+ <div class="card-item">
738
+ <div class="item-title">Date & Time: ${exam.date} at ${exam.time}</div>
739
+ </div>
740
+ <div class="card-item">
741
+ <div class="item-title">Location: ${exam.location}</div>
742
+ </div>
743
+ ${exam.instructions ? `<div class="card-item"><div class="item-details">${exam.instructions}</div></div>` : ''}
744
+ </div>
745
+ `;
746
+ grid.appendChild(card);
747
+ });
748
+ }
749
+
750
+ // Load grades
751
+ async function loadGrades() {
752
+ try {
753
+ const response = await fetch('/grades');
754
+ const data = await response.json();
755
+
756
+ if (data.success) {
757
+ renderGrades(data.grades);
758
+ }
759
+ } catch (error) {
760
+ console.error('Grades fetch error:', error);
761
+ }
762
+ }
763
+
764
+ function renderGrades(grades) {
765
+ const grid = document.getElementById('gradesGrid');
766
+ grid.innerHTML = '';
767
+
768
+ if (grades.length === 0) {
769
+ grid.innerHTML = '<div class="welcome-message"><h3>No Grades Available</h3><p>No grades recorded yet.</p></div>';
770
+ return;
771
+ }
772
+
773
+ grades.forEach(grade => {
774
+ const card = document.createElement('div');
775
+ card.className = 'dashboard-card';
776
+ card.innerHTML = `
777
+ <div class="card-header">
778
+ <span class="card-icon">πŸ“Š</span>
779
+ <span class="card-title">${grade.subject}</span>
780
+ </div>
781
+ <div class="card-content">
782
+ <div class="card-item">
783
+ <div class="item-title">${grade.name}</div>
784
+ <div class="item-details">${grade.type}</div>
785
+ </div>
786
+ <div class="card-item">
787
+ <div class="item-title">Score: ${grade.marks_obtained}/${grade.total_marks} (${grade.percentage}%)</div>
788
+ <div class="item-details">Grade: ${grade.grade}</div>
789
+ </div>
790
+ <div class="card-item">
791
+ <div class="item-details">Date: ${grade.date}</div>
792
+ </div>
793
+ ${grade.comments ? `<div class="card-item"><div class="item-details">Comments: ${grade.comments}</div></div>` : ''}
794
+ </div>
795
+ `;
796
+ grid.appendChild(card);
797
+ });
798
+ }
799
+
800
+ // Chat functionality
801
+ if (chatForm) {
802
+ chatForm.addEventListener('submit', async (e) => {
803
+ e.preventDefault();
804
+ const message = chatInput.value.trim();
805
+ if (!message) return;
806
+
807
+ // Add user message to chat
808
+ addMessage(message, 'user');
809
+ chatInput.value = '';
810
+ sendButton.disabled = true;
811
+ sendButton.innerHTML = '<span class="loading"></span>';
812
+
813
+ try {
814
+ const response = await fetch('/chat', {
815
+ method: 'POST',
816
+ headers: {
817
+ 'Content-Type': 'application/json',
818
+ },
819
+ body: JSON.stringify({ message: message })
820
+ });
821
+
822
+ const data = await response.json();
823
+
824
+ if (data.reply) {
825
+ addMessage(data.reply, 'assistant');
826
+ } else {
827
+ addMessage('Sorry, I encountered an error. Please try again.', 'assistant');
828
+ }
829
+ } catch (error) {
830
+ addMessage('Sorry, I could not connect to the server. Please check your connection and try again.', 'assistant');
831
+ } finally {
832
+ sendButton.disabled = false;
833
+ sendButton.innerHTML = 'Send';
834
+ }
835
+ });
836
+ }
837
+
838
+ function addMessage(content, sender) {
839
+ const messageDiv = document.createElement('div');
840
+ messageDiv.className = `message ${sender}`;
841
+
842
+ const contentDiv = document.createElement('div');
843
+ contentDiv.className = 'message-content';
844
+ contentDiv.innerHTML = content.replace(/\n/g, '<br>');
845
+
846
+ messageDiv.appendChild(contentDiv);
847
+ chatMessages.appendChild(messageDiv);
848
+
849
+ // Scroll to bottom
850
+ chatMessages.scrollTop = chatMessages.scrollHeight;
851
+ }
852
  </script>
853
  </body>
854
  </html>