|
|
let timer; |
|
|
let timeLeft = 1500; |
|
|
let running = false; |
|
|
let sessionId; |
|
|
let currentSessionType = 'work'; |
|
|
let workDuration = 1500; |
|
|
let restDuration = 300; |
|
|
let streak = 0; |
|
|
let tasks = []; |
|
|
|
|
|
document.addEventListener("DOMContentLoaded", function() { |
|
|
fetchScripts(); |
|
|
fetchTasks(); |
|
|
updateStreak(); |
|
|
setupSwipeGestures(); |
|
|
document.getElementById('work-duration').value = workDuration / 60; |
|
|
document.getElementById('rest-duration').value = restDuration / 60; |
|
|
|
|
|
if ('serviceWorker' in navigator) { |
|
|
navigator.serviceWorker.register('/service-worker.js').then(function(registration) { |
|
|
console.log('ServiceWorker registration successful with scope: ', registration.scope); |
|
|
}, function(err) { |
|
|
console.log('ServiceWorker registration failed: ', err); |
|
|
}); |
|
|
} |
|
|
}); |
|
|
|
|
|
function setupSwipeGestures() { |
|
|
const timerElement = document.getElementById('timer-container'); |
|
|
const hammer = new Hammer(timerElement); |
|
|
|
|
|
hammer.on('swipeleft', function() { |
|
|
switchSessionType(); |
|
|
}); |
|
|
|
|
|
hammer.on('swiperight', function() { |
|
|
resetTimer(); |
|
|
}); |
|
|
} |
|
|
|
|
|
function startTimer() { |
|
|
if (!running) { |
|
|
running = true; |
|
|
timer = setInterval(countdown, 1000); |
|
|
fetch('/start_session', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ |
|
|
session_type: currentSessionType, |
|
|
duration: currentSessionType === 'work' ? workDuration : restDuration |
|
|
}) |
|
|
}) |
|
|
.then(response => response.json()) |
|
|
.then(data => { |
|
|
sessionId = data.session_id; |
|
|
console.log("Session started with ID:", sessionId); |
|
|
}) |
|
|
.catch(error => console.error('Error starting session:', error)); |
|
|
} |
|
|
} |
|
|
|
|
|
function pauseTimer() { |
|
|
if (running) { |
|
|
running = false; |
|
|
clearInterval(timer); |
|
|
} |
|
|
} |
|
|
|
|
|
function resetTimer() { |
|
|
running = false; |
|
|
clearInterval(timer); |
|
|
timeLeft = currentSessionType === 'work' ? workDuration : restDuration; |
|
|
updateTimerDisplay(); |
|
|
} |
|
|
|
|
|
function countdown() { |
|
|
if (timeLeft > 0) { |
|
|
timeLeft--; |
|
|
updateTimerDisplay(); |
|
|
} else { |
|
|
running = false; |
|
|
clearInterval(timer); |
|
|
endSession(); |
|
|
playNotificationSound(); |
|
|
switchSessionType(); |
|
|
} |
|
|
} |
|
|
|
|
|
function updateTimerDisplay() { |
|
|
const minutes = Math.floor(timeLeft / 60); |
|
|
const seconds = timeLeft % 60; |
|
|
document.getElementById('timer').innerText = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; |
|
|
} |
|
|
|
|
|
function switchSessionType() { |
|
|
currentSessionType = currentSessionType === 'work' ? 'rest' : 'work'; |
|
|
timeLeft = currentSessionType === 'work' ? workDuration : restDuration; |
|
|
document.getElementById('session-type').innerText = currentSessionType.charAt(0).toUpperCase() + currentSessionType.slice(1); |
|
|
updateTimerDisplay(); |
|
|
if (currentSessionType === 'work') { |
|
|
streak++; |
|
|
updateStreak(); |
|
|
} |
|
|
} |
|
|
|
|
|
function endSession() { |
|
|
fetch('/end_session', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ session_id: sessionId }) |
|
|
}) |
|
|
.then(() => { |
|
|
console.log("Session ended successfully"); |
|
|
fetchScripts(); |
|
|
}) |
|
|
.catch(error => console.error('Error ending session:', error)); |
|
|
} |
|
|
|
|
|
function saveScript() { |
|
|
const scriptCode = document.getElementById('script').value; |
|
|
fetch('/save_script', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ session_id: sessionId, script_code: scriptCode }) |
|
|
}) |
|
|
.then(() => { |
|
|
console.log("Script saved successfully"); |
|
|
fetchScripts(); |
|
|
}) |
|
|
.catch(error => console.error('Error saving script:', error)); |
|
|
} |
|
|
|
|
|
function fetchScripts() { |
|
|
fetch('/scripts') |
|
|
.then(response => response.json()) |
|
|
.then(scripts => { |
|
|
const scriptsDiv = document.getElementById('scripts'); |
|
|
scriptsDiv.innerHTML = '<h2>Saved Sessions</h2>'; |
|
|
scripts.forEach(script => { |
|
|
const scriptDiv = createScriptElement(script); |
|
|
scriptsDiv.appendChild(scriptDiv); |
|
|
}); |
|
|
updateStatistics(scripts); |
|
|
}) |
|
|
.catch(error => console.error('Error fetching scripts:', error)); |
|
|
} |
|
|
|
|
|
function createScriptElement(script) { |
|
|
const scriptDiv = document.createElement('div'); |
|
|
scriptDiv.classList.add('script'); |
|
|
const rating = script[4] || 0; |
|
|
const backgroundColor = `rgb(${Math.min(255, rating * 25)}, 0, 0)`; |
|
|
scriptDiv.style.backgroundColor = backgroundColor; |
|
|
|
|
|
scriptDiv.innerHTML = ` |
|
|
<p><strong>Session ID:</strong> ${script[0]}</p> |
|
|
<p><strong>Type:</strong> ${script[6]}</p> |
|
|
<p><strong>Start Time:</strong> ${script[1]}</p> |
|
|
<p><strong>Script:</strong> <pre>${script[3] || 'No Script Saved'}</pre></p> |
|
|
<p><strong>Rating:</strong> <span class="tomato-rating">${'🍅'.repeat(rating)}</span></p> |
|
|
<p><strong>Comments:</strong> ${script[5] || 'No Comments'}</p> |
|
|
<input type="number" min="0" max="10" placeholder="Rate 0-10" value="${rating}" onchange="rateScript(${script[0]}, this.value)"> |
|
|
<textarea placeholder="Add a comment" onchange="commentScript(${script[0]}, this.value)">${script[5] || ''}</textarea> |
|
|
`; |
|
|
|
|
|
return scriptDiv; |
|
|
} |
|
|
|
|
|
function rateScript(sessionId, rating) { |
|
|
fetch('/rate_script', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ session_id: sessionId, rating: parseInt(rating) }) |
|
|
}) |
|
|
.then(() => { |
|
|
console.log("Script rated successfully"); |
|
|
fetchScripts(); |
|
|
}) |
|
|
.catch(error => console.error('Error rating script:', error)); |
|
|
} |
|
|
|
|
|
function commentScript(sessionId, comments) { |
|
|
fetch('/comment_script', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ session_id: sessionId, comments: comments }) |
|
|
}) |
|
|
.then(() => { |
|
|
console.log("Comment added successfully"); |
|
|
fetchScripts(); |
|
|
}) |
|
|
.catch(error => console.error('Error adding comment:', error)); |
|
|
} |
|
|
|
|
|
function generateOtp() { |
|
|
fetch('/generate_otp', { |
|
|
method: 'GET' |
|
|
}) |
|
|
.then(() => console.log("OTP generated successfully")) |
|
|
.catch(error => console.error('Error generating OTP:', error)); |
|
|
} |
|
|
|
|
|
function resetDatabase() { |
|
|
const otp = document.getElementById('otp').value; |
|
|
fetch('/reset_database', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ otp: otp }) |
|
|
}) |
|
|
.then(response => { |
|
|
if (response.status === 204) { |
|
|
console.log('Database reset successfully'); |
|
|
alert('Database reset successfully'); |
|
|
fetchScripts(); |
|
|
} else { |
|
|
response.json().then(data => { |
|
|
console.error('Error resetting database:', data.error); |
|
|
alert(data.error); |
|
|
}); |
|
|
} |
|
|
}) |
|
|
.catch(error => console.error('Error resetting database:', error)); |
|
|
} |
|
|
|
|
|
function playNotificationSound() { |
|
|
const audio = new Audio('/static/sounds/notification.mp3'); |
|
|
audio.play(); |
|
|
} |
|
|
|
|
|
function updateStreak() { |
|
|
document.getElementById('streak').innerText = streak; |
|
|
} |
|
|
|
|
|
function updateStatistics(scripts) { |
|
|
const totalSessions = scripts.length; |
|
|
const totalWorkTime = scripts.reduce((acc, script) => acc + (script[6] === 'work' ? script[7] : 0), 0); |
|
|
const averageRating = scripts.reduce((acc, script) => acc + (script[4] || 0), 0) / totalSessions || 0; |
|
|
|
|
|
document.getElementById('total-sessions').innerText = totalSessions; |
|
|
document.getElementById('total-work-time').innerText = formatTime(totalWorkTime); |
|
|
document.getElementById('average-rating').innerText = averageRating.toFixed(2); |
|
|
} |
|
|
|
|
|
function formatTime(seconds) { |
|
|
const hours = Math.floor(seconds / 3600); |
|
|
const minutes = Math.floor((seconds % 3600) / 60); |
|
|
return `${hours}h ${minutes}m`; |
|
|
} |
|
|
|
|
|
function updateDurations() { |
|
|
workDuration = parseInt(document.getElementById('work-duration').value) * 60; |
|
|
restDuration = parseInt(document.getElementById('rest-duration').value) * 60; |
|
|
resetTimer(); |
|
|
} |
|
|
|
|
|
function addTask() { |
|
|
const taskInput = document.getElementById('task-input'); |
|
|
const taskDescription = taskInput.value.trim(); |
|
|
if (taskDescription) { |
|
|
fetch('/add_task', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ description: taskDescription }) |
|
|
}) |
|
|
.then(response => response.json()) |
|
|
.then(data => { |
|
|
console.log("Task added successfully"); |
|
|
taskInput.value = ''; |
|
|
fetchTasks(); |
|
|
}) |
|
|
.catch(error => console.error('Error adding task:', error)); |
|
|
} |
|
|
} |
|
|
|
|
|
function fetchTasks() { |
|
|
fetch('/get_tasks') |
|
|
.then(response => response.json()) |
|
|
.then(tasks => { |
|
|
const taskList = document.getElementById('task-list'); |
|
|
taskList.innerHTML = ''; |
|
|
tasks.forEach(task => { |
|
|
const taskElement = createTaskElement(task); |
|
|
taskList.appendChild(taskElement); |
|
|
}); |
|
|
}) |
|
|
.catch(error => console.error('Error fetching tasks:', error)); |
|
|
} |
|
|
|
|
|
function createTaskElement(task) { |
|
|
const taskElement = document.createElement('li'); |
|
|
taskElement.innerHTML = ` |
|
|
<input type="checkbox" ${task.completed ? 'checked' : ''} onchange="updateTask(${task.id}, this.checked)"> |
|
|
<span>${task.description}</span> |
|
|
`; |
|
|
return taskElement; |
|
|
} |
|
|
|
|
|
function updateTask(taskId, completed) { |
|
|
fetch('/update_task', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ task_id: taskId, completed: completed }) |
|
|
}) |
|
|
.then(() => { |
|
|
console.log("Task updated successfully"); |
|
|
fetchTasks(); |
|
|
}) |
|
|
.catch(error => console.error('Error updating task:', error)); |
|
|
} |
|
|
|
|
|
function exportData() { |
|
|
fetch('/scripts') |
|
|
.then(response => response.json()) |
|
|
.then(scripts => { |
|
|
const csvContent = "data:text/csv;charset=utf-8," |
|
|
+ "Session ID,Type,Start Time,End Time,Script,Rating,Comments,Duration\n" |
|
|
+ scripts.map(s => `${s[0]},"${s[6]}","${s[1]}","${s[2] || ''}","${s[3] || ''}",${s[4] || ''},${s[5] || ''},${s[7]}`).join("\n"); |
|
|
const encodedUri = encodeURI(csvContent); |
|
|
const link = document.createElement("a"); |
|
|
link.setAttribute("href", encodedUri); |
|
|
link.setAttribute("download", "pomodoro_data.csv"); |
|
|
document.body.appendChild(link); |
|
|
link.click(); |
|
|
}) |
|
|
.catch(error => console.error('Error exporting data:', error)); |
|
|
} |
|
|
|
|
|
function login() { |
|
|
const username = document.getElementById('username').value; |
|
|
const password = document.getElementById('password').value; |
|
|
fetch('/login', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ username, password }) |
|
|
}) |
|
|
.then(response => response.json()) |
|
|
.then(data => { |
|
|
if (data.message === 'Login successful') { |
|
|
document.getElementById('login-form').style.display = 'none'; |
|
|
document.getElementById('main-content').style.display = 'block'; |
|
|
if (data.is_admin) { |
|
|
document.getElementById('admin-panel').style.display = 'block'; |
|
|
} |
|
|
} else { |
|
|
alert(data.error); |
|
|
} |
|
|
}) |
|
|
.catch(error => console.error('Error logging in:', error)); |
|
|
} |
|
|
|
|
|
function register() { |
|
|
const username = document.getElementById('reg-username').value; |
|
|
const password = document.getElementById('reg-password').value; |
|
|
fetch('/register', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ username, password }) |
|
|
}) |
|
|
.then(response => response.json()) |
|
|
.then(data => { |
|
|
if (data.message === 'User registered successfully') { |
|
|
alert('Registration successful. Please log in.'); |
|
|
showLoginForm(); |
|
|
} else { |
|
|
alert(data.error); |
|
|
} |
|
|
}) |
|
|
.catch(error => console.error('Error registering:', error)); |
|
|
} |
|
|
|
|
|
function logout() { |
|
|
fetch('/logout', { |
|
|
method: 'POST' |
|
|
}) |
|
|
.then(() => { |
|
|
document.getElementById('login-form').style.display = 'block'; |
|
|
document.getElementById('main-content').style.display = 'none'; |
|
|
document.getElementById('admin-panel').style.display = 'none'; |
|
|
}) |
|
|
.catch(error => console.error('Error logging out:', error)); |
|
|
} |
|
|
|
|
|
function showRegisterForm() { |
|
|
document.getElementById('login-form').style.display = 'none'; |
|
|
document.getElementById('register-form').style.display = 'block'; |
|
|
} |
|
|
|
|
|
function showLoginForm() { |
|
|
document.getElementById('register-form').style.display = 'none'; |
|
|
document.getElementById('login-form').style.display = 'block'; |
|
|
} |
|
|
|
|
|
function updateSettings() { |
|
|
const settings = { |
|
|
sound_enabled: document.getElementById('sound-enabled').checked, |
|
|
dark_mode: document.getElementById('dark-mode').checked, |
|
|
notification_enabled: document.getElementById('notification-enabled').checked, |
|
|
work_duration: parseInt(document.getElementById('work-duration').value), |
|
|
rest_duration: parseInt(document.getElementById('rest-duration').value) |
|
|
}; |
|
|
|
|
|
fetch('/update_settings', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify(settings) |
|
|
}) |
|
|
.then(() => { |
|
|
console.log("Settings updated successfully"); |
|
|
applySettings(settings); |
|
|
}) |
|
|
.catch(error => console.error('Error updating settings:', error)); |
|
|
} |
|
|
|
|
|
function applySettings(settings) { |
|
|
if (settings.dark_mode) { |
|
|
document.body.classList.add('dark-mode'); |
|
|
} else { |
|
|
document.body.classList.remove('dark-mode'); |
|
|
} |
|
|
workDuration = settings.work_duration * 60; |
|
|
restDuration = settings.rest_duration * 60; |
|
|
resetTimer(); |
|
|
} |
|
|
|
|
|
function saveAdminSettings() { |
|
|
const settings = { |
|
|
sound_enabled: document.getElementById('enable-sound').checked, |
|
|
notifications_enabled: document.getElementById('enable-notifications').checked, |
|
|
dark_mode_enabled: document.getElementById('enable-dark-mode').checked, |
|
|
task_manager_enabled: document.getElementById('enable-task-manager').checked, |
|
|
statistics_enabled: document.getElementById('enable-statistics').checked |
|
|
}; |
|
|
|
|
|
fetch('/update_admin_settings', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify(settings) |
|
|
}) |
|
|
.then(response => response.json()) |
|
|
.then(data => { |
|
|
if (data.success) { |
|
|
alert('Admin settings saved successfully'); |
|
|
applyAdminSettings(settings); |
|
|
} else { |
|
|
alert('Failed to save admin settings'); |
|
|
} |
|
|
}) |
|
|
.catch(error => console.error('Error saving admin settings:', error)); |
|
|
} |
|
|
|
|
|
function applyAdminSettings(settings) { |
|
|
document.getElementById('sound-enabled').disabled = !settings.sound_enabled; |
|
|
document.getElementById('notification-enabled').disabled = !settings.notifications_enabled; |
|
|
document.getElementById('dark-mode').disabled = !settings.dark_mode_enabled; |
|
|
document.getElementById('task-manager').style.display = settings.task_manager_enabled ? 'block' : 'none'; |
|
|
document.getElementById('statistics').style.display = settings.statistics_enabled ? 'block' : 'none'; |
|
|
} |
|
|
|
|
|
function fetchAdminSettings() { |
|
|
fetch('/get_admin_settings') |
|
|
.then(response => response.json()) |
|
|
.then(settings => { |
|
|
document.getElementById('enable-sound').checked = settings.sound_enabled; |
|
|
document.getElementById('enable-notifications').checked = settings.notifications_enabled; |
|
|
document.getElementById('enable-dark-mode').checked = settings.dark_mode_enabled; |
|
|
document.getElementById('enable-task-manager').checked = settings.task_manager_enabled; |
|
|
document.getElementById('enable-statistics').checked = settings.statistics_enabled; |
|
|
applyAdminSettings(settings); |
|
|
}) |
|
|
.catch(error => console.error('Error fetching admin settings:', error)); |
|
|
} |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
if (document.getElementById('admin-panel').style.display !== 'none') { |
|
|
fetchAdminSettings(); |
|
|
} |
|
|
}); |