Oranblock commited on
Commit
81afa9f
·
verified ·
1 Parent(s): 158d2fd

Create static/js/script.js

Browse files
Files changed (1) hide show
  1. static/js/script.js +502 -0
static/js/script.js ADDED
@@ -0,0 +1,502 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let timer;
2
+ let timeLeft = 1500; // 25 minutes in seconds (default work session)
3
+ let running = false;
4
+ let sessionId;
5
+ let currentSessionType = 'work';
6
+ let workDuration = 1500; // 25 minutes
7
+ let restDuration = 300; // 5 minutes
8
+ let streak = 0;
9
+ let tasks = [];
10
+
11
+ document.addEventListener("DOMContentLoaded", function() {
12
+ fetchScripts();
13
+ fetchTasks();
14
+ updateStreak();
15
+ setupSwipeGestures();
16
+ document.getElementById('work-duration').value = workDuration / 60;
17
+ document.getElementById('rest-duration').value = restDuration / 60;
18
+
19
+ if ('serviceWorker' in navigator) {
20
+ navigator.serviceWorker.register('/service-worker.js').then(function(registration) {
21
+ console.log('ServiceWorker registration successful with scope: ', registration.scope);
22
+ }, function(err) {
23
+ console.log('ServiceWorker registration failed: ', err);
24
+ });
25
+ }
26
+ });
27
+
28
+ function setupSwipeGestures() {
29
+ const timerElement = document.getElementById('timer-container');
30
+ const hammer = new Hammer(timerElement);
31
+
32
+ hammer.on('swipeleft', function() {
33
+ switchSessionType();
34
+ });
35
+
36
+ hammer.on('swiperight', function() {
37
+ resetTimer();
38
+ });
39
+ }
40
+
41
+ function startTimer() {
42
+ if (!running) {
43
+ running = true;
44
+ timer = setInterval(countdown, 1000);
45
+ fetch('/start_session', {
46
+ method: 'POST',
47
+ headers: {
48
+ 'Content-Type': 'application/json'
49
+ },
50
+ body: JSON.stringify({
51
+ session_type: currentSessionType,
52
+ duration: currentSessionType === 'work' ? workDuration : restDuration
53
+ })
54
+ })
55
+ .then(response => response.json())
56
+ .then(data => {
57
+ sessionId = data.session_id;
58
+ console.log("Session started with ID:", sessionId);
59
+ })
60
+ .catch(error => console.error('Error starting session:', error));
61
+ }
62
+ }
63
+
64
+ function pauseTimer() {
65
+ if (running) {
66
+ running = false;
67
+ clearInterval(timer);
68
+ }
69
+ }
70
+
71
+ function resetTimer() {
72
+ running = false;
73
+ clearInterval(timer);
74
+ timeLeft = currentSessionType === 'work' ? workDuration : restDuration;
75
+ updateTimerDisplay();
76
+ }
77
+
78
+ function countdown() {
79
+ if (timeLeft > 0) {
80
+ timeLeft--;
81
+ updateTimerDisplay();
82
+ } else {
83
+ running = false;
84
+ clearInterval(timer);
85
+ endSession();
86
+ playNotificationSound();
87
+ switchSessionType();
88
+ }
89
+ }
90
+
91
+ function updateTimerDisplay() {
92
+ const minutes = Math.floor(timeLeft / 60);
93
+ const seconds = timeLeft % 60;
94
+ document.getElementById('timer').innerText = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
95
+ }
96
+
97
+ function switchSessionType() {
98
+ currentSessionType = currentSessionType === 'work' ? 'rest' : 'work';
99
+ timeLeft = currentSessionType === 'work' ? workDuration : restDuration;
100
+ document.getElementById('session-type').innerText = currentSessionType.charAt(0).toUpperCase() + currentSessionType.slice(1);
101
+ updateTimerDisplay();
102
+ if (currentSessionType === 'work') {
103
+ streak++;
104
+ updateStreak();
105
+ }
106
+ }
107
+
108
+ function endSession() {
109
+ fetch('/end_session', {
110
+ method: 'POST',
111
+ headers: {
112
+ 'Content-Type': 'application/json'
113
+ },
114
+ body: JSON.stringify({ session_id: sessionId })
115
+ })
116
+ .then(() => {
117
+ console.log("Session ended successfully");
118
+ fetchScripts();
119
+ })
120
+ .catch(error => console.error('Error ending session:', error));
121
+ }
122
+
123
+ function saveScript() {
124
+ const scriptCode = document.getElementById('script').value;
125
+ fetch('/save_script', {
126
+ method: 'POST',
127
+ headers: {
128
+ 'Content-Type': 'application/json'
129
+ },
130
+ body: JSON.stringify({ session_id: sessionId, script_code: scriptCode })
131
+ })
132
+ .then(() => {
133
+ console.log("Script saved successfully");
134
+ fetchScripts();
135
+ })
136
+ .catch(error => console.error('Error saving script:', error));
137
+ }
138
+
139
+ function fetchScripts() {
140
+ fetch('/scripts')
141
+ .then(response => response.json())
142
+ .then(scripts => {
143
+ const scriptsDiv = document.getElementById('scripts');
144
+ scriptsDiv.innerHTML = '<h2>Saved Sessions</h2>';
145
+ scripts.forEach(script => {
146
+ const scriptDiv = createScriptElement(script);
147
+ scriptsDiv.appendChild(scriptDiv);
148
+ });
149
+ updateStatistics(scripts);
150
+ })
151
+ .catch(error => console.error('Error fetching scripts:', error));
152
+ }
153
+
154
+ function createScriptElement(script) {
155
+ const scriptDiv = document.createElement('div');
156
+ scriptDiv.classList.add('script');
157
+ const rating = script[4] || 0;
158
+ const backgroundColor = `rgb(${Math.min(255, rating * 25)}, 0, 0)`;
159
+ scriptDiv.style.backgroundColor = backgroundColor;
160
+
161
+ scriptDiv.innerHTML = `
162
+ <p><strong>Session ID:</strong> ${script[0]}</p>
163
+ <p><strong>Type:</strong> ${script[6]}</p>
164
+ <p><strong>Start Time:</strong> ${script[1]}</p>
165
+ <p><strong>Script:</strong> <pre>${script[3] || 'No Script Saved'}</pre></p>
166
+ <p><strong>Rating:</strong> <span class="tomato-rating">${'🍅'.repeat(rating)}</span></p>
167
+ <p><strong>Comments:</strong> ${script[5] || 'No Comments'}</p>
168
+ <input type="number" min="0" max="10" placeholder="Rate 0-10" value="${rating}" onchange="rateScript(${script[0]}, this.value)">
169
+ <textarea placeholder="Add a comment" onchange="commentScript(${script[0]}, this.value)">${script[5] || ''}</textarea>
170
+ `;
171
+
172
+ return scriptDiv;
173
+ }
174
+
175
+ function rateScript(sessionId, rating) {
176
+ fetch('/rate_script', {
177
+ method: 'POST',
178
+ headers: {
179
+ 'Content-Type': 'application/json'
180
+ },
181
+ body: JSON.stringify({ session_id: sessionId, rating: parseInt(rating) })
182
+ })
183
+ .then(() => {
184
+ console.log("Script rated successfully");
185
+ fetchScripts();
186
+ })
187
+ .catch(error => console.error('Error rating script:', error));
188
+ }
189
+
190
+ function commentScript(sessionId, comments) {
191
+ fetch('/comment_script', {
192
+ method: 'POST',
193
+ headers: {
194
+ 'Content-Type': 'application/json'
195
+ },
196
+ body: JSON.stringify({ session_id: sessionId, comments: comments })
197
+ })
198
+ .then(() => {
199
+ console.log("Comment added successfully");
200
+ fetchScripts();
201
+ })
202
+ .catch(error => console.error('Error adding comment:', error));
203
+ }
204
+
205
+ function generateOtp() {
206
+ fetch('/generate_otp', {
207
+ method: 'GET'
208
+ })
209
+ .then(() => console.log("OTP generated successfully"))
210
+ .catch(error => console.error('Error generating OTP:', error));
211
+ }
212
+
213
+ function resetDatabase() {
214
+ const otp = document.getElementById('otp').value;
215
+ fetch('/reset_database', {
216
+ method: 'POST',
217
+ headers: {
218
+ 'Content-Type': 'application/json'
219
+ },
220
+ body: JSON.stringify({ otp: otp })
221
+ })
222
+ .then(response => {
223
+ if (response.status === 204) {
224
+ console.log('Database reset successfully');
225
+ alert('Database reset successfully');
226
+ fetchScripts();
227
+ } else {
228
+ response.json().then(data => {
229
+ console.error('Error resetting database:', data.error);
230
+ alert(data.error);
231
+ });
232
+ }
233
+ })
234
+ .catch(error => console.error('Error resetting database:', error));
235
+ }
236
+
237
+ function playNotificationSound() {
238
+ const audio = new Audio('/static/sounds/notification.mp3');
239
+ audio.play();
240
+ }
241
+
242
+ function updateStreak() {
243
+ document.getElementById('streak').innerText = streak;
244
+ }
245
+
246
+ function updateStatistics(scripts) {
247
+ const totalSessions = scripts.length;
248
+ const totalWorkTime = scripts.reduce((acc, script) => acc + (script[6] === 'work' ? script[7] : 0), 0);
249
+ const averageRating = scripts.reduce((acc, script) => acc + (script[4] || 0), 0) / totalSessions || 0;
250
+
251
+ document.getElementById('total-sessions').innerText = totalSessions;
252
+ document.getElementById('total-work-time').innerText = formatTime(totalWorkTime);
253
+ document.getElementById('average-rating').innerText = averageRating.toFixed(2);
254
+ }
255
+
256
+ function formatTime(seconds) {
257
+ const hours = Math.floor(seconds / 3600);
258
+ const minutes = Math.floor((seconds % 3600) / 60);
259
+ return `${hours}h ${minutes}m`;
260
+ }
261
+
262
+ function updateDurations() {
263
+ workDuration = parseInt(document.getElementById('work-duration').value) * 60;
264
+ restDuration = parseInt(document.getElementById('rest-duration').value) * 60;
265
+ resetTimer();
266
+ }
267
+
268
+ function addTask() {
269
+ const taskInput = document.getElementById('task-input');
270
+ const taskDescription = taskInput.value.trim();
271
+ if (taskDescription) {
272
+ fetch('/add_task', {
273
+ method: 'POST',
274
+ headers: {
275
+ 'Content-Type': 'application/json'
276
+ },
277
+ body: JSON.stringify({ description: taskDescription })
278
+ })
279
+ .then(response => response.json())
280
+ .then(data => {
281
+ console.log("Task added successfully");
282
+ taskInput.value = '';
283
+ fetchTasks();
284
+ })
285
+ .catch(error => console.error('Error adding task:', error));
286
+ }
287
+ }
288
+
289
+ function fetchTasks() {
290
+ fetch('/get_tasks')
291
+ .then(response => response.json())
292
+ .then(tasks => {
293
+ const taskList = document.getElementById('task-list');
294
+ taskList.innerHTML = '';
295
+ tasks.forEach(task => {
296
+ const taskElement = createTaskElement(task);
297
+ taskList.appendChild(taskElement);
298
+ });
299
+ })
300
+ .catch(error => console.error('Error fetching tasks:', error));
301
+ }
302
+
303
+ function createTaskElement(task) {
304
+ const taskElement = document.createElement('li');
305
+ taskElement.innerHTML = `
306
+ <input type="checkbox" ${task.completed ? 'checked' : ''} onchange="updateTask(${task.id}, this.checked)">
307
+ <span>${task.description}</span>
308
+ `;
309
+ return taskElement;
310
+ }
311
+
312
+ function updateTask(taskId, completed) {
313
+ fetch('/update_task', {
314
+ method: 'POST',
315
+ headers: {
316
+ 'Content-Type': 'application/json'
317
+ },
318
+ body: JSON.stringify({ task_id: taskId, completed: completed })
319
+ })
320
+ .then(() => {
321
+ console.log("Task updated successfully");
322
+ fetchTasks();
323
+ })
324
+ .catch(error => console.error('Error updating task:', error));
325
+ }
326
+
327
+ function exportData() {
328
+ fetch('/scripts')
329
+ .then(response => response.json())
330
+ .then(scripts => {
331
+ const csvContent = "data:text/csv;charset=utf-8,"
332
+ + "Session ID,Type,Start Time,End Time,Script,Rating,Comments,Duration\n"
333
+ + scripts.map(s => `${s[0]},"${s[6]}","${s[1]}","${s[2] || ''}","${s[3] || ''}",${s[4] || ''},${s[5] || ''},${s[7]}`).join("\n");
334
+ const encodedUri = encodeURI(csvContent);
335
+ const link = document.createElement("a");
336
+ link.setAttribute("href", encodedUri);
337
+ link.setAttribute("download", "pomodoro_data.csv");
338
+ document.body.appendChild(link);
339
+ link.click();
340
+ })
341
+ .catch(error => console.error('Error exporting data:', error));
342
+ }
343
+
344
+ function login() {
345
+ const username = document.getElementById('username').value;
346
+ const password = document.getElementById('password').value;
347
+ fetch('/login', {
348
+ method: 'POST',
349
+ headers: {
350
+ 'Content-Type': 'application/json'
351
+ },
352
+ body: JSON.stringify({ username, password })
353
+ })
354
+ .then(response => response.json())
355
+ .then(data => {
356
+ if (data.message === 'Login successful') {
357
+ document.getElementById('login-form').style.display = 'none';
358
+ document.getElementById('main-content').style.display = 'block';
359
+ if (data.is_admin) {
360
+ document.getElementById('admin-panel').style.display = 'block';
361
+ }
362
+ } else {
363
+ alert(data.error);
364
+ }
365
+ })
366
+ .catch(error => console.error('Error logging in:', error));
367
+ }
368
+
369
+ function register() {
370
+ const username = document.getElementById('reg-username').value;
371
+ const password = document.getElementById('reg-password').value;
372
+ fetch('/register', {
373
+ method: 'POST',
374
+ headers: {
375
+ 'Content-Type': 'application/json'
376
+ },
377
+ body: JSON.stringify({ username, password })
378
+ })
379
+ .then(response => response.json())
380
+ .then(data => {
381
+ if (data.message === 'User registered successfully') {
382
+ alert('Registration successful. Please log in.');
383
+ showLoginForm();
384
+ } else {
385
+ alert(data.error);
386
+ }
387
+ })
388
+ .catch(error => console.error('Error registering:', error));
389
+ }
390
+
391
+ function logout() {
392
+ fetch('/logout', {
393
+ method: 'POST'
394
+ })
395
+ .then(() => {
396
+ document.getElementById('login-form').style.display = 'block';
397
+ document.getElementById('main-content').style.display = 'none';
398
+ document.getElementById('admin-panel').style.display = 'none';
399
+ })
400
+ .catch(error => console.error('Error logging out:', error));
401
+ }
402
+
403
+ function showRegisterForm() {
404
+ document.getElementById('login-form').style.display = 'none';
405
+ document.getElementById('register-form').style.display = 'block';
406
+ }
407
+
408
+ function showLoginForm() {
409
+ document.getElementById('register-form').style.display = 'none';
410
+ document.getElementById('login-form').style.display = 'block';
411
+ }
412
+
413
+ function updateSettings() {
414
+ const settings = {
415
+ sound_enabled: document.getElementById('sound-enabled').checked,
416
+ dark_mode: document.getElementById('dark-mode').checked,
417
+ notification_enabled: document.getElementById('notification-enabled').checked,
418
+ work_duration: parseInt(document.getElementById('work-duration').value),
419
+ rest_duration: parseInt(document.getElementById('rest-duration').value)
420
+ };
421
+
422
+ fetch('/update_settings', {
423
+ method: 'POST',
424
+ headers: {
425
+ 'Content-Type': 'application/json'
426
+ },
427
+ body: JSON.stringify(settings)
428
+ })
429
+ .then(() => {
430
+ console.log("Settings updated successfully");
431
+ applySettings(settings);
432
+ })
433
+ .catch(error => console.error('Error updating settings:', error));
434
+ }
435
+
436
+ function applySettings(settings) {
437
+ if (settings.dark_mode) {
438
+ document.body.classList.add('dark-mode');
439
+ } else {
440
+ document.body.classList.remove('dark-mode');
441
+ }
442
+ workDuration = settings.work_duration * 60;
443
+ restDuration = settings.rest_duration * 60;
444
+ resetTimer();
445
+ }
446
+
447
+ function saveAdminSettings() {
448
+ const settings = {
449
+ sound_enabled: document.getElementById('enable-sound').checked,
450
+ notifications_enabled: document.getElementById('enable-notifications').checked,
451
+ dark_mode_enabled: document.getElementById('enable-dark-mode').checked,
452
+ task_manager_enabled: document.getElementById('enable-task-manager').checked,
453
+ statistics_enabled: document.getElementById('enable-statistics').checked
454
+ };
455
+
456
+ fetch('/update_admin_settings', {
457
+ method: 'POST',
458
+ headers: {
459
+ 'Content-Type': 'application/json'
460
+ },
461
+ body: JSON.stringify(settings)
462
+ })
463
+ .then(response => response.json())
464
+ .then(data => {
465
+ if (data.success) {
466
+ alert('Admin settings saved successfully');
467
+ applyAdminSettings(settings);
468
+ } else {
469
+ alert('Failed to save admin settings');
470
+ }
471
+ })
472
+ .catch(error => console.error('Error saving admin settings:', error));
473
+ }
474
+
475
+ function applyAdminSettings(settings) {
476
+ document.getElementById('sound-enabled').disabled = !settings.sound_enabled;
477
+ document.getElementById('notification-enabled').disabled = !settings.notifications_enabled;
478
+ document.getElementById('dark-mode').disabled = !settings.dark_mode_enabled;
479
+ document.getElementById('task-manager').style.display = settings.task_manager_enabled ? 'block' : 'none';
480
+ document.getElementById('statistics').style.display = settings.statistics_enabled ? 'block' : 'none';
481
+ }
482
+
483
+ function fetchAdminSettings() {
484
+ fetch('/get_admin_settings')
485
+ .then(response => response.json())
486
+ .then(settings => {
487
+ document.getElementById('enable-sound').checked = settings.sound_enabled;
488
+ document.getElementById('enable-notifications').checked = settings.notifications_enabled;
489
+ document.getElementById('enable-dark-mode').checked = settings.dark_mode_enabled;
490
+ document.getElementById('enable-task-manager').checked = settings.task_manager_enabled;
491
+ document.getElementById('enable-statistics').checked = settings.statistics_enabled;
492
+ applyAdminSettings(settings);
493
+ })
494
+ .catch(error => console.error('Error fetching admin settings:', error));
495
+ }
496
+
497
+ // Call fetchAdminSettings on page load if the user is an admin
498
+ document.addEventListener('DOMContentLoaded', () => {
499
+ if (document.getElementById('admin-panel').style.display !== 'none') {
500
+ fetchAdminSettings();
501
+ }
502
+ });