ABSONUMBER1 commited on
Commit
0acef56
·
verified ·
1 Parent(s): 856f288

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +880 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Evaluation
3
- emoji: 🐨
4
- colorFrom: purple
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: evaluation
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,880 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>UC Math Evaluation System</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .gradient-bg {
11
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
12
+ }
13
+ .evaluation-card {
14
+ transition: all 0.3s ease;
15
+ }
16
+ .evaluation-card:hover {
17
+ transform: translateY(-5px);
18
+ box-shadow: 0 10px 20px rgba(0,0,0,0.1);
19
+ }
20
+ .shake {
21
+ animation: shake 0.5s;
22
+ }
23
+ @keyframes shake {
24
+ 0%, 100% { transform: trans
25
+ lateX(0); }
26
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
27
+ 20%, 40%, 60%, 80% { transform: translateX(5px); }
28
+ }
29
+ </style>
30
+ </head>
31
+ <body class="min-h-screen bg-gray-100">
32
+ <!-- Main Container -->
33
+ <div id="app" class="container mx-auto px-4 py-8">
34
+ <!-- Login Screen -->
35
+ <div id="login-screen" class="max-w-md mx-auto">
36
+ <div class="gradient-bg rounded-xl shadow-xl overflow-hidden">
37
+ <div class="px-10 py-12">
38
+ <div class="text-center mb-8">
39
+ <h1 class="text-3xl font-bold text-white">UC Math Evaluation</h1>
40
+ <p class="text-white opacity-80 mt-2">Student & Teacher Portal</p>
41
+ </div>
42
+
43
+ <form id="login-form" class="space-y-6">
44
+ <div>
45
+ <label for="username" class="block text-sm font-medium text-white">Username</label>
46
+ <div class="mt-1 relative rounded-md shadow-sm">
47
+ <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
48
+ <i class="fas fa-user text-gray-300"></i>
49
+ </div>
50
+ <input type="text" id="username" name="username" required
51
+ class="py-3 pl-10 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500">
52
+ </div>
53
+ </div>
54
+
55
+ <div>
56
+ <label for="password" class="block text-sm font-medium text-white">Password</label>
57
+ <div class="mt-1 relative rounded-md shadow-sm">
58
+ <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
59
+ <i class="fas fa-lock text-gray-300"></i>
60
+ </div>
61
+ <input type="password" id="password" name="password" required
62
+ class="py-3 pl-10 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500">
63
+ </div>
64
+ </div>
65
+
66
+ <div>
67
+ <button type="submit"
68
+ class="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-indigo-700 bg-white hover:bg-indigo-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-all">
69
+ Sign in
70
+ </button>
71
+ </div>
72
+ </form>
73
+
74
+ <div id="login-error" class="mt-4 hidden">
75
+ <div class="bg-red-50 border-l-4 border-red-400 p-4">
76
+ <div class="flex">
77
+ <div class="flex-shrink-0">
78
+ <i class="fas fa-exclamation-circle text-red-400"></i>
79
+ </div>
80
+ <div class="ml-3">
81
+ <p class="text-sm text-red-700" id="error-message">Invalid username or password</p>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <!-- Student Dashboard (Hidden by default) -->
91
+ <div id="student-dashboard" class="hidden">
92
+ <div class="flex justify-between items-center mb-8">
93
+ <h1 class="text-3xl font-bold text-gray-800">Your Math Evaluations</h1>
94
+ <button id="logout-btn" class="flex items-center text-gray-600 hover:text-gray-900">
95
+ <i class="fas fa-sign-out-alt mr-2"></i> Logout
96
+ </button>
97
+ </div>
98
+
99
+ <div class="bg-white rounded-xl shadow-md overflow-hidden">
100
+ <div class="p-6">
101
+ <div class="flex items-center mb-6">
102
+ <div class="h-12 w-12 rounded-full bg-indigo-100 flex items-center justify-center">
103
+ <i class="fas fa-user-graduate text-indigo-600 text-xl"></i>
104
+ </div>
105
+ <div class="ml-4">
106
+ <h2 class="text-xl font-semibold text-gray-800" id="student-name">John Doe</h2>
107
+ <p class="text-gray-600">Student ID: <span id="student-id">S12345</span></p>
108
+ </div>
109
+ </div>
110
+
111
+ <div id="evaluations-container" class="grid grid-cols-1 md:grid-cols-2 gap-6">
112
+ <!-- Evaluations will be loaded here -->
113
+ </div>
114
+
115
+ <div id="no-evaluations" class="text-center py-12 hidden">
116
+ <i class="fas fa-book-open text-gray-300 text-5xl mb-4"></i>
117
+ <h3 class="text-lg font-medium text-gray-500">No evaluations available</h3>
118
+ <p class="text-gray-400 mt-1">Your teacher hasn't uploaded any evaluations yet.</p>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ </div>
123
+
124
+ <!-- Teacher Dashboard (Hidden by default) -->
125
+ <div id="teacher-dashboard" class="hidden">
126
+ <div class="flex justify-between items-center mb-8">
127
+ <h1 class="text-3xl font-bold text-gray-800">Teacher Control Panel</h1>
128
+ <button id="teacher-logout-btn" class="flex items-center text-gray-600 hover:text-gray-900">
129
+ <i class="fas fa-sign-out-alt mr-2"></i> Logout
130
+ </button>
131
+ </div>
132
+
133
+ <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8">
134
+ <div class="p-6">
135
+ <div class="flex items-center mb-6">
136
+ <div class="h-12 w-12 rounded-full bg-purple-100 flex items-center justify-center">
137
+ <i class="fas fa-chalkboard-teacher text-purple-600 text-xl"></i>
138
+ </div>
139
+ <div class="ml-4">
140
+ <h2 class="text-xl font-semibold text-gray-800">Prof. Shaimaa Robaa</h2>
141
+ <p class="text-gray-600">Math Department</p>
142
+ </div>
143
+ </div>
144
+
145
+ <div class="border-b border-gray-200">
146
+ <nav class="-mb-px flex space-x-8">
147
+ <button id="manage-students-tab" class="border-indigo-500 text-indigo-600 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">
148
+ Manage Students
149
+ </button>
150
+ <button id="upload-evaluations-tab" class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">
151
+ Upload Evaluations
152
+ </button>
153
+ </nav>
154
+ </div>
155
+ </div>
156
+ </div>
157
+
158
+ <!-- Manage Students Panel -->
159
+ <div id="manage-students-panel">
160
+ <div class="bg-white rounded-xl shadow-md overflow-hidden mb-6">
161
+ <div class="p-6">
162
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Add New Student</h2>
163
+ <form id="add-student-form" class="space-y-4">
164
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
165
+ <div>
166
+ <label for="student-firstname" class="block text-sm font-medium text-gray-700">First Name</label>
167
+ <input type="text" id="student-firstname" name="firstname" required
168
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border">
169
+ </div>
170
+ <div>
171
+ <label for="student-lastname" class="block text-sm font-medium text-gray-700">Last Name</label>
172
+ <input type="text" id="student-lastname" name="lastname" required
173
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border">
174
+ </div>
175
+ </div>
176
+ <div>
177
+ <label for="student-email" class="block text-sm font-medium text-gray-700">Email</label>
178
+ <input type="email" id="student-email" name="email" required
179
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border">
180
+ </div>
181
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
182
+ <div>
183
+ <label for="student-username" class="block text-sm font-medium text-gray-700">Username</label>
184
+ <input type="text" id="student-username" name="username" required
185
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border">
186
+ </div>
187
+ <div>
188
+ <label for="student-password" class="block text-sm font-medium text-gray-700">Password</label>
189
+ <input type="password" id="student-password" name="password" required
190
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border">
191
+ </div>
192
+ </div>
193
+ <div class="pt-2">
194
+ <button type="submit"
195
+ class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
196
+ Add Student
197
+ </button>
198
+ </div>
199
+ </form>
200
+ </div>
201
+ </div>
202
+
203
+ <div class="bg-white rounded-xl shadow-md overflow-hidden">
204
+ <div class="p-6">
205
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Student List</h2>
206
+ <div class="overflow-x-auto">
207
+ <table class="min-w-full divide-y divide-gray-200">
208
+ <thead class="bg-gray-50">
209
+ <tr>
210
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
211
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Username</th>
212
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Email</th>
213
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
214
+ </tr>
215
+ </thead>
216
+ <tbody id="student-list" class="bg-white divide-y divide-gray-200">
217
+ <!-- Student list will be loaded here -->
218
+ </tbody>
219
+ </table>
220
+ </div>
221
+ <div id="no-students" class="text-center py-12 hidden">
222
+ <i class="fas fa-user-graduate text-gray-300 text-5xl mb-4"></i>
223
+ <h3 class="text-lg font-medium text-gray-500">No students added</h3>
224
+ <p class="text-gray-400 mt-1">Add your first student using the form above.</p>
225
+ </div>
226
+ </div>
227
+ </div>
228
+ </div>
229
+
230
+ <!-- Upload Evaluations Panel (Hidden by default) -->
231
+ <div id="upload-evaluations-panel" class="hidden">
232
+ <div class="bg-white rounded-xl shadow-md overflow-hidden mb-6">
233
+ <div class="p-6">
234
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Upload New Evaluation</h2>
235
+ <form id="upload-evaluation-form" class="space-y-4">
236
+ <div>
237
+ <label for="evaluation-title" class="block text-sm font-medium text-gray-700">Title</label>
238
+ <input type="text" id="evaluation-title" name="title" required
239
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border">
240
+ </div>
241
+ <div>
242
+ <label for="evaluation-description" class="block text-sm font-medium text-gray-700">Description</label>
243
+ <textarea id="evaluation-description" name="description" rows="3"
244
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border"></textarea>
245
+ </div>
246
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
247
+ <div>
248
+ <label for="evaluation-date" class="block text-sm font-medium text-gray-700">Due Date</label>
249
+ <input type="date" id="evaluation-date" name="date" required
250
+ class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 py-2 px-3 border">
251
+ </div>
252
+ <div>
253
+ <label for="evaluation-file" class="block text-sm font-medium text-gray-700">Evaluation File</label>
254
+ <div class="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md">
255
+ <div class="space-y-1 text-center">
256
+ <div class="flex text-sm text-gray-600">
257
+ <label for="file-upload" class="relative cursor-pointer bg-white rounded-md font-medium text-indigo-600 hover:text-indigo-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-indigo-500">
258
+ <span>Upload a file</span>
259
+ <input id="file-upload" name="file-upload" type="file" class="sr-only">
260
+ </label>
261
+ <p class="pl-1">or drag and drop</p>
262
+ </div>
263
+ <p class="text-xs text-gray-500">PDF, DOCX up to 10MB</p>
264
+ </div>
265
+ </div>
266
+ </div>
267
+ </div>
268
+ <div class="pt-2">
269
+ <button type="submit"
270
+ class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
271
+ Upload Evaluation
272
+ </button>
273
+ </div>
274
+ </form>
275
+ </div>
276
+ </div>
277
+
278
+ <div class="bg-white rounded-xl shadow-md overflow-hidden">
279
+ <div class="p-6">
280
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Recent Evaluations</h2>
281
+ <div id="teacher-evaluations-container" class="space-y-4">
282
+ <!-- Teacher's evaluations will be loaded here -->
283
+ </div>
284
+ <div id="no-teacher-evaluations" class="text-center py-12 hidden">
285
+ <i class="fas fa-book text-gray-300 text-5xl mb-4"></i>
286
+ <h3 class="text-lg font-medium text-gray-500">No evaluations uploaded</h3>
287
+ <p class="text-gray-400 mt-1">Upload your first evaluation using the form above.</p>
288
+ </div>
289
+ </div>
290
+ </div>
291
+ </div>
292
+ </div>
293
+ </div>
294
+
295
+ <script>
296
+ // Database keys for localStorage
297
+ const DB_KEYS = {
298
+ STUDENTS: 'uc_math_students',
299
+ EVALUATIONS: 'uc_math_evaluations'
300
+ };
301
+
302
+ // Initialize database with default data if not exists
303
+ function initializeDatabase() {
304
+ if (!localStorage.getItem(DB_KEYS.STUDENTS)) {
305
+ const defaultStudents = [
306
+ { id: 'S1001', username: 'student1', password: 'password1', name: 'Alice Johnson', email: '[email protected]' },
307
+ { id: 'S1002', username: 'student2', password: 'password2', name: 'Bob Smith', email: '[email protected]' },
308
+ { id: 'S1003', username: 'student3', password: 'password3', name: 'Charlie Brown', email: '[email protected]' }
309
+ ];
310
+ localStorage.setItem(DB_KEYS.STUDENTS, JSON.stringify(defaultStudents));
311
+ }
312
+
313
+ if (!localStorage.getItem(DB_KEYS.EVALUATIONS)) {
314
+ const defaultEvaluations = [
315
+ {
316
+ id: 'E101',
317
+ title: 'Linear Algebra Midterm',
318
+ description: 'Covers chapters 1-4 on vector spaces and linear transformations',
319
+ date: '2023-11-15',
320
+ file: 'linear-algebra-midterm.pdf',
321
+ assignedTo: ['S1001', 'S1002', 'S1003'],
322
+ status: {
323
+ 'S1001': 'Submitted',
324
+ 'S1002': 'Pending',
325
+ 'S1003': 'Submitted'
326
+ }
327
+ },
328
+ {
329
+ id: 'E102',
330
+ title: 'Calculus Assignment 3',
331
+ description: 'Integration techniques and applications',
332
+ date: '2023-11-22',
333
+ file: 'calculus-assignment3.pdf',
334
+ assignedTo: ['S1001', 'S1002'],
335
+ status: {
336
+ 'S1001': 'Pending',
337
+ 'S1002': 'Submitted'
338
+ }
339
+ }
340
+ ];
341
+ localStorage.setItem(DB_KEYS.EVALUATIONS, JSON.stringify(defaultEvaluations));
342
+ }
343
+ }
344
+
345
+ // Database functions
346
+ const database = {
347
+ getStudents() {
348
+ const students = localStorage.getItem(DB_KEYS.STUDENTS);
349
+ return students ? JSON.parse(students) : [];
350
+ },
351
+
352
+ saveStudents(students) {
353
+ localStorage.setItem(DB_KEYS.STUDENTS, JSON.stringify(students));
354
+ },
355
+
356
+ getEvaluations() {
357
+ const evaluations = localStorage.getItem(DB_KEYS.EVALUATIONS);
358
+ return evaluations ? JSON.parse(evaluations) : [];
359
+ },
360
+
361
+ saveEvaluations(evaluations) {
362
+ localStorage.setItem(DB_KEYS.EVALUATIONS, JSON.stringify(evaluations));
363
+ },
364
+
365
+ teacher: {
366
+ username: 'Shaimaa Robaa',
367
+ password: 'controlpanel'
368
+ }
369
+ };
370
+
371
+ // Current user
372
+ let currentUser = null;
373
+
374
+ // DOM Elements
375
+ const loginScreen = document.getElementById('login-screen');
376
+ const studentDashboard = document.getElementById('student-dashboard');
377
+ const teacherDashboard = document.getElementById('teacher-dashboard');
378
+ const loginForm = document.getElementById('login-form');
379
+ const logoutBtn = document.getElementById('logout-btn');
380
+ const teacherLogoutBtn = document.getElementById('teacher-logout-btn');
381
+ const loginError = document.getElementById('login-error');
382
+ const errorMessage = document.getElementById('error-message');
383
+ const evaluationsContainer = document.getElementById('evaluations-container');
384
+ const noEvaluations = document.getElementById('no-evaluations');
385
+ const studentName = document.getElementById('student-name');
386
+ const studentId = document.getElementById('student-id');
387
+
388
+ // Teacher dashboard elements
389
+ const manageStudentsTab = document.getElementById('manage-students-tab');
390
+ const uploadEvaluationsTab = document.getElementById('upload-evaluations-tab');
391
+ const manageStudentsPanel = document.getElementById('manage-students-panel');
392
+ const uploadEvaluationsPanel = document.getElementById('upload-evaluations-panel');
393
+ const addStudentForm = document.getElementById('add-student-form');
394
+ const studentList = document.getElementById('student-list');
395
+ const noStudents = document.getElementById('no-students');
396
+ const uploadEvaluationForm = document.getElementById('upload-evaluation-form');
397
+ const teacherEvaluationsContainer = document.getElementById('teacher-evaluations-container');
398
+ const noTeacherEvaluations = document.getElementById('no-teacher-evaluations');
399
+
400
+ // Event Listeners
401
+ loginForm.addEventListener('submit', handleLogin);
402
+ logoutBtn.addEventListener('click', handleLogout);
403
+ teacherLogoutBtn.addEventListener('click', handleLogout);
404
+ manageStudentsTab.addEventListener('click', () => switchTeacherTab('manage'));
405
+ uploadEvaluationsTab.addEventListener('click', () => switchTeacherTab('upload'));
406
+ addStudentForm.addEventListener('submit', handleAddStudent);
407
+ uploadEvaluationForm.addEventListener('submit', handleUploadEvaluation);
408
+
409
+ // Initialize the app
410
+ function init() {
411
+ initializeDatabase();
412
+
413
+ // Check if user is already logged in (from session storage)
414
+ const storedUser = sessionStorage.getItem('currentUser');
415
+ if (storedUser) {
416
+ currentUser = JSON.parse(storedUser);
417
+ if (currentUser.username === database.teacher.username) {
418
+ showTeacherDashboard();
419
+ loadStudents();
420
+ loadTeacherEvaluations();
421
+ } else {
422
+ showStudentDashboard();
423
+ loadStudentEvaluations();
424
+ }
425
+ } else {
426
+ showLoginScreen();
427
+ }
428
+ }
429
+
430
+ // Handle login
431
+ function handleLogin(e) {
432
+ e.preventDefault();
433
+
434
+ const username = document.getElementById('username').value;
435
+ const password = document.getElementById('password').value;
436
+
437
+ // Check if teacher is logging in
438
+ if (username === database.teacher.username && password === database.teacher.password) {
439
+ currentUser = { username: database.teacher.username, role: 'teacher' };
440
+ sessionStorage.setItem('currentUser', JSON.stringify(currentUser));
441
+ showTeacherDashboard();
442
+ loadStudents();
443
+ loadTeacherEvaluations();
444
+ return;
445
+ }
446
+
447
+ // Check if student is logging in
448
+ const students = database.getStudents();
449
+ const student = students.find(s => s.username === username && s.password === password);
450
+ if (student) {
451
+ currentUser = {
452
+ username: student.username,
453
+ id: student.id,
454
+ name: student.name,
455
+ email: student.email,
456
+ role: 'student'
457
+ };
458
+ sessionStorage.setItem('currentUser', JSON.stringify(currentUser));
459
+ showStudentDashboard();
460
+ loadStudentEvaluations();
461
+ return;
462
+ }
463
+
464
+ // Invalid credentials
465
+ showLoginError();
466
+ }
467
+
468
+ // Show login error
469
+ function showLoginError() {
470
+ loginError.classList.remove('hidden');
471
+ loginForm.classList.add('shake');
472
+ setTimeout(() => {
473
+ loginForm.classList.remove('shake');
474
+ }, 500);
475
+ }
476
+
477
+ // Handle logout
478
+ function handleLogout() {
479
+ currentUser = null;
480
+ sessionStorage.removeItem('currentUser');
481
+ showLoginScreen();
482
+ loginForm.reset();
483
+ }
484
+
485
+ // Show login screen
486
+ function showLoginScreen() {
487
+ loginScreen.classList.remove('hidden');
488
+ studentDashboard.classList.add('hidden');
489
+ teacherDashboard.classList.add('hidden');
490
+ loginError.classList.add('hidden');
491
+ }
492
+
493
+ // Show student dashboard
494
+ function showStudentDashboard() {
495
+ loginScreen.classList.add('hidden');
496
+ studentDashboard.classList.remove('hidden');
497
+ teacherDashboard.classList.add('hidden');
498
+
499
+ // Set student info
500
+ studentName.textContent = currentUser.name;
501
+ studentId.textContent = currentUser.id;
502
+ }
503
+
504
+ // Show teacher dashboard
505
+ function showTeacherDashboard() {
506
+ loginScreen.classList.add('hidden');
507
+ studentDashboard.classList.add('hidden');
508
+ teacherDashboard.classList.remove('hidden');
509
+ }
510
+
511
+ // Load student evaluations
512
+ function loadStudentEvaluations() {
513
+ const studentEvaluations = database.getEvaluations().filter(eval =>
514
+ eval.assignedTo.includes(currentUser.id)
515
+ );
516
+
517
+ evaluationsContainer.innerHTML = '';
518
+
519
+ if (studentEvaluations.length === 0) {
520
+ noEvaluations.classList.remove('hidden');
521
+ return;
522
+ }
523
+
524
+ noEvaluations.classList.add('hidden');
525
+
526
+ studentEvaluations.forEach(eval => {
527
+ const status = eval.status[currentUser.id] || 'Pending';
528
+ const statusColor = getStatusColor(status);
529
+
530
+ const evalCard = document.createElement('div');
531
+ evalCard.className = 'evaluation-card bg-white rounded-lg shadow p-6';
532
+ evalCard.innerHTML = `
533
+ <div class="flex justify-between items-start">
534
+ <div>
535
+ <h3 class="text-lg font-semibold text-gray-800">${eval.title}</h3>
536
+ <p class="text-gray-600 mt-1">${eval.description}</p>
537
+ </div>
538
+ <span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${statusColor}">
539
+ ${status}
540
+ </span>
541
+ </div>
542
+ <div class="mt-4 flex items-center text-sm text-gray-500">
543
+ <i class="far fa-calendar-alt mr-2"></i>
544
+ Due: ${formatDate(eval.date)}
545
+ </div>
546
+ <div class="mt-4">
547
+ <a href="#" class="inline-flex items-center text-indigo-600 hover:text-indigo-800">
548
+ <i class="far fa-file-pdf mr-2"></i> Download Evaluation
549
+ </a>
550
+ </div>
551
+ ${status === 'Pending' ? `
552
+ <div class="mt-4">
553
+ <button class="w-full inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
554
+ Submit Solution
555
+ </button>
556
+ </div>
557
+ ` : ''}
558
+ `;
559
+
560
+ evaluationsContainer.appendChild(evalCard);
561
+ });
562
+ }
563
+
564
+ // Load students for teacher dashboard
565
+ function loadStudents() {
566
+ studentList.innerHTML = '';
567
+
568
+ const students = database.getStudents();
569
+
570
+ if (students.length === 0) {
571
+ noStudents.classList.remove('hidden');
572
+ return;
573
+ }
574
+
575
+ noStudents.classList.add('hidden');
576
+
577
+ students.forEach(student => {
578
+ const studentRow = document.createElement('tr');
579
+ studentRow.innerHTML = `
580
+ <td class="px-6 py-4 whitespace-nowrap">
581
+ <div class="flex items-center">
582
+ <div class="flex-shrink-0 h-10 w-10 rounded-full bg-indigo-100 flex items-center justify-center">
583
+ <i class="fas fa-user text-indigo-600"></i>
584
+ </div>
585
+ <div class="ml-4">
586
+ <div class="text-sm font-medium text-gray-900">${student.name}</div>
587
+ <div class="text-sm text-gray-500">${student.id}</div>
588
+ </div>
589
+ </div>
590
+ </td>
591
+ <td class="px-6 py-4 whitespace-nowrap">
592
+ <div class="text-sm text-gray-900">${student.username}</div>
593
+ </td>
594
+ <td class="px-6 py-4 whitespace-nowrap">
595
+ <div class="text-sm text-gray-900">${student.email}</div>
596
+ </td>
597
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
598
+ <button class="text-indigo-600 hover:text-indigo-900 mr-3 edit-student" data-id="${student.id}">
599
+ <i class="fas fa-edit"></i>
600
+ </button>
601
+ <button class="text-red-600 hover:text-red-900 delete-student" data-id="${student.id}">
602
+ <i class="fas fa-trash"></i>
603
+ </button>
604
+ </td>
605
+ `;
606
+
607
+ studentList.appendChild(studentRow);
608
+ });
609
+
610
+ // Add event listeners to edit and delete buttons
611
+ document.querySelectorAll('.edit-student').forEach(btn => {
612
+ btn.addEventListener('click', (e) => {
613
+ const studentId = e.currentTarget.getAttribute('data-id');
614
+ editStudent(studentId);
615
+ });
616
+ });
617
+
618
+ document.querySelectorAll('.delete-student').forEach(btn => {
619
+ btn.addEventListener('click', (e) => {
620
+ const studentId = e.currentTarget.getAttribute('data-id');
621
+ deleteStudent(studentId);
622
+ });
623
+ });
624
+ }
625
+
626
+ // Load teacher evaluations
627
+ function loadTeacherEvaluations() {
628
+ teacherEvaluationsContainer.innerHTML = '';
629
+
630
+ const evaluations = database.getEvaluations();
631
+
632
+ if (evaluations.length === 0) {
633
+ noTeacherEvaluations.classList.remove('hidden');
634
+ return;
635
+ }
636
+
637
+ noTeacherEvaluations.classList.add('hidden');
638
+
639
+ evaluations.forEach(eval => {
640
+ const students = database.getStudents();
641
+ const assignedStudents = eval.assignedTo.map(id => {
642
+ const student = students.find(s => s.id === id);
643
+ return student ? student.name : '';
644
+ }).filter(name => name !== '');
645
+
646
+ const submittedCount = Object.values(eval.status).filter(s => s === 'Submitted').length;
647
+ const totalCount = eval.assignedTo.length;
648
+
649
+ const evalCard = document.createElement('div');
650
+ evalCard.className = 'evaluation-card bg-white rounded-lg shadow p-6';
651
+ evalCard.innerHTML = `
652
+ <div class="flex justify-between items-start">
653
+ <div>
654
+ <h3 class="text-lg font-semibold text-gray-800">${eval.title}</h3>
655
+ <p class="text-gray-600 mt-1">${eval.description}</p>
656
+ </div>
657
+ <span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800">
658
+ ${submittedCount}/${totalCount} submitted
659
+ </span>
660
+ </div>
661
+ <div class="mt-4 flex items-center text-sm text-gray-500">
662
+ <i class="far fa-calendar-alt mr-2"></i>
663
+ Due: ${formatDate(eval.date)}
664
+ </div>
665
+ <div class="mt-3">
666
+ <span class="text-sm text-gray-600">Assigned to:</span>
667
+ <div class="mt-1 flex flex-wrap gap-2">
668
+ ${assignedStudents.map(name => `
669
+ <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
670
+ ${name}
671
+ </span>
672
+ `).join('')}
673
+ </div>
674
+ </div>
675
+ <div class="mt-4 flex space-x-3">
676
+ <a href="#" class="inline-flex items-center text-indigo-600 hover:text-indigo-800">
677
+ <i class="far fa-file-pdf mr-2"></i> Download
678
+ </a>
679
+ <a href="#" class="inline-flex items-center text-gray-600 hover:text-gray-800">
680
+ <i class="fas fa-list-check mr-2"></i> View Submissions
681
+ </a>
682
+ <a href="#" class="inline-flex items-center text-gray-600 hover:text-gray-800">
683
+ <i class="fas fa-edit mr-2"></i> Edit
684
+ </a>
685
+ </div>
686
+ `;
687
+
688
+ teacherEvaluationsContainer.appendChild(evalCard);
689
+ });
690
+ }
691
+
692
+ // Switch between teacher tabs
693
+ function switchTeacherTab(tab) {
694
+ if (tab === 'manage') {
695
+ manageStudentsTab.classList.remove('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
696
+ manageStudentsTab.classList.add('border-indigo-500', 'text-indigo-600');
697
+
698
+ uploadEvaluationsTab.classList.remove('border-indigo-500', 'text-indigo-600');
699
+ uploadEvaluationsTab.classList.add('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
700
+
701
+ manageStudentsPanel.classList.remove('hidden');
702
+ uploadEvaluationsPanel.classList.add('hidden');
703
+ } else {
704
+ uploadEvaluationsTab.classList.remove('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
705
+ uploadEvaluationsTab.classList.add('border-indigo-500', 'text-indigo-600');
706
+
707
+ manageStudentsTab.classList.remove('border-indigo-500', 'text-indigo-600');
708
+ manageStudentsTab.classList.add('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
709
+
710
+ uploadEvaluationsPanel.classList.remove('hidden');
711
+ manageStudentsPanel.classList.add('hidden');
712
+ }
713
+ }
714
+
715
+ // Handle add student
716
+ function handleAddStudent(e) {
717
+ e.preventDefault();
718
+
719
+ const firstname = document.getElementById('student-firstname').value;
720
+ const lastname = document.getElementById('student-lastname').value;
721
+ const email = document.getElementById('student-email').value;
722
+ const username = document.getElementById('student-username').value;
723
+ const password = document.getElementById('student-password').value;
724
+
725
+ // Generate student ID
726
+ const students = database.getStudents();
727
+ const id = 'S' + (1000 + students.length + 1);
728
+
729
+ // Create new student
730
+ const newStudent = {
731
+ id,
732
+ username,
733
+ password,
734
+ name: `${firstname} ${lastname}`,
735
+ email
736
+ };
737
+
738
+ // Add to database
739
+ students.push(newStudent);
740
+ database.saveStudents(students);
741
+
742
+ // Reload students
743
+ loadStudents();
744
+
745
+ // Reset form
746
+ addStudentForm.reset();
747
+
748
+ // Show success message
749
+ showAlert('Student added successfully!', 'success');
750
+ }
751
+
752
+ // Edit student
753
+ function editStudent(studentId) {
754
+ const students = database.getStudents();
755
+ const student = students.find(s => s.id === studentId);
756
+ if (student) {
757
+ // In a real app, you would show a modal or form to edit the student
758
+ // For this demo, we'll just show a prompt for each field
759
+ const newName = prompt('Edit student name:', student.name);
760
+ if (newName !== null) {
761
+ student.name = newName;
762
+
763
+ const newUsername = prompt('Edit username:', student.username);
764
+ if (newUsername !== null) student.username = newUsername;
765
+
766
+ const newEmail = prompt('Edit email:', student.email);
767
+ if (newEmail !== null) student.email = newEmail;
768
+
769
+ // Save changes
770
+ database.saveStudents(students);
771
+ loadStudents();
772
+ showAlert('Student updated successfully!', 'success');
773
+ }
774
+ }
775
+ }
776
+
777
+ // Delete student
778
+ function deleteStudent(studentId) {
779
+ if (confirm('Are you sure you want to delete this student?')) {
780
+ const students = database.getStudents();
781
+ const index = students.findIndex(s => s.id === studentId);
782
+ if (index !== -1) {
783
+ students.splice(index, 1);
784
+ database.saveStudents(students);
785
+ loadStudents();
786
+ showAlert('Student deleted successfully!', 'success');
787
+ }
788
+ }
789
+ }
790
+
791
+ // Handle upload evaluation
792
+ function handleUploadEvaluation(e) {
793
+ e.preventDefault();
794
+
795
+ const title = document.getElementById('evaluation-title').value;
796
+ const description = document.getElementById('evaluation-description').value;
797
+ const date = document.getElementById('evaluation-date').value;
798
+
799
+ // In a real app, you would handle file upload here
800
+ const fileInput = document.getElementById('file-upload');
801
+ const fileName = fileInput.files.length > 0 ? fileInput.files[0].name : 'evaluation.pdf';
802
+
803
+ // Generate evaluation ID
804
+ const evaluations = database.getEvaluations();
805
+ const id = 'E' + (100 + evaluations.length + 1);
806
+
807
+ // Get all student IDs
808
+ const students = database.getStudents();
809
+ const assignedTo = students.map(s => s.id);
810
+
811
+ // Create status object with all students as pending
812
+ const status = {};
813
+ assignedTo.forEach(id => {
814
+ status[id] = 'Pending';
815
+ });
816
+
817
+ // Create new evaluation
818
+ const newEvaluation = {
819
+ id,
820
+ title,
821
+ description,
822
+ date,
823
+ file: fileName,
824
+ assignedTo,
825
+ status
826
+ };
827
+
828
+ // Add to database
829
+ evaluations.push(newEvaluation);
830
+ database.saveEvaluations(evaluations);
831
+
832
+ // Reload evaluations
833
+ loadTeacherEvaluations();
834
+
835
+ // Reset form
836
+ uploadEvaluationForm.reset();
837
+
838
+ // Show success message
839
+ showAlert('Evaluation uploaded successfully!', 'success');
840
+ }
841
+
842
+ // Show alert message
843
+ function showAlert(message, type) {
844
+ const alertDiv = document.createElement('div');
845
+ alertDiv.className = `fixed top-4 right-4 px-4 py-3 rounded shadow-lg ${type === 'success' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}`;
846
+ alertDiv.innerHTML = `
847
+ <div class="flex items-center">
848
+ <i class="fas ${type === 'success' ? 'fa-check-circle' : 'fa-exclamation-circle'} mr-2"></i>
849
+ <span>${message}</span>
850
+ </div>
851
+ `;
852
+
853
+ document.body.appendChild(alertDiv);
854
+
855
+ setTimeout(() => {
856
+ alertDiv.classList.add('opacity-0', 'transition-opacity', 'duration-500');
857
+ setTimeout(() => {
858
+ alertDiv.remove();
859
+ }, 500);
860
+ }, 3000);
861
+ }
862
+
863
+ // Helper functions
864
+ function formatDate(dateString) {
865
+ const options = { year: 'numeric', month: 'long', day: 'numeric' };
866
+ return new Date(dateString).toLocaleDateString(undefined, options);
867
+ }
868
+
869
+ function getStatusColor(status) {
870
+ if (status === 'Submitted') return 'bg-green-100 text-green-800';
871
+ if (status === 'Pending') return 'bg-yellow-100 text-yellow-800';
872
+ if (status === 'Late') return 'bg-red-100 text-red-800';
873
+ return 'bg-gray-100 text-gray-800';
874
+ }
875
+
876
+ // Initialize the app
877
+ init();
878
+ </script>
879
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ABSONUMBER1/evaluation" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
880
+ </html>