Here's the work/rest tracker website with all your requirements:
Here's the updated version with the "Finish Work Day" button:
Key changes made:
finishWorkDay()
function that:
The "Finish Work Day" button will:
Here's the updated version with real-time updates in the Daily Summary section:
Key changes made:
updateDailySummary()
function that:
updateWorkTime()
and updateRestTime()
) to call updateDailySummary()
updateDailySummary()
in startWork()
and pauseWork()
Now the Daily Summary section will update in real-time as you play/pause, showing:
No, the daily summary won't get erased automatically when a new day starts. The data is saved in localStorage and persists between sessions. However, I'll modify the code to properly handle day changes by:
Here's the updated version:
Key changes made:
currentDate
variable to track the current daycheckNewDay()
function that:
Now the tracker will:
Here's the complete code separated into HTML, CSS, and JavaScript files for you to copy to GitHub:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Work/Rest Tracker</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<div class="header">
<img src="https://placekitten.com/100/100" alt="Hello Kitty" class="kitty-img">
<h1>NASR IS ASS</h1>
</div>
<div class="tracker">
<div class="timer-display">
<div class="time" id="work-time">Work: 00:00:00</div>
<div class="time" id="rest-time">Rest: 00:00:00</div>
</div>
<div class="controls">
<button id="play-btn">Play</button>
<button id="pause-btn">Pause</button>
<button id="finish-btn">Finish Work Day</button>
</div>
</div>
<div class="calendar">
<h2>Daily Summary</h2>
<div id="calendar-view">
<p id="today-date"></p>
<p id="total-work">Total Work: 00:00:00</p>
<p id="total-rest">Total Rest: 00:00:00</p>
</div>
</div>
<div class="session-history">
<h2>Session History</h2>
<table id="sessions-table">
<thead>
<tr>
<th>Date</th>
<th>Start Time</th>
<th>End Time</th>
<th>Work Duration</th>
<th>Rest Duration</th>
</tr>
</thead>
<tbody id="session-body">
</tbody>
</table>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Work/Rest Tracker</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<div class="header">
<img src="https://placekitten.com/100/100" alt="Hello Kitty" class="kitty-img">
<h1>NASR IS ASS</h1>
</div>
<div class="tracker">
<div class="timer-display">
<div class="time" id="work-time">Work: 00:00:00</div>
<div class="time" id="rest-time">Rest: 00:00:00</div>
</div>
<div class="controls">
<button id="play-btn">Play</button>
<button id="pause-btn">Pause</button>
<button id="finish-btn">Finish Work Day</button>
</div>
</div>
<div class="calendar">
<h2>Daily Summary</h2>
<div id="calendar-view">
<p id="today-date"></p>
<p id="total-work">Total Work: 00:00:00</p>
<p id="total-rest">Total Rest: 00:00:00</p>
</div>
</div>
<div class="session-history">
<h2>Session History</h2>
<table id="sessions-table">
<thead>
<tr>
<th>Date</th>
<th>Start Time</th>
<th>End Time</th>
<th>Work Duration</th>
<th>Rest Duration</th>
</tr>
</thead>
<tbody id="session-body">
</tbody>
</table>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.header {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.kitty-img {
margin-right: 20px;
border-radius: 50%;
}
.tracker {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background-color: #f0f8ff;
border-radius: 8px;
}
.timer-display {
display: flex;
justify-content: space-around;
margin-bottom: 20px;
}
.time {
font-size: 24px;
font-weight: bold;
}
.controls button {
padding: 10px 20px;
margin: 0 10px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 5px;
}
#play-btn {
background-color: #4CAF50;
color: white;
}
#pause-btn {
background-color: #f44336;
color: white;
}
#finish-btn {
background-color: #2196F3;
color: white;
}
.calendar, .session-history {
margin-bottom: 30px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.header {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.kitty-img {
margin-right: 20px;
border-radius: 50%;
}
.tracker {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background-color: #f0f8ff;
border-radius: 8px;
}
.timer-display {
display: flex;
justify-content: space-around;
margin-bottom: 20px;
}
.time {
font-size: 24px;
font-weight: bold;
}
.controls button {
padding: 10px 20px;
margin: 0 10px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 5px;
}
#play-btn {
background-color: #4CAF50;
color: white;
}
#pause-btn {
background-color: #f44336;
color: white;
}
#finish-btn {
background-color: #2196F3;
color: white;
}
.calendar, .session-history {
margin-bottom: 30px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
let workTime = 0;
let restTime = 0;
let workInterval;
let restInterval;
let isWorking = false;
let currentSession = null;
let sessions = JSON.parse(localStorage.getItem('sessions')) || [];
let currentDate = new Date().toLocaleDateString();
const workTimeDisplay = document.getElementById('work-time');
const restTimeDisplay = document.getElementById('rest-time');
const playBtn = document.getElementById('play-btn');
const pauseBtn = document.getElementById('pause-btn');
const finishBtn = document.getElementById('finish-btn');
const todayDateDisplay = document.getElementById('today-date');
const totalWorkDisplay = document.getElementById('total-work');
const totalRestDisplay = document.getElementById('total-rest');
const sessionBody = document.getElementById('session-body');
function formatTime(seconds) {
const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return `${hrs.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
function checkNewDay() {
const today = new Date().toLocaleDateString();
if (today !== currentDate) {
// New day detected
if (currentSession) {
saveSession();
resetTimers();
}
currentDate = today;
updateDailySummary();
}
}
function updateWorkTime() {
checkNewDay();
workTime++;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
updateDailySummary();
}
function updateRestTime() {
checkNewDay();
restTime++;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
updateDailySummary();
}
function updateDailySummary() {
const today = new Date().toLocaleDateString();
const todaySessions = sessions.filter(session => session.date === today);
let totalWork = workTime;
let totalRest = restTime;
todaySessions.forEach(session => {
totalWork += session.workDuration;
totalRest += session.restDuration;
});
todayDateDisplay.textContent = `Today (${today})`;
totalWorkDisplay.textContent = `Total Work: ${formatTime(totalWork)}`;
totalRestDisplay.textContent = `Total Rest: ${formatTime(totalRest)}`;
}
function startWork() {
checkNewDay();
if (!isWorking) {
isWorking = true;
if (!currentSession) {
currentSession = {
date: new Date().toLocaleDateString(),
startTime: new Date().toLocaleTimeString(),
workDuration: 0,
restDuration: 0,
endTime: null
};
}
workInterval = setInterval(updateWorkTime, 1000);
if (restInterval) clearInterval(restInterval);
updateDailySummary();
}
}
function pauseWork() {
if (isWorking) {
isWorking = false;
clearInterval(workInterval);
restInterval = setInterval(updateRestTime, 1000);
updateDailySummary();
}
}
function finishWorkDay() {
if (currentSession) {
saveSession();
resetTimers();
updateDailySummary();
updateSessionTable();
}
}
function saveSession() {
if (currentSession) {
currentSession.endTime = new Date().toLocaleTimeString();
currentSession.workDuration = workTime;
currentSession.restDuration = restTime;
sessions.push(currentSession);
localStorage.setItem('sessions', JSON.stringify(sessions));
currentSession = null;
}
}
function resetTimers() {
workTime = 0;
restTime = 0;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
clearInterval(workInterval);
clearInterval(restInterval);
isWorking = false;
}
function updateSessionTable() {
sessionBody.innerHTML = sessions.map(session => `
<tr>
<td>${session.date}</td>
<td>${session.startTime}</td>
<td>${session.endTime}</td>
<td>${formatTime(session.workDuration)}</td>
<td>${formatTime(session.restDuration)}</td>
</tr>
`).join('');
}
playBtn.addEventListener('click', startWork);
pauseBtn.addEventListener('click', pauseWork);
finishBtn.addEventListener('click', finishWorkDay);
window.addEventListener('beforeunload', () => {
if (currentSession) {
saveSession();
}
});
// Initialize
updateDailySummary();
updateSessionTable();
// Check for new day periodically
setInterval(checkNewDay, 60000); // Check every minute
let workTime = 0;
let restTime = 0;
let workInterval;
let restInterval;
let isWorking = false;
let currentSession = null;
let sessions = JSON.parse(localStorage.getItem('sessions')) || [];
let currentDate = new Date().toLocaleDateString();
const workTimeDisplay = document.getElementById('work-time');
const restTimeDisplay = document.getElementById('rest-time');
const playBtn = document.getElementById('play-btn');
const pauseBtn = document.getElementById('pause-btn');
const finishBtn = document.getElementById('finish-btn');
const todayDateDisplay = document.getElementById('today-date');
const totalWorkDisplay = document.getElementById('total-work');
const totalRestDisplay = document.getElementById('total-rest');
const sessionBody = document.getElementById('session-body');
function formatTime(seconds) {
const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return `${hrs.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
function checkNewDay() {
const today = new Date().toLocaleDateString();
if (today !== currentDate) {
// New day detected
if (currentSession) {
saveSession();
resetTimers();
}
currentDate = today;
updateDailySummary();
}
}
function updateWorkTime() {
checkNewDay();
workTime++;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
updateDailySummary();
}
function updateRestTime() {
checkNewDay();
restTime++;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
updateDailySummary();
}
function updateDailySummary() {
const today = new Date().toLocaleDateString();
const todaySessions = sessions.filter(session => session.date === today);
let totalWork = workTime;
let totalRest = restTime;
todaySessions.forEach(session => {
totalWork += session.workDuration;
totalRest += session.restDuration;
});
todayDateDisplay.textContent = `Today (${today})`;
totalWorkDisplay.textContent = `Total Work: ${formatTime(totalWork)}`;
totalRestDisplay.textContent = `Total Rest: ${formatTime(totalRest)}`;
}
function startWork() {
checkNewDay();
if (!isWorking) {
isWorking = true;
if (!currentSession) {
currentSession = {
date: new Date().toLocaleDateString(),
startTime: new Date().toLocaleTimeString(),
workDuration: 0,
restDuration: 0,
endTime: null
};
}
workInterval = setInterval(updateWorkTime, 1000);
if (restInterval) clearInterval(restInterval);
updateDailySummary();
}
}
function pauseWork() {
if (isWorking) {
isWorking = false;
clearInterval(workInterval);
restInterval = setInterval(updateRestTime, 1000);
updateDailySummary();
}
}
function finishWorkDay() {
if (currentSession) {
saveSession();
resetTimers();
updateDailySummary();
updateSessionTable();
}
}
function saveSession() {
if (currentSession) {
currentSession.endTime = new Date().toLocaleTimeString();
currentSession.workDuration = workTime;
currentSession.restDuration = restTime;
sessions.push(currentSession);
localStorage.setItem('sessions', JSON.stringify(sessions));
currentSession = null;
}
}
function resetTimers() {
workTime = 0;
restTime = 0;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
clearInterval(workInterval);
clearInterval(restInterval);
isWorking = false;
}
function updateSessionTable() {
sessionBody.innerHTML = sessions.map(session => `
<tr>
<td>${session.date}</td>
<td>${session.startTime}</td>
<td>${session.endTime}</td>
<td>${formatTime(session.workDuration)}</td>
<td>${formatTime(session.restDuration)}</td>
</tr>
`).join('');
}
playBtn.addEventListener('click', startWork);
pauseBtn.addEventListener('click', pauseWork);
finishBtn.addEventListener('click', finishWorkDay);
window.addEventListener('beforeunload', () => {
if (currentSession) {
saveSession();
}
});
// Initialize
updateDailySummary();
updateSessionTable();
// Check for new day periodically
setInterval(checkNewDay, 60000); // Check every minute
To deploy this on GitHub:
https://[your-username].github.io/[repository-name]/
I'll help you fix the GitHub Pages deployment issue and provide properly linked files. The error occurs because GitHub Pages tries to use Jekyll by default, but our simple HTML/CSS/JS site doesn't need it.
Here's the complete solution:
index.html
→ time.html
styles.css
→ time.css
script.js
→ time.js
.nojekyll
file to disable Jekyll processingHere are all the files you need:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Work/Rest Tracker</title>
<link rel="stylesheet" href="time.css">
</head>
<body>
<div class="container">
<div class="header">
<img src="https://placekitten.com/100/100" alt="Hello Kitty" class="kitty-img">
<h1>NASR IS ASS</h1>
</div>
<div class="tracker">
<div class="timer-display">
<div class="time" id="work-time">Work: 00:00:00</div>
<div class="time" id="rest-time">Rest: 00:00:00</div>
</div>
<div class="controls">
<button id="play-btn">Play</button>
<button id="pause-btn">Pause</button>
<button id="finish-btn">Finish Work Day</button>
</div>
</div>
<div class="calendar">
<h2>Daily Summary</h2>
<div id="calendar-view">
<p id="today-date"></p>
<p id="total-work">Total Work: 00:00:00</p>
<p id="total-rest">Total Rest: 00:00:00</p>
</div>
</div>
<div class="session-history">
<h2>Session History</h2>
<table id="sessions-table">
<thead>
<tr>
<th>Date</th>
<th>Start Time</th>
<th>End Time</th>
<th>Work Duration</th>
<th>Rest Duration</th>
</tr>
</thead>
<tbody id="session-body">
</tbody>
</table>
</div>
</div>
<script src="time.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Work/Rest Tracker</title>
<link rel="stylesheet" href="time.css">
</head>
<body>
<div class="container">
<div class="header">
<img src="https://placekitten.com/100/100" alt="Hello Kitty" class="kitty-img">
<h1>NASR IS ASS</h1>
</div>
<div class="tracker">
<div class="timer-display">
<div class="time" id="work-time">Work: 00:00:00</div>
<div class="time" id="rest-time">Rest: 00:00:00</div>
</div>
<div class="controls">
<button id="play-btn">Play</button>
<button id="pause-btn">Pause</button>
<button id="finish-btn">Finish Work Day</button>
</div>
</div>
<div class="calendar">
<h2>Daily Summary</h2>
<div id="calendar-view">
<p id="today-date"></p>
<p id="total-work">Total Work: 00:00:00</p>
<p id="total-rest">Total Rest: 00:00:00</p>
</div>
</div>
<div class="session-history">
<h2>Session History</h2>
<table id="sessions-table">
<thead>
<tr>
<th>Date</th>
<th>Start Time</th>
<th>End Time</th>
<th>Work Duration</th>
<th>Rest Duration</th>
</tr>
</thead>
<tbody id="session-body">
</tbody>
</table>
</div>
</div>
<script src="time.js"></script>
</body>
</html>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.header {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.kitty-img {
margin-right: 20px;
border-radius: 50%;
}
.tracker {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background-color: #f0f8ff;
border-radius: 8px;
}
.timer-display {
display: flex;
justify-content: space-around;
margin-bottom: 20px;
}
.time {
font-size: 24px;
font-weight: bold;
}
.controls button {
padding: 10px 20px;
margin: 0 10px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 5px;
}
#play-btn {
background-color: #4CAF50;
color: white;
}
#pause-btn {
background-color: #f44336;
color: white;
}
#finish-btn {
background-color: #2196F3;
color: white;
}
.calendar, .session-history {
margin-bottom: 30px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.header {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.kitty-img {
margin-right: 20px;
border-radius: 50%;
}
.tracker {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background-color: #f0f8ff;
border-radius: 8px;
}
.timer-display {
display: flex;
justify-content: space-around;
margin-bottom: 20px;
}
.time {
font-size: 24px;
font-weight: bold;
}
.controls button {
padding: 10px 20px;
margin: 0 10px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 5px;
}
#play-btn {
background-color: #4CAF50;
color: white;
}
#pause-btn {
background-color: #f44336;
color: white;
}
#finish-btn {
background-color: #2196F3;
color: white;
}
.calendar, .session-history {
margin-bottom: 30px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
let workTime = 0;
let restTime = 0;
let workInterval;
let restInterval;
let isWorking = false;
let currentSession = null;
let sessions = JSON.parse(localStorage.getItem('sessions')) || [];
let currentDate = new Date().toLocaleDateString();
const workTimeDisplay = document.getElementById('work-time');
const restTimeDisplay = document.getElementById('rest-time');
const playBtn = document.getElementById('play-btn');
const pauseBtn = document.getElementById('pause-btn');
const finishBtn = document.getElementById('finish-btn');
const todayDateDisplay = document.getElementById('today-date');
const totalWorkDisplay = document.getElementById('total-work');
const totalRestDisplay = document.getElementById('total-rest');
const sessionBody = document.getElementById('session-body');
function formatTime(seconds) {
const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return `${hrs.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
function checkNewDay() {
const today = new Date().toLocaleDateString();
if (today !== currentDate) {
if (currentSession) {
saveSession();
resetTimers();
}
currentDate = today;
updateDailySummary();
}
}
function updateWorkTime() {
checkNewDay();
workTime++;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
updateDailySummary();
}
function updateRestTime() {
checkNewDay();
restTime++;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
updateDailySummary();
}
function updateDailySummary() {
const today = new Date().toLocaleDateString();
const todaySessions = sessions.filter(session => session.date === today);
let totalWork = workTime;
let totalRest = restTime;
todaySessions.forEach(session => {
totalWork += session.workDuration;
totalRest += session.restDuration;
});
todayDateDisplay.textContent = `Today (${today})`;
totalWorkDisplay.textContent = `Total Work: ${formatTime(totalWork)}`;
totalRestDisplay.textContent = `Total Rest: ${formatTime(totalRest)}`;
}
function startWork() {
checkNewDay();
if (!isWorking) {
isWorking = true;
if (!currentSession) {
currentSession = {
date: new Date().toLocaleDateString(),
startTime: new Date().toLocaleTimeString(),
workDuration: 0,
restDuration: 0,
endTime: null
};
}
workInterval = setInterval(updateWorkTime, 1000);
if (restInterval) clearInterval(restInterval);
updateDailySummary();
}
}
function pauseWork() {
if (isWorking) {
isWorking = false;
clearInterval(workInterval);
restInterval = setInterval(updateRestTime, 1000);
updateDailySummary();
}
}
function finishWorkDay() {
if (currentSession) {
saveSession();
resetTimers();
updateDailySummary();
updateSessionTable();
}
}
function saveSession() {
if (currentSession) {
currentSession.endTime = new Date().toLocaleTimeString();
currentSession.workDuration = workTime;
currentSession.restDuration = restTime;
sessions.push(currentSession);
localStorage.setItem('sessions', JSON.stringify(sessions));
currentSession = null;
}
}
function resetTimers() {
workTime = 0;
restTime = 0;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
clearInterval(workInterval);
clearInterval(restInterval);
isWorking = false;
}
function updateSessionTable() {
sessionBody.innerHTML = sessions.map(session => `
<tr>
<td>${session.date}</td>
<td>${session.startTime}</td>
<td>${session.endTime}</td>
<td>${formatTime(session.workDuration)}</td>
<td>${formatTime(session.restDuration)}</td>
</tr>
`).join('');
}
playBtn.addEventListener('click', startWork);
pauseBtn.addEventListener('click', pauseWork);
finishBtn.addEventListener('click', finishWorkDay);
window.addEventListener('beforeunload', () => {
if (currentSession) {
saveSession();
}
});
// Initialize
updateDailySummary();
updateSessionTable();
// Check for new day periodically
setInterval(checkNewDay, 60000);
let workTime = 0;
let restTime = 0;
let workInterval;
let restInterval;
let isWorking = false;
let currentSession = null;
let sessions = JSON.parse(localStorage.getItem('sessions')) || [];
let currentDate = new Date().toLocaleDateString();
const workTimeDisplay = document.getElementById('work-time');
const restTimeDisplay = document.getElementById('rest-time');
const playBtn = document.getElementById('play-btn');
const pauseBtn = document.getElementById('pause-btn');
const finishBtn = document.getElementById('finish-btn');
const todayDateDisplay = document.getElementById('today-date');
const totalWorkDisplay = document.getElementById('total-work');
const totalRestDisplay = document.getElementById('total-rest');
const sessionBody = document.getElementById('session-body');
function formatTime(seconds) {
const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return `${hrs.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
function checkNewDay() {
const today = new Date().toLocaleDateString();
if (today !== currentDate) {
if (currentSession) {
saveSession();
resetTimers();
}
currentDate = today;
updateDailySummary();
}
}
function updateWorkTime() {
checkNewDay();
workTime++;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
updateDailySummary();
}
function updateRestTime() {
checkNewDay();
restTime++;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
updateDailySummary();
}
function updateDailySummary() {
const today = new Date().toLocaleDateString();
const todaySessions = sessions.filter(session => session.date === today);
let totalWork = workTime;
let totalRest = restTime;
todaySessions.forEach(session => {
totalWork += session.workDuration;
totalRest += session.restDuration;
});
todayDateDisplay.textContent = `Today (${today})`;
totalWorkDisplay.textContent = `Total Work: ${formatTime(totalWork)}`;
totalRestDisplay.textContent = `Total Rest: ${formatTime(totalRest)}`;
}
function startWork() {
checkNewDay();
if (!isWorking) {
isWorking = true;
if (!currentSession) {
currentSession = {
date: new Date().toLocaleDateString(),
startTime: new Date().toLocaleTimeString(),
workDuration: 0,
restDuration: 0,
endTime: null
};
}
workInterval = setInterval(updateWorkTime, 1000);
if (restInterval) clearInterval(restInterval);
updateDailySummary();
}
}
function pauseWork() {
if (isWorking) {
isWorking = false;
clearInterval(workInterval);
restInterval = setInterval(updateRestTime, 1000);
updateDailySummary();
}
}
function finishWorkDay() {
if (currentSession) {
saveSession();
resetTimers();
updateDailySummary();
updateSessionTable();
}
}
function saveSession() {
if (currentSession) {
currentSession.endTime = new Date().toLocaleTimeString();
currentSession.workDuration = workTime;
currentSession.restDuration = restTime;
sessions.push(currentSession);
localStorage.setItem('sessions', JSON.stringify(sessions));
currentSession = null;
}
}
function resetTimers() {
workTime = 0;
restTime = 0;
workTimeDisplay.textContent = `Work: ${formatTime(workTime)}`;
restTimeDisplay.textContent = `Rest: ${formatTime(restTime)}`;
clearInterval(workInterval);
clearInterval(restInterval);
isWorking = false;
}
function updateSessionTable() {
sessionBody.innerHTML = sessions.map(session => `
<tr>
<td>${session.date}</td>
<td>${session.startTime}</td>
<td>${session.endTime}</td>
<td>${formatTime(session.workDuration)}</td>
<td>${formatTime(session.restDuration)}</td>
</tr>
`).join('');
}
playBtn.addEventListener('click', startWork);
pauseBtn.addEventListener('click', pauseWork);
finishBtn.addEventListener('click', finishWorkDay);
window.addEventListener('beforeunload', () => {
if (currentSession) {
saveSession();
}
});
// Initialize
updateDailySummary();
updateSessionTable();
// Check for new day periodically
setInterval(checkNewDay, 60000);
Create this empty file in your repository to disable Jekyll processing.
time.html
time.css
time.js
.nojekyll
(empty file)The site should now be live at: https://[your-username].github.io/[repository-name]/time.html
The error you were seeing was because GitHub Pages was trying to process your files with Jekyll. The .nojekyll
file prevents this and lets your static files work as-is.
The error persists because GitHub Pages is still trying to use Jekyll despite the .nojekyll
file. Let's fix this with a more reliable approach:
docs
folder - GitHub Pages works best when serving from /docs
folder/docs
index.html
as the entry point/docs
folderHere's the complete structure you need:
repository-root/
├── docs/
│ ├── .nojekyll
│ ├── index.html (redirect)
│ ├── time.html
│ ├── time.css
│ └── time.js
repository-root/
├── docs/
│ ├── .nojekyll
│ ├── index.html (redirect)
│ ├── time.html
│ ├── time.css
│ └── time.js
docs/.nojekyll (empty file)
docs/index.html (redirect to time.html):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0; url=time.html">
</head>
<body>
Redirecting to time tracker...
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0; url=time.html">
</head>
<body>
Redirecting to time tracker...
</body>
</html>
/docs
folder./docs
(not root!)/docs
folder is GitHub's recommended way to host project pages.nojekyll
file inside /docs
properly disables Jekyll processingindex.html
ensures users land on your time tracker immediatelyYour site will be available at:
https://[your-username].github.io/[repository-name]/
(will redirect to time.html)
If you still see Jekyll errors after this:
This approach has worked reliably for many static sites on GitHub Pages. The key is using the /docs
folder rather than root, as GitHub's automatic Jekyll processing behaves differently for project pages vs. user/organization pages.
Here are several free hosting alternatives to GitHub Pages that will work well for your time tracker site:
Steps:
random-name.netlify.app
)Steps:
Steps:
/
(or /docs
if using that)Steps:
npm install -g surge
surge ./ your-site-name.surge.sh
npm install -g surge
surge ./ your-site-name.surge.sh
Use Netlify Drop if you want the simplest solution - just drag and drop your files. For automatic updates when you push code, Vercel or Cloudflare Pages are excellent choices.
All these services will host your static files without the Jekyll errors you encountered on GitHub Pages. They all provide:
Choose based on which workflow you prefer (manual upload vs. Git integration).