Jacksonnavigator7 commited on
Commit
f7d66b5
·
verified ·
1 Parent(s): 6381676

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +1147 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Attendancy System
3
- emoji: 🦀
4
- colorFrom: gray
5
- colorTo: yellow
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: attendancy-system
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: purple
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,1147 @@
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>Mobile Attendance 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
+ .hidden {
11
+ display: none;
12
+ }
13
+ .active-tab {
14
+ border-bottom: 3px solid #3b82f6;
15
+ color: #3b82f6;
16
+ font-weight: 600;
17
+ }
18
+ .attendance-card:hover {
19
+ transform: translateY(-2px);
20
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
21
+ }
22
+ .progress-bar {
23
+ height: 8px;
24
+ border-radius: 4px;
25
+ background-color: #e5e7eb;
26
+ }
27
+ .progress-fill {
28
+ height: 100%;
29
+ border-radius: 4px;
30
+ background-color: #3b82f6;
31
+ transition: width 0.5s ease-in-out;
32
+ }
33
+ #deviceIdDisplay {
34
+ font-family: monospace;
35
+ background-color: #f3f4f6;
36
+ padding: 0.25rem 0.5rem;
37
+ border-radius: 0.25rem;
38
+ font-size: 0.875rem;
39
+ }
40
+ </style>
41
+ </head>
42
+ <body class="bg-gray-50 min-h-screen">
43
+ <!-- Login Screen -->
44
+ <div id="loginScreen" class="flex flex-col items-center justify-center min-h-screen p-4">
45
+ <div class="w-full max-w-md bg-white rounded-lg shadow-md p-8">
46
+ <div class="text-center mb-8">
47
+ <i class="fas fa-user-graduate text-5xl text-blue-500 mb-4"></i>
48
+ <h1 class="text-3xl font-bold text-gray-800">Attendance System</h1>
49
+ <p class="text-gray-600 mt-2">Sign in to access your account</p>
50
+ </div>
51
+
52
+ <form id="loginForm" class="space-y-6">
53
+ <div>
54
+ <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
55
+ <input type="email" id="email" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
56
+ </div>
57
+
58
+ <div>
59
+ <label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
60
+ <input type="password" id="password" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
61
+ </div>
62
+
63
+ <div class="flex items-center justify-between">
64
+ <div class="flex items-center">
65
+ <input type="checkbox" id="remember" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
66
+ <label for="remember" class="ml-2 block text-sm text-gray-700">Remember me</label>
67
+ </div>
68
+ <a href="#" class="text-sm text-blue-600 hover:text-blue-500">Forgot password?</a>
69
+ </div>
70
+
71
+ <button type="submit" class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition duration-150">
72
+ Sign In
73
+ </button>
74
+ </form>
75
+
76
+ <div class="mt-6 text-center">
77
+ <p class="text-sm text-gray-600">Don't have an account? <a href="#" class="text-blue-600 hover:text-blue-500 font-medium">Contact admin</a></p>
78
+ </div>
79
+ </div>
80
+ </div>
81
+
82
+ <!-- Teacher Dashboard -->
83
+ <div id="teacherDashboard" class="hidden min-h-screen">
84
+ <header class="bg-white shadow-sm">
85
+ <div class="max-w-7xl mx-auto px-4 py-4 sm:px-6 lg:px-8 flex justify-between items-center">
86
+ <h1 class="text-xl font-semibold text-gray-900">Teacher Dashboard</h1>
87
+ <div class="flex items-center space-x-4">
88
+ <span id="teacherName" class="text-gray-700">John Doe</span>
89
+ <button id="teacherLogout" class="text-gray-500 hover:text-gray-700">
90
+ <i class="fas fa-sign-out-alt"></i>
91
+ </button>
92
+ </div>
93
+ </div>
94
+
95
+ <div class="border-b border-gray-200">
96
+ <nav class="-mb-px flex space-x-8 px-4">
97
+ <button id="teacherSessionsTab" class="py-4 px-1 border-b-2 font-medium text-sm active-tab">
98
+ Attendance Sessions
99
+ </button>
100
+ <button id="teacherStudentsTab" class="py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">
101
+ Manage Students
102
+ </button>
103
+ <button id="teacherReportsTab" class="py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">
104
+ Reports
105
+ </button>
106
+ </nav>
107
+ </div>
108
+ </header>
109
+
110
+ <main class="max-w-7xl mx-auto px-4 py-6 sm:px-6 lg:px-8">
111
+ <!-- Sessions Tab Content -->
112
+ <div id="teacherSessionsContent" class="space-y-6">
113
+ <div class="flex justify-between items-center">
114
+ <h2 class="text-lg font-medium text-gray-900">Current Sessions</h2>
115
+ <button id="createSessionBtn" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
116
+ <i class="fas fa-plus mr-2"></i> New Session
117
+ </button>
118
+ </div>
119
+
120
+ <div id="activeSessions" class="bg-white shadow overflow-hidden sm:rounded-md">
121
+ <ul class="divide-y divide-gray-200">
122
+ <!-- Active sessions will be added here dynamically -->
123
+ </ul>
124
+ </div>
125
+
126
+ <h2 class="text-lg font-medium text-gray-900">Session History</h2>
127
+ <div id="pastSessions" class="bg-white shadow overflow-hidden sm:rounded-md">
128
+ <ul class="divide-y divide-gray-200">
129
+ <!-- Past sessions will be added here dynamically -->
130
+ </ul>
131
+ </div>
132
+ </div>
133
+
134
+ <!-- Students Tab Content -->
135
+ <div id="teacherStudentsContent" class="hidden space-y-6">
136
+ <div class="flex justify-between items-center">
137
+ <h2 class="text-lg font-medium text-gray-900">Class Students</h2>
138
+ <button id="addStudentBtn" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
139
+ <i class="fas fa-user-plus mr-2"></i> Add Student
140
+ </button>
141
+ </div>
142
+
143
+ <div class="bg-white shadow overflow-hidden sm:rounded-md">
144
+ <ul id="studentsList" class="divide-y divide-gray-200">
145
+ <!-- Students will be added here dynamically -->
146
+ </ul>
147
+ </div>
148
+ </div>
149
+
150
+ <!-- Reports Tab Content -->
151
+ <div id="teacherReportsContent" class="hidden">
152
+ <h2 class="text-lg font-medium text-gray-900 mb-4">Attendance Reports</h2>
153
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
154
+ <div class="bg-white p-6 rounded-lg shadow">
155
+ <h3 class="text-md font-medium text-gray-900 mb-4">Class Attendance Summary</h3>
156
+ <div id="classAttendanceChart" class="h-64">
157
+ <!-- Chart will be rendered here -->
158
+ </div>
159
+ </div>
160
+ <div class="bg-white p-6 rounded-lg shadow">
161
+ <h3 class="text-md font-medium text-gray-900 mb-4">Recent Attendance</h3>
162
+ <div id="recentAttendanceTable" class="overflow-x-auto">
163
+ <!-- Table will be rendered here -->
164
+ </div>
165
+ </div>
166
+ </div>
167
+ </div>
168
+ </main>
169
+
170
+ <!-- Create Session Modal -->
171
+ <div id="createSessionModal" class="hidden fixed inset-0 overflow-y-auto z-10">
172
+ <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
173
+ <div class="fixed inset-0 transition-opacity" aria-hidden="true">
174
+ <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
175
+ </div>
176
+
177
+ <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
178
+
179
+ <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
180
+ <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
181
+ <div class="sm:flex sm:items-start">
182
+ <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
183
+ <i class="fas fa-calendar-plus text-blue-600"></i>
184
+ </div>
185
+ <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
186
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Create New Attendance Session</h3>
187
+ <div class="mt-2">
188
+ <form id="createSessionForm" class="space-y-4">
189
+ <div>
190
+ <label for="sessionName" class="block text-sm font-medium text-gray-700">Session Name</label>
191
+ <input type="text" id="sessionName" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
192
+ </div>
193
+ <div>
194
+ <label for="sessionDuration" class="block text-sm font-medium text-gray-700">Duration (minutes)</label>
195
+ <input type="number" id="sessionDuration" min="1" max="120" value="15" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
196
+ </div>
197
+ <div>
198
+ <label for="sessionClass" class="block text-sm font-medium text-gray-700">Class</label>
199
+ <select id="sessionClass" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
200
+ <option>CS101</option>
201
+ <option>MATH202</option>
202
+ <option>ENG150</option>
203
+ </select>
204
+ </div>
205
+ </form>
206
+ </div>
207
+ </div>
208
+ </div>
209
+ </div>
210
+ <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
211
+ <button type="button" id="confirmCreateSession" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
212
+ Create Session
213
+ </button>
214
+ <button type="button" id="cancelCreateSession" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
215
+ Cancel
216
+ </button>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ </div>
221
+
222
+ <!-- Add Student Modal -->
223
+ <div id="addStudentModal" class="hidden fixed inset-0 overflow-y-auto z-10">
224
+ <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
225
+ <div class="fixed inset-0 transition-opacity" aria-hidden="true">
226
+ <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
227
+ </div>
228
+
229
+ <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
230
+
231
+ <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
232
+ <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
233
+ <div class="sm:flex sm:items-start">
234
+ <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
235
+ <i class="fas fa-user-plus text-blue-600"></i>
236
+ </div>
237
+ <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
238
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Add New Student</h3>
239
+ <div class="mt-2">
240
+ <form id="addStudentForm" class="space-y-4">
241
+ <div>
242
+ <label for="studentName" class="block text-sm font-medium text-gray-700">Full Name</label>
243
+ <input type="text" id="studentName" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
244
+ </div>
245
+ <div>
246
+ <label for="studentEmail" class="block text-sm font-medium text-gray-700">Email</label>
247
+ <input type="email" id="studentEmail" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
248
+ </div>
249
+ <div>
250
+ <label for="studentId" class="block text-sm font-medium text-gray-700">Student ID</label>
251
+ <input type="text" id="studentId" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
252
+ </div>
253
+ <div>
254
+ <label for="studentClass" class="block text-sm font-medium text-gray-700">Class</label>
255
+ <select id="studentClass" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
256
+ <option>CS101</option>
257
+ <option>MATH202</option>
258
+ <option>ENG150</option>
259
+ </select>
260
+ </div>
261
+ </form>
262
+ </div>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
267
+ <button type="button" id="confirmAddStudent" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
268
+ Add Student
269
+ </button>
270
+ <button type="button" id="cancelAddStudent" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
271
+ Cancel
272
+ </button>
273
+ </div>
274
+ </div>
275
+ </div>
276
+ </div>
277
+ </div>
278
+
279
+ <!-- Student Dashboard -->
280
+ <div id="studentDashboard" class="hidden min-h-screen">
281
+ <header class="bg-white shadow-sm">
282
+ <div class="max-w-7xl mx-auto px-4 py-4 sm:px-6 lg:px-8 flex justify-between items-center">
283
+ <h1 class="text-xl font-semibold text-gray-900">Student Dashboard</h1>
284
+ <div class="flex items-center space-x-4">
285
+ <span id="studentName" class="text-gray-700">Jane Smith</span>
286
+ <button id="studentLogout" class="text-gray-500 hover:text-gray-700">
287
+ <i class="fas fa-sign-out-alt"></i>
288
+ </button>
289
+ </div>
290
+ </div>
291
+
292
+ <div class="border-b border-gray-200">
293
+ <nav class="-mb-px flex space-x-8 px-4">
294
+ <button id="studentAttendanceTab" class="py-4 px-1 border-b-2 font-medium text-sm active-tab">
295
+ Mark Attendance
296
+ </button>
297
+ <button id="studentHistoryTab" class="py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">
298
+ My History
299
+ </button>
300
+ <button id="studentStatsTab" class="py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">
301
+ My Stats
302
+ </button>
303
+ </nav>
304
+ </div>
305
+ </header>
306
+
307
+ <main class="max-w-7xl mx-auto px-4 py-6 sm:px-6 lg:px-8">
308
+ <!-- Attendance Tab Content -->
309
+ <div id="studentAttendanceContent" class="space-y-6">
310
+ <div class="bg-white shadow overflow-hidden sm:rounded-lg">
311
+ <div class="px-4 py-5 sm:px-6 border-b border-gray-200">
312
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Current Attendance Sessions</h3>
313
+ <p class="mt-1 text-sm text-gray-500">Available sessions where you can mark your attendance.</p>
314
+ </div>
315
+ <div id="availableSessions" class="divide-y divide-gray-200">
316
+ <!-- Available sessions will be added here dynamically -->
317
+ </div>
318
+ </div>
319
+
320
+ <div class="bg-white shadow overflow-hidden sm:rounded-lg">
321
+ <div class="px-4 py-5 sm:px-6 border-b border-gray-200">
322
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Device Information</h3>
323
+ <p class="mt-1 text-sm text-gray-500">Your attendance is tied to this device for security.</p>
324
+ </div>
325
+ <div class="px-4 py-5 sm:p-6">
326
+ <div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
327
+ <div>
328
+ <label class="block text-sm font-medium text-gray-700">Device ID</label>
329
+ <div id="deviceIdDisplay" class="mt-1">Loading...</div>
330
+ </div>
331
+ <div>
332
+ <label class="block text-sm font-medium text-gray-700">Status</label>
333
+ <div class="mt-1">
334
+ <span id="deviceStatus" class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
335
+ <i class="fas fa-check-circle mr-1"></i> Verified
336
+ </span>
337
+ </div>
338
+ </div>
339
+ </div>
340
+ <div class="mt-4">
341
+ <p class="text-sm text-gray-600">If you need to change your device, please contact your instructor.</p>
342
+ </div>
343
+ </div>
344
+ </div>
345
+ </div>
346
+
347
+ <!-- History Tab Content -->
348
+ <div id="studentHistoryContent" class="hidden">
349
+ <h2 class="text-lg font-medium text-gray-900 mb-4">My Attendance History</h2>
350
+ <div class="bg-white shadow overflow-hidden sm:rounded-lg">
351
+ <div class="px-4 py-5 sm:px-6 border-b border-gray-200">
352
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Recent Attendance Records</h3>
353
+ <p class="mt-1 text-sm text-gray-500">Your last 10 attendance marks.</p>
354
+ </div>
355
+ <div id="attendanceHistory" class="divide-y divide-gray-200">
356
+ <!-- Attendance history will be added here dynamically -->
357
+ </div>
358
+ </div>
359
+ </div>
360
+
361
+ <!-- Stats Tab Content -->
362
+ <div id="studentStatsContent" class="hidden">
363
+ <h2 class="text-lg font-medium text-gray-900 mb-4">My Attendance Statistics</h2>
364
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
365
+ <div class="bg-white p-6 rounded-lg shadow">
366
+ <h3 class="text-md font-medium text-gray-900 mb-4">Overall Attendance</h3>
367
+ <div class="flex items-center justify-between mb-2">
368
+ <span class="text-sm font-medium text-gray-700">Attendance Rate</span>
369
+ <span id="attendanceRate" class="text-sm font-medium text-blue-600">85%</span>
370
+ </div>
371
+ <div class="progress-bar">
372
+ <div id="attendanceProgress" class="progress-fill" style="width: 85%"></div>
373
+ </div>
374
+ <div class="mt-4 grid grid-cols-2 gap-4">
375
+ <div class="bg-blue-50 p-3 rounded-lg">
376
+ <p class="text-sm font-medium text-gray-500">Present</p>
377
+ <p id="presentCount" class="text-2xl font-semibold text-blue-600">17</p>
378
+ </div>
379
+ <div class="bg-gray-50 p-3 rounded-lg">
380
+ <p class="text-sm font-medium text-gray-500">Absent</p>
381
+ <p id="absentCount" class="text-2xl font-semibold text-gray-600">3</p>
382
+ </div>
383
+ </div>
384
+ </div>
385
+ <div class="bg-white p-6 rounded-lg shadow">
386
+ <h3 class="text-md font-medium text-gray-900 mb-4">Attendance by Class</h3>
387
+ <div id="classAttendanceStats" class="space-y-4">
388
+ <!-- Class attendance stats will be added here dynamically -->
389
+ </div>
390
+ </div>
391
+ </div>
392
+ </div>
393
+ </main>
394
+
395
+ <!-- Attendance Confirmation Modal -->
396
+ <div id="attendanceConfirmationModal" class="hidden fixed inset-0 overflow-y-auto z-10">
397
+ <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
398
+ <div class="fixed inset-0 transition-opacity" aria-hidden="true">
399
+ <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
400
+ </div>
401
+
402
+ <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
403
+
404
+ <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
405
+ <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
406
+ <div class="sm:flex sm:items-start">
407
+ <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
408
+ <i class="fas fa-check-circle text-blue-600"></i>
409
+ </div>
410
+ <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
411
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Confirm Attendance</h3>
412
+ <div class="mt-2">
413
+ <p class="text-sm text-gray-500">You are about to mark your attendance for <span id="confirmSessionName" class="font-medium">CS101 Lecture</span>.</p>
414
+ <p class="text-sm text-gray-500 mt-2">This action cannot be undone.</p>
415
+ </div>
416
+ </div>
417
+ </div>
418
+ </div>
419
+ <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
420
+ <button type="button" id="confirmAttendance" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
421
+ Confirm
422
+ </button>
423
+ <button type="button" id="cancelAttendance" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
424
+ Cancel
425
+ </button>
426
+ </div>
427
+ </div>
428
+ </div>
429
+ </div>
430
+
431
+ <!-- Attendance Success Modal -->
432
+ <div id="attendanceSuccessModal" class="hidden fixed inset-0 overflow-y-auto z-10">
433
+ <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
434
+ <div class="fixed inset-0 transition-opacity" aria-hidden="true">
435
+ <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
436
+ </div>
437
+
438
+ <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
439
+
440
+ <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
441
+ <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
442
+ <div class="sm:flex sm:items-start">
443
+ <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-green-100 sm:mx-0 sm:h-10 sm:w-10">
444
+ <i class="fas fa-check text-green-600"></i>
445
+ </div>
446
+ <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
447
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Attendance Recorded</h3>
448
+ <div class="mt-2">
449
+ <p class="text-sm text-gray-500">Your attendance for <span id="successSessionName" class="font-medium">CS101 Lecture</span> has been successfully recorded.</p>
450
+ <p class="text-sm text-gray-500 mt-2">Time: <span id="attendanceTime" class="font-medium">10:15 AM</span></p>
451
+ </div>
452
+ </div>
453
+ </div>
454
+ </div>
455
+ <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
456
+ <button type="button" id="closeSuccessModal" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
457
+ OK
458
+ </button>
459
+ </div>
460
+ </div>
461
+ </div>
462
+ </div>
463
+ </div>
464
+
465
+ <script>
466
+ // Database simulation
467
+ const db = {
468
+ users: [
469
+ { id: 1, email: 'teacher@school.edu', password: 'teacher123', name: 'John Doe', role: 'teacher' },
470
+ { id: 2, email: 'student@school.edu', password: 'student123', name: 'Jane Smith', role: 'student', studentId: 'S1001', class: 'CS101', deviceId: 'device123' },
471
+ { id: 3, email: 'student2@school.edu', password: 'student123', name: 'Mike Johnson', role: 'student', studentId: 'S1002', class: 'CS101', deviceId: 'device456' }
472
+ ],
473
+ sessions: [
474
+ { id: 1, name: 'CS101 Lecture', class: 'CS101', teacherId: 1, status: 'active', startTime: new Date(), endTime: new Date(Date.now() + 15 * 60000), attendees: [2] },
475
+ { id: 2, name: 'CS101 Lab', class: 'CS101', teacherId: 1, status: 'closed', startTime: new Date(Date.now() - 86400000), endTime: new Date(Date.now() - 86400000 + 60 * 60000), attendees: [2, 3] },
476
+ { id: 3, name: 'MATH202 Lecture', class: 'MATH202', teacherId: 1, status: 'closed', startTime: new Date(Date.now() - 2 * 86400000), endTime: new Date(Date.now() - 2 * 86400000 + 30 * 60000), attendees: [2] }
477
+ ],
478
+ attendance: [
479
+ { id: 1, sessionId: 2, studentId: 2, timestamp: new Date(Date.now() - 86400000 + 5 * 60000) },
480
+ { id: 2, sessionId: 2, studentId: 3, timestamp: new Date(Date.now() - 86400000 + 10 * 60000) },
481
+ { id: 3, sessionId: 3, studentId: 2, timestamp: new Date(Date.now() - 2 * 86400000 + 5 * 60000) }
482
+ ]
483
+ };
484
+
485
+ // Current user and device ID
486
+ let currentUser = null;
487
+ const deviceId = 'device' + Math.floor(Math.random() * 1000000);
488
+
489
+ // DOM elements
490
+ const loginScreen = document.getElementById('loginScreen');
491
+ const teacherDashboard = document.getElementById('teacherDashboard');
492
+ const studentDashboard = document.getElementById('studentDashboard');
493
+ const loginForm = document.getElementById('loginForm');
494
+ const teacherLogout = document.getElementById('teacherLogout');
495
+ const studentLogout = document.getElementById('studentLogout');
496
+
497
+ // Teacher elements
498
+ const teacherSessionsTab = document.getElementById('teacherSessionsTab');
499
+ const teacherStudentsTab = document.getElementById('teacherStudentsTab');
500
+ const teacherReportsTab = document.getElementById('teacherReportsTab');
501
+ const teacherSessionsContent = document.getElementById('teacherSessionsContent');
502
+ const teacherStudentsContent = document.getElementById('teacherStudentsContent');
503
+ const teacherReportsContent = document.getElementById('teacherReportsContent');
504
+ const createSessionBtn = document.getElementById('createSessionBtn');
505
+ const createSessionModal = document.getElementById('createSessionModal');
506
+ const cancelCreateSession = document.getElementById('cancelCreateSession');
507
+ const confirmCreateSession = document.getElementById('confirmCreateSession');
508
+ const activeSessions = document.getElementById('activeSessions');
509
+ const pastSessions = document.getElementById('pastSessions');
510
+ const addStudentBtn = document.getElementById('addStudentBtn');
511
+ const addStudentModal = document.getElementById('addStudentModal');
512
+ const cancelAddStudent = document.getElementById('cancelAddStudent');
513
+ const confirmAddStudent = document.getElementById('confirmAddStudent');
514
+ const studentsList = document.getElementById('studentsList');
515
+
516
+ // Student elements
517
+ const studentAttendanceTab = document.getElementById('studentAttendanceTab');
518
+ const studentHistoryTab = document.getElementById('studentHistoryTab');
519
+ const studentStatsTab = document.getElementById('studentStatsTab');
520
+ const studentAttendanceContent = document.getElementById('studentAttendanceContent');
521
+ const studentHistoryContent = document.getElementById('studentHistoryContent');
522
+ const studentStatsContent = document.getElementById('studentStatsContent');
523
+ const availableSessions = document.getElementById('availableSessions');
524
+ const attendanceHistory = document.getElementById('attendanceHistory');
525
+ const attendanceConfirmationModal = document.getElementById('attendanceConfirmationModal');
526
+ const confirmAttendance = document.getElementById('confirmAttendance');
527
+ const cancelAttendance = document.getElementById('cancelAttendance');
528
+ const attendanceSuccessModal = document.getElementById('attendanceSuccessModal');
529
+ const closeSuccessModal = document.getElementById('closeSuccessModal');
530
+ const deviceIdDisplay = document.getElementById('deviceIdDisplay');
531
+ const deviceStatus = document.getElementById('deviceStatus');
532
+ const attendanceRate = document.getElementById('attendanceRate');
533
+ const attendanceProgress = document.getElementById('attendanceProgress');
534
+ const presentCount = document.getElementById('presentCount');
535
+ const absentCount = document.getElementById('absentCount');
536
+ const classAttendanceStats = document.getElementById('classAttendanceStats');
537
+
538
+ // Login functionality
539
+ loginForm.addEventListener('submit', function(e) {
540
+ e.preventDefault();
541
+ const email = document.getElementById('email').value;
542
+ const password = document.getElementById('password').value;
543
+
544
+ const user = db.users.find(u => u.email === email && u.password === password);
545
+
546
+ if (user) {
547
+ currentUser = user;
548
+
549
+ if (user.role === 'teacher') {
550
+ showTeacherDashboard();
551
+ } else if (user.role === 'student') {
552
+ // Check device binding for students
553
+ if (!user.deviceId) {
554
+ // First login - bind device
555
+ user.deviceId = deviceId;
556
+ showStudentDashboard();
557
+ } else if (user.deviceId === deviceId) {
558
+ // Device matches
559
+ showStudentDashboard();
560
+ } else {
561
+ // Device doesn't match
562
+ alert('You can only access your account from your registered device. Please contact your instructor if you need to change devices.');
563
+ return;
564
+ }
565
+ }
566
+
567
+ loginScreen.classList.add('hidden');
568
+ } else {
569
+ alert('Invalid email or password');
570
+ }
571
+ });
572
+
573
+ // Logout functionality
574
+ teacherLogout.addEventListener('click', function() {
575
+ currentUser = null;
576
+ teacherDashboard.classList.add('hidden');
577
+ loginScreen.classList.remove('hidden');
578
+ resetTeacherDashboard();
579
+ });
580
+
581
+ studentLogout.addEventListener('click', function() {
582
+ currentUser = null;
583
+ studentDashboard.classList.add('hidden');
584
+ loginScreen.classList.remove('hidden');
585
+ resetStudentDashboard();
586
+ });
587
+
588
+ // Teacher dashboard tabs
589
+ teacherSessionsTab.addEventListener('click', function() {
590
+ setActiveTab('teacher', 'sessions');
591
+ });
592
+
593
+ teacherStudentsTab.addEventListener('click', function() {
594
+ setActiveTab('teacher', 'students');
595
+ });
596
+
597
+ teacherReportsTab.addEventListener('click', function() {
598
+ setActiveTab('teacher', 'reports');
599
+ });
600
+
601
+ // Student dashboard tabs
602
+ studentAttendanceTab.addEventListener('click', function() {
603
+ setActiveTab('student', 'attendance');
604
+ });
605
+
606
+ studentHistoryTab.addEventListener('click', function() {
607
+ setActiveTab('student', 'history');
608
+ });
609
+
610
+ studentStatsTab.addEventListener('click', function() {
611
+ setActiveTab('student', 'stats');
612
+ });
613
+
614
+ // Session management
615
+ createSessionBtn.addEventListener('click', function() {
616
+ createSessionModal.classList.remove('hidden');
617
+ });
618
+
619
+ cancelCreateSession.addEventListener('click', function() {
620
+ createSessionModal.classList.add('hidden');
621
+ });
622
+
623
+ confirmCreateSession.addEventListener('click', function() {
624
+ const sessionName = document.getElementById('sessionName').value;
625
+ const sessionDuration = parseInt(document.getElementById('sessionDuration').value);
626
+ const sessionClass = document.getElementById('sessionClass').value;
627
+
628
+ const newSession = {
629
+ id: db.sessions.length + 1,
630
+ name: sessionName,
631
+ class: sessionClass,
632
+ teacherId: currentUser.id,
633
+ status: 'active',
634
+ startTime: new Date(),
635
+ endTime: new Date(Date.now() + sessionDuration * 60000),
636
+ attendees: []
637
+ };
638
+
639
+ db.sessions.push(newSession);
640
+ createSessionModal.classList.add('hidden');
641
+ document.getElementById('createSessionForm').reset();
642
+ renderTeacherSessions();
643
+ });
644
+
645
+ // Student management
646
+ addStudentBtn.addEventListener('click', function() {
647
+ addStudentModal.classList.remove('hidden');
648
+ });
649
+
650
+ cancelAddStudent.addEventListener('click', function() {
651
+ addStudentModal.classList.add('hidden');
652
+ });
653
+
654
+ confirmAddStudent.addEventListener('click', function() {
655
+ const studentName = document.getElementById('studentName').value;
656
+ const studentEmail = document.getElementById('studentEmail').value;
657
+ const studentId = document.getElementById('studentId').value;
658
+ const studentClass = document.getElementById('studentClass').value;
659
+
660
+ const newStudent = {
661
+ id: db.users.length + 1,
662
+ email: studentEmail,
663
+ password: 'student123', // Default password
664
+ name: studentName,
665
+ role: 'student',
666
+ studentId: studentId,
667
+ class: studentClass,
668
+ deviceId: null // Will be set on first login
669
+ };
670
+
671
+ db.users.push(newStudent);
672
+ addStudentModal.classList.add('hidden');
673
+ document.getElementById('addStudentForm').reset();
674
+ renderStudentsList();
675
+ });
676
+
677
+ // Attendance marking
678
+ function setupAttendanceButtons() {
679
+ document.querySelectorAll('.mark-attendance-btn').forEach(button => {
680
+ button.addEventListener('click', function() {
681
+ const sessionId = parseInt(this.getAttribute('data-session-id'));
682
+ const session = db.sessions.find(s => s.id === sessionId);
683
+
684
+ document.getElementById('confirmSessionName').textContent = session.name;
685
+ document.getElementById('confirmAttendance').setAttribute('data-session-id', sessionId);
686
+ attendanceConfirmationModal.classList.remove('hidden');
687
+ });
688
+ });
689
+ }
690
+
691
+ confirmAttendance.addEventListener('click', function() {
692
+ const sessionId = parseInt(this.getAttribute('data-session-id'));
693
+ const session = db.sessions.find(s => s.id === sessionId);
694
+
695
+ // Record attendance
696
+ const newAttendance = {
697
+ id: db.attendance.length + 1,
698
+ sessionId: sessionId,
699
+ studentId: currentUser.id,
700
+ timestamp: new Date()
701
+ };
702
+
703
+ db.attendance.push(newAttendance);
704
+ session.attendees.push(currentUser.id);
705
+
706
+ // Show success
707
+ document.getElementById('successSessionName').textContent = session.name;
708
+ document.getElementById('attendanceTime').textContent = newAttendance.timestamp.toLocaleTimeString();
709
+ attendanceConfirmationModal.classList.add('hidden');
710
+ attendanceSuccessModal.classList.remove('hidden');
711
+
712
+ // Update UI
713
+ renderAvailableSessions();
714
+ });
715
+
716
+ cancelAttendance.addEventListener('click', function() {
717
+ attendanceConfirmationModal.classList.add('hidden');
718
+ });
719
+
720
+ closeSuccessModal.addEventListener('click', function() {
721
+ attendanceSuccessModal.classList.add('hidden');
722
+ });
723
+
724
+ // Helper functions
725
+ function showTeacherDashboard() {
726
+ teacherDashboard.classList.remove('hidden');
727
+ document.getElementById('teacherName').textContent = currentUser.name;
728
+ renderTeacherSessions();
729
+ renderStudentsList();
730
+ setActiveTab('teacher', 'sessions');
731
+ }
732
+
733
+ function showStudentDashboard() {
734
+ studentDashboard.classList.remove('hidden');
735
+ document.getElementById('studentName').textContent = currentUser.name;
736
+ deviceIdDisplay.textContent = currentUser.deviceId;
737
+
738
+ // Check if device matches
739
+ if (currentUser.deviceId === deviceId) {
740
+ deviceStatus.innerHTML = '<i class="fas fa-check-circle mr-1"></i> Verified';
741
+ deviceStatus.className = 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800';
742
+ } else {
743
+ deviceStatus.innerHTML = '<i class="fas fa-exclamation-triangle mr-1"></i> Mismatch';
744
+ deviceStatus.className = 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800';
745
+ }
746
+
747
+ renderAvailableSessions();
748
+ renderAttendanceHistory();
749
+ renderStudentStats();
750
+ setActiveTab('student', 'attendance');
751
+ }
752
+
753
+ function resetTeacherDashboard() {
754
+ teacherSessionsContent.classList.remove('hidden');
755
+ teacherStudentsContent.classList.add('hidden');
756
+ teacherReportsContent.classList.add('hidden');
757
+
758
+ teacherSessionsTab.classList.add('active-tab');
759
+ teacherStudentsTab.classList.remove('active-tab');
760
+ teacherReportsTab.classList.remove('active-tab');
761
+ }
762
+
763
+ function resetStudentDashboard() {
764
+ studentAttendanceContent.classList.remove('hidden');
765
+ studentHistoryContent.classList.add('hidden');
766
+ studentStatsContent.classList.add('hidden');
767
+
768
+ studentAttendanceTab.classList.add('active-tab');
769
+ studentHistoryTab.classList.remove('active-tab');
770
+ studentStatsTab.classList.remove('active-tab');
771
+ }
772
+
773
+ function setActiveTab(role, tab) {
774
+ if (role === 'teacher') {
775
+ teacherSessionsContent.classList.add('hidden');
776
+ teacherStudentsContent.classList.add('hidden');
777
+ teacherReportsContent.classList.add('hidden');
778
+
779
+ teacherSessionsTab.classList.remove('active-tab');
780
+ teacherStudentsTab.classList.remove('active-tab');
781
+ teacherReportsTab.classList.remove('active-tab');
782
+
783
+ if (tab === 'sessions') {
784
+ teacherSessionsContent.classList.remove('hidden');
785
+ teacherSessionsTab.classList.add('active-tab');
786
+ renderTeacherSessions();
787
+ } else if (tab === 'students') {
788
+ teacherStudentsContent.classList.remove('hidden');
789
+ teacherStudentsTab.classList.add('active-tab');
790
+ renderStudentsList();
791
+ } else if (tab === 'reports') {
792
+ teacherReportsContent.classList.remove('hidden');
793
+ teacherReportsTab.classList.add('active-tab');
794
+ renderTeacherReports();
795
+ }
796
+ } else if (role === 'student') {
797
+ studentAttendanceContent.classList.add('hidden');
798
+ studentHistoryContent.classList.add('hidden');
799
+ studentStatsContent.classList.add('hidden');
800
+
801
+ studentAttendanceTab.classList.remove('active-tab');
802
+ studentHistoryTab.classList.remove('active-tab');
803
+ studentStatsTab.classList.remove('active-tab');
804
+
805
+ if (tab === 'attendance') {
806
+ studentAttendanceContent.classList.remove('hidden');
807
+ studentAttendanceTab.classList.add('active-tab');
808
+ renderAvailableSessions();
809
+ } else if (tab === 'history') {
810
+ studentHistoryContent.classList.remove('hidden');
811
+ studentHistoryTab.classList.add('active-tab');
812
+ renderAttendanceHistory();
813
+ } else if (tab === 'stats') {
814
+ studentStatsContent.classList.remove('hidden');
815
+ studentStatsTab.classList.add('active-tab');
816
+ renderStudentStats();
817
+ }
818
+ }
819
+ }
820
+
821
+ function renderTeacherSessions() {
822
+ // Active sessions
823
+ const activeSessionsList = db.sessions.filter(s => s.status === 'active' && s.teacherId === currentUser.id);
824
+ const activeSessionsUl = document.querySelector('#activeSessions ul');
825
+ activeSessionsUl.innerHTML = '';
826
+
827
+ if (activeSessionsList.length === 0) {
828
+ activeSessionsUl.innerHTML = '<li class="px-4 py-4 text-center text-gray-500">No active sessions</li>';
829
+ } else {
830
+ activeSessionsList.forEach(session => {
831
+ const attendeesCount = session.attendees.length;
832
+ const studentsCount = db.users.filter(u => u.role === 'student' && u.class === session.class).length;
833
+
834
+ const li = document.createElement('li');
835
+ li.className = 'px-4 py-4';
836
+ li.innerHTML = `
837
+ <div class="flex items-center justify-between">
838
+ <div class="flex items-center">
839
+ <div class="min-w-0 flex-1">
840
+ <div class="flex items-center">
841
+ <p class="text-sm font-medium text-blue-600 truncate">${session.name}</p>
842
+ <span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
843
+ ${session.class}
844
+ </span>
845
+ </div>
846
+ <div class="mt-2 flex">
847
+ <div class="flex items-center text-sm text-gray-500">
848
+ <i class="fas fa-users mr-1.5"></i>
849
+ <span>${attendeesCount}/${studentsCount} students</span>
850
+ </div>
851
+ <div class="ml-3 flex items-center text-sm text-gray-500">
852
+ <i class="fas fa-clock mr-1.5"></i>
853
+ <span>Ends at ${session.endTime.toLocaleTimeString()}</span>
854
+ </div>
855
+ </div>
856
+ </div>
857
+ </div>
858
+ <div>
859
+ <button class="close-session-btn inline-flex items-center px-3 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500" data-session-id="${session.id}">
860
+ <i class="fas fa-times mr-1"></i> Close
861
+ </button>
862
+ </div>
863
+ </div>
864
+ `;
865
+ activeSessionsUl.appendChild(li);
866
+ });
867
+ }
868
+
869
+ // Past sessions
870
+ const pastSessionsList = db.sessions.filter(s => s.status === 'closed' && s.teacherId === currentUser.id)
871
+ .sort((a, b) => b.startTime - a.startTime);
872
+ const pastSessionsUl = document.querySelector('#pastSessions ul');
873
+ pastSessionsUl.innerHTML = '';
874
+
875
+ if (pastSessionsList.length === 0) {
876
+ pastSessionsUl.innerHTML = '<li class="px-4 py-4 text-center text-gray-500">No past sessions</li>';
877
+ } else {
878
+ pastSessionsList.forEach(session => {
879
+ const attendeesCount = session.attendees.length;
880
+ const studentsCount = db.users.filter(u => u.role === 'student' && u.class === session.class).length;
881
+
882
+ const li = document.createElement('li');
883
+ li.className = 'px-4 py-4';
884
+ li.innerHTML = `
885
+ <div class="flex items-center justify-between">
886
+ <div class="flex items-center">
887
+ <div class="min-w-0 flex-1">
888
+ <div class="flex items-center">
889
+ <p class="text-sm font-medium text-gray-900 truncate">${session.name}</p>
890
+ <span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
891
+ ${session.class}
892
+ </span>
893
+ </div>
894
+ <div class="mt-2 flex">
895
+ <div class="flex items-center text-sm text-gray-500">
896
+ <i class="fas fa-users mr-1.5"></i>
897
+ <span>${attendeesCount}/${studentsCount} students</span>
898
+ </div>
899
+ <div class="ml-3 flex items-center text-sm text-gray-500">
900
+ <i class="fas fa-calendar-day mr-1.5"></i>
901
+ <span>${session.startTime.toLocaleDateString()}</span>
902
+ </div>
903
+ </div>
904
+ </div>
905
+ </div>
906
+ <div>
907
+ <button class="view-session-btn inline-flex items-center px-3 py-1.5 border border-gray-300 text-xs font-medium rounded shadow-sm text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" data-session-id="${session.id}">
908
+ <i class="fas fa-eye mr-1"></i> View
909
+ </button>
910
+ </div>
911
+ </div>
912
+ `;
913
+ pastSessionsUl.appendChild(li);
914
+ });
915
+ }
916
+
917
+ // Add event listeners to buttons
918
+ document.querySelectorAll('.close-session-btn').forEach(button => {
919
+ button.addEventListener('click', function() {
920
+ const sessionId = parseInt(this.getAttribute('data-session-id'));
921
+ const session = db.sessions.find(s => s.id === sessionId);
922
+ session.status = 'closed';
923
+ renderTeacherSessions();
924
+ });
925
+ });
926
+
927
+ document.querySelectorAll('.view-session-btn').forEach(button => {
928
+ button.addEventListener('click', function() {
929
+ const sessionId = parseInt(this.getAttribute('data-session-id'));
930
+ // In a real app, this would show detailed session info
931
+ alert('Viewing session details would show here');
932
+ });
933
+ });
934
+ }
935
+
936
+ function renderStudentsList() {
937
+ const students = db.users.filter(u => u.role === 'student' && u.class === 'CS101'); // Simplified for demo
938
+ studentsList.innerHTML = '';
939
+
940
+ if (students.length === 0) {
941
+ studentsList.innerHTML = '<li class="px-4 py-4 text-center text-gray-500">No students in this class</li>';
942
+ } else {
943
+ students.forEach(student => {
944
+ const li = document.createElement('li');
945
+ li.className = 'px-4 py-4';
946
+ li.innerHTML = `
947
+ <div class="flex items-center justify-between">
948
+ <div class="flex items-center">
949
+ <div class="h-10 w-10 rounded-full bg-gray-200 flex items-center justify-center">
950
+ <i class="fas fa-user text-gray-500"></i>
951
+ </div>
952
+ <div class="ml-4">
953
+ <div class="text-sm font-medium text-gray-900">${student.name}</div>
954
+ <div class="text-sm text-gray-500">${student.email}</div>
955
+ </div>
956
+ </div>
957
+ <div class="flex items-center">
958
+ <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
959
+ ${student.studentId}
960
+ </span>
961
+ <span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${student.deviceId ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'}">
962
+ ${student.deviceId ? 'Device set' : 'No device'}
963
+ </span>
964
+ </div>
965
+ </div>
966
+ `;
967
+ studentsList.appendChild(li);
968
+ });
969
+ }
970
+ }
971
+
972
+ function renderTeacherReports() {
973
+ // Simplified for demo - in a real app, this would show charts and detailed reports
974
+ document.getElementById('classAttendanceChart').innerHTML = `
975
+ <div class="flex items-center justify-center h-full">
976
+ <div class="text-center">
977
+ <i class="fas fa-chart-bar text-4xl text-gray-300 mb-2"></i>
978
+ <p class="text-gray-500">Attendance charts would display here</p>
979
+ </div>
980
+ </div>
981
+ `;
982
+
983
+ document.getElementById('recentAttendanceTable').innerHTML = `
984
+ <table class="min-w-full divide-y divide-gray-200">
985
+ <thead class="bg-gray-50">
986
+ <tr>
987
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
988
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Class</th>
989
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Attendance</th>
990
+ </tr>
991
+ </thead>
992
+ <tbody class="bg-white divide-y divide-gray-200">
993
+ <tr>
994
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${new Date().toLocaleDateString()}</td>
995
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">CS101</td>
996
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">15/20</td>
997
+ </tr>
998
+ <tr>
999
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${new Date(Date.now() - 86400000).toLocaleDateString()}</td>
1000
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">CS101</td>
1001
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">18/20</td>
1002
+ </tr>
1003
+ </tbody>
1004
+ </table>
1005
+ `;
1006
+ }
1007
+
1008
+ function renderAvailableSessions() {
1009
+ const availableSessionsList = db.sessions.filter(s =>
1010
+ s.status === 'active' &&
1011
+ s.class === currentUser.class &&
1012
+ !s.attendees.includes(currentUser.id)
1013
+ );
1014
+
1015
+ availableSessions.innerHTML = '';
1016
+
1017
+ if (availableSessionsList.length === 0) {
1018
+ availableSessions.innerHTML = `
1019
+ <div class="px-4 py-5 sm:p-6 text-center">
1020
+ <i class="fas fa-calendar-check text-4xl text-gray-300 mb-3"></i>
1021
+ <h3 class="text-lg font-medium text-gray-900">No available sessions</h3>
1022
+ <p class="mt-1 text-sm text-gray-500">There are currently no active attendance sessions for your class.</p>
1023
+ </div>
1024
+ `;
1025
+ } else {
1026
+ availableSessionsList.forEach(session => {
1027
+ const endTime = new Date(session.endTime);
1028
+ const timeLeft = Math.max(0, Math.floor((endTime - new Date()) / 60000));
1029
+
1030
+ const div = document.createElement('div');
1031
+ div.className = 'px-4 py-5 sm:p-6 attendance-card transition duration-150 ease-in-out';
1032
+ div.innerHTML = `
1033
+ <div class="flex items-center justify-between">
1034
+ <div>
1035
+ <h3 class="text-lg leading-6 font-medium text-gray-900">${session.name}</h3>
1036
+ <p class="mt-1 text-sm text-gray-500">${session.class} • Ends in ${timeLeft} minutes</p>
1037
+ </div>
1038
+ <div>
1039
+ <button class="mark-attendance-btn inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" data-session-id="${session.id}">
1040
+ <i class="fas fa-check-circle mr-2"></i> Mark Attendance
1041
+ </button>
1042
+ </div>
1043
+ </div>
1044
+ `;
1045
+ availableSessions.appendChild(div);
1046
+ });
1047
+
1048
+ setupAttendanceButtons();
1049
+ }
1050
+ }
1051
+
1052
+ function renderAttendanceHistory() {
1053
+ const studentAttendance = db.attendance
1054
+ .filter(a => a.studentId === currentUser.id)
1055
+ .sort((a, b) => b.timestamp - a.timestamp)
1056
+ .slice(0, 10);
1057
+
1058
+ attendanceHistory.innerHTML = '';
1059
+
1060
+ if (studentAttendance.length === 0) {
1061
+ attendanceHistory.innerHTML = `
1062
+ <div class="px-4 py-5 sm:p-6 text-center">
1063
+ <i class="fas fa-history text-4xl text-gray-300 mb-3"></i>
1064
+ <h3 class="text-lg font-medium text-gray-900">No attendance history</h3>
1065
+ <p class="mt-1 text-sm text-gray-500">You haven't marked any attendance sessions yet.</p>
1066
+ </div>
1067
+ `;
1068
+ } else {
1069
+ studentAttendance.forEach(record => {
1070
+ const session = db.sessions.find(s => s.id === record.sessionId);
1071
+
1072
+ const div = document.createElement('div');
1073
+ div.className = 'px-4 py-5 sm:p-6';
1074
+ div.innerHTML = `
1075
+ <div class="flex items-center justify-between">
1076
+ <div>
1077
+ <h3 class="text-lg leading-6 font-medium text-gray-900">${session.name}</h3>
1078
+ <p class="mt-1 text-sm text-gray-500">${session.class} • ${record.timestamp.toLocaleDateString()} at ${record.timestamp.toLocaleTimeString()}</p>
1079
+ </div>
1080
+ <div>
1081
+ <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
1082
+ <i class="fas fa-check mr-1"></i> Present
1083
+ </span>
1084
+ </div>
1085
+ </div>
1086
+ `;
1087
+ attendanceHistory.appendChild(div);
1088
+ });
1089
+ }
1090
+ }
1091
+
1092
+ function renderStudentStats() {
1093
+ // Calculate stats
1094
+ const totalSessions = db.sessions.filter(s => s.class === currentUser.class && s.status === 'closed').length;
1095
+ const attendedSessions = db.attendance
1096
+ .filter(a => a.studentId === currentUser.id)
1097
+ .map(a => a.sessionId)
1098
+ .filter((v, i, a) => a.indexOf(v) === i).length;
1099
+
1100
+ const attendancePercentage = totalSessions > 0 ? Math.round((attendedSessions / totalSessions) * 100) : 0;
1101
+
1102
+ // Update UI
1103
+ attendanceRate.textContent = `${attendancePercentage}%`;
1104
+ attendanceProgress.style.width = `${attendancePercentage}%`;
1105
+ presentCount.textContent = attendedSessions;
1106
+ absentCount.textContent = totalSessions - attendedSessions;
1107
+
1108
+ // Class stats
1109
+ const classes = [...new Set(db.sessions.map(s => s.class))];
1110
+ classAttendanceStats.innerHTML = '';
1111
+
1112
+ classes.forEach(classId => {
1113
+ const classSessions = db.sessions.filter(s => s.class === classId && s.status === 'closed').length;
1114
+ const classAttended = db.attendance
1115
+ .filter(a => a.studentId === currentUser.id && db.sessions.find(s => s.id === a.sessionId && s.class === classId))
1116
+ .map(a => a.sessionId)
1117
+ .filter((v, i, a) => a.indexOf(v) === i).length;
1118
+
1119
+ const classPercentage = classSessions > 0 ? Math.round((classAttended / classSessions) * 100) : 0;
1120
+
1121
+ const div = document.createElement('div');
1122
+ div.className = 'flex items-center justify-between';
1123
+ div.innerHTML = `
1124
+ <div>
1125
+ <h4 class="text-sm font-medium text-gray-900">${classId}</h4>
1126
+ <p class="text-xs text-gray-500">${classAttended}/${classSessions} sessions</p>
1127
+ </div>
1128
+ <div class="w-1/2">
1129
+ <div class="progress-bar">
1130
+ <div class="progress-fill" style="width: ${classPercentage}%"></div>
1131
+ </div>
1132
+ <p class="text-xs text-right mt-1 text-gray-500">${classPercentage}%</p>
1133
+ </div>
1134
+ `;
1135
+ classAttendanceStats.appendChild(div);
1136
+ });
1137
+ }
1138
+
1139
+ // Initialize
1140
+ document.addEventListener('DOMContentLoaded', function() {
1141
+ // For demo purposes, pre-fill login form
1142
+ document.getElementById('email').value = 'teacher@school.edu';
1143
+ document.getElementById('password').value = 'teacher123';
1144
+ });
1145
+ </script>
1146
+ <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=Jacksonnavigator7/attendancy-system" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1147
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ Create for me "Mobile Attendance System that allows educational institutions to track student attendance digitally. Here's what it does: Core Functionality For Teachers: Manage Attendance Sessions - Open/close attendance sessions for their classes Add Students - Register new students to their class with email and password View Session History - See all past attendance sessions with their status Monitor Class Data - Track which sessions are active or closed For Students: Mark Attendance - Check in when an attendance session is open View Attendance History - See their past 10 attendance records Track Statistics - View total sessions attended and attendance percentage Device Security - Students are locked to one device to prevent proxy attendance Key Features Role-based Access - Different interfaces for teachers vs students Device Binding - Students can only use one device to prevent cheating Session Management - Teachers control when attendance is available Data Persistence - SQLite database stores all users, sessions, and attendance logs Modern UI - Clean, responsive interface with tabs and professional styling How It Works Users log in with email/password Teachers can open attendance sessions and manage students Students can mark attendance only when sessions are open and haven't already checked in System tracks everything in a database for reporting and analytics It's essentially a digital replacement for traditional paper attendance sheets with added security and automation features."