Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9c07658

Browse files
authored
1 parent 1e1e759 commit 9c07658

File tree

1 file changed

+179
-6
lines changed
  • pomodoro.html

1 file changed

+179
-6
lines changed

pomodoro.html

Lines changed: 179 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
body {
99
font-family: Arial, sans-serif;
1010
display: flex;
11-
justify-content: center;
11+
flex-direction: column;
1212
align-items: center;
13-
height: 100vh;
14-
margin: 0;
13+
padding: 2rem;
1514
background-color: #f0f0f0;
1615
}
1716
.container {
@@ -20,12 +19,13 @@
2019
padding: 2rem;
2120
border-radius: 10px;
2221
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
22+
margin-bottom: 2rem;
2323
}
2424
#timer {
2525
font-size: 4rem;
2626
margin-bottom: 1rem;
2727
}
28-
button, select {
28+
button, select, input {
2929
font-size: 1rem;
3030
padding: 0.5rem 1rem;
3131
margin: 0.5rem;
@@ -41,11 +41,11 @@
4141
#startBtn:hover {
4242
background-color: #45a049;
4343
}
44-
#resetBtn {
44+
#resetBtn, #endBtn {
4545
background-color: #f44336;
4646
color: white;
4747
}
48-
#resetBtn:hover {
48+
#resetBtn:hover, #endBtn:hover {
4949
background-color: #da190b;
5050
}
5151
select {
@@ -55,11 +55,43 @@
5555
select:hover {
5656
background-color: #2980b9;
5757
}
58+
#goalInput {
59+
width: 100%;
60+
padding: 0.5rem;
61+
margin-bottom: 1rem;
62+
border: 1px solid #ccc;
63+
border-radius: 5px;
64+
}
65+
#sessionLog {
66+
width: 100%;
67+
max-width: 800px;
68+
margin-top: 2rem;
69+
overflow-x: auto;
70+
}
71+
#sessionLog table {
72+
width: 100%;
73+
border-collapse: collapse;
74+
}
75+
#sessionLog th, #sessionLog td {
76+
border: 1px solid #ddd;
77+
padding: 8px;
78+
text-align: left;
79+
}
80+
#sessionLog th {
81+
background-color: #f2f2f2;
82+
}
83+
#jsonOutput {
84+
width: 100%;
85+
height: 200px;
86+
margin-top: 2rem;
87+
font-family: monospace;
88+
}
5889
style>
5990
head>
6091
<body>
6192
<div class="container">
6293
<h1>Pomodoro Timerh1>
94+
<input type="text" id="goalInput" placeholder="Enter your goal for this session" required>
6395
<div id="timer">25:00div>
6496
<select id="durationSelect">
6597
<option value="5">5 minutesoption>
@@ -74,18 +106,81 @@

Pomodoro Timer

74106
<br>
75107
<button id="startBtn">Startbutton>
76108
<button id="resetBtn">Resetbutton>
109+
<button id="endBtn">End Sessionbutton>
110+
div>
111+
112+
<div id="sessionLog">
113+
<h2>Session Logh2>
114+
<table>
115+
<thead>
116+
<tr>
117+
<th>Goalth>
118+
<th>Start Timeth>
119+
<th>End Timeth>
120+
<th>Durationth>
121+
<th>Pausesth>
122+
tr>
123+
thead>
124+
<tbody id="sessionLogBody">tbody>
125+
table>
77126
div>
78127

128+
<textarea id="jsonOutput" readonly>textarea>
129+
79130
<script>
80131
const timerDisplay = document.getElementById('timer');
81132
const startBtn = document.getElementById('startBtn');
82133
const resetBtn = document.getElementById('resetBtn');
134+
const endBtn = document.getElementById('endBtn');
83135
const durationSelect = document.getElementById('durationSelect');
136+
const goalInput = document.getElementById('goalInput');
137+
const sessionLogBody = document.getElementById('sessionLogBody');
138+
const jsonOutput = document.getElementById('jsonOutput');
84139

85140
let startTime;
86141
let timeLeft = 25 * 60; // Default to 25 minutes in seconds
87142
let isRunning = false;
88143
let duration = 25 * 60; // Default duration in seconds
144+
let currentSession = null;
145+
let sessions = [];
146+
147+
// Check if localStorage is available
148+
function isLocalStorageAvailable() {
149+
try {
150+
localStorage.setItem('test', 'test');
151+
localStorage.removeItem('test');
152+
return true;
153+
} catch (e) {
154+
return false;
155+
}
156+
}
157+
158+
// Load sessions from storage
159+
function loadSessions() {
160+
if (isLocalStorageAvailable()) {
161+
const storedSessions = localStorage.getItem('pomodoroSessions');
162+
if (storedSessions) {
163+
sessions = JSON.parse(storedSessions);
164+
}
165+
} else {
166+
console.warn('localStorage is not available. Session data will not persist.');
167+
}
168+
updateSessionLog();
169+
}
170+
171+
loadSessions();
172+
173+
function formatDate(date) {
174+
return new Date(date).toLocaleString('en-US', {
175+
year: 'numeric',
176+
month: '2-digit',
177+
day: '2-digit',
178+
hour: '2-digit',
179+
minute: '2-digit',
180+
second: '2-digit',
181+
hour12: true
182+
}).replace(',', '');
183+
}
89184

90185
function updateDisplay() {
91186
const minutes = Math.floor(timeLeft / 60);
@@ -95,14 +190,34 @@

Pomodoro Timer

95190

96191
function startTimer() {
97192
if (!isRunning) {
193+
if (!goalInput.value) {
194+
alert('Please enter a goal for this session.');
195+
return;
196+
}
98197
isRunning = true;
99198
startBtn.textContent = 'Pause';
100199
durationSelect.disabled = true;
200+
goalInput.disabled = true;
201+
if (!currentSession) {
202+
currentSession = {
203+
goal: goalInput.value,
204+
startTime: new Date().toISOString(),
205+
endTime: null,
206+
duration: 0,
207+
pauses: []
208+
};
209+
} else {
210+
currentSession.pauses[currentSession.pauses.length - 1].resumeTime = new Date().toISOString();
211+
}
101212
startTime = Date.now() - ((duration - timeLeft) * 1000);
102213
requestAnimationFrame(updateTimer);
103214
} else {
104215
isRunning = false;
105216
startBtn.textContent = 'Resume';
217+
currentSession.pauses.push({
218+
pauseTime: new Date().toISOString(),
219+
resumeTime: null
220+
});
106221
}
107222
}
108223

@@ -116,6 +231,8 @@

Pomodoro Timer

116231
isRunning = false;
117232
startBtn.textContent = 'Start';
118233
durationSelect.disabled = false;
234+
goalInput.disabled = false;
235+
endSession();
119236
alert('Pomodoro session complete!');
120237
} else {
121238
requestAnimationFrame(updateTimer);
@@ -132,6 +249,8 @@

Pomodoro Timer

132249
updateDisplay();
133250
startBtn.textContent = 'Start';
134251
durationSelect.disabled = false;
252+
goalInput.disabled = false;
253+
currentSession = null;
135254
}
136255

137256
function changeDuration() {
@@ -142,10 +261,64 @@

Pomodoro Timer

142261
}
143262
}
144263

264+
function endSession() {
265+
if (currentSession) {
266+
currentSession.endTime = new Date().toISOString();
267+
currentSession.duration = Math.round((new Date(currentSession.endTime) - new Date(currentSession.startTime)) / 1000);
268+
sessions.unshift(currentSession);
269+
updateSessionLog();
270+
saveSessions();
271+
resetTimer();
272+
}
273+
}
274+
275+
function updateSessionLog() {
276+
sessionLogBody.innerHTML = '';
277+
sessions.forEach(session => {
278+
const row = document.createElement('tr');
279+
row.innerHTML = `
280+
${session.goal}
281+
${formatDate(session.startTime)}
282+
${session.endTime ? formatDate(session.endTime) : 'In progress'}
283+
${formatDuration(session.duration)}
284+
${formatPauses(session.pauses)}
285+
`;
286+
sessionLogBody.appendChild(row);
287+
});
288+
jsonOutput.value = JSON.stringify(sessions, null, 2);
289+
}
290+
291+
function formatDuration(seconds) {
292+
const minutes = Math.floor(seconds / 60);
293+
const remainingSeconds = seconds % 60;
294+
return `${minutes}m ${remainingSeconds}s`;
295+
}
296+
297+
function formatPauses(pauses) {
298+
return pauses.map(pause =>
299+
`${formatDate(pause.pauseTime)} - ${pause.resumeTime ? formatDate(pause.resumeTime) : 'Not resumed'}`
300+
).join('
'
);
301+
}
302+
303+
function saveSessions() {
304+
if (isLocalStorageAvailable()) {
305+
localStorage.setItem('pomodoroSessions', JSON.stringify(sessions));
306+
}
307+
}
308+
145309
startBtn.addEventListener('click', startTimer);
146310
resetBtn.addEventListener('click', resetTimer);
311+
endBtn.addEventListener('click', endSession);
147312
durationSelect.addEventListener('change', changeDuration);
148313

314+
// Keyboard shortcut
315+
document.addEventListener('keydown', (e) => {
316+
if (e.code === 'Space' && document.activeElement !== goalInput) {
317+
e.preventDefault();
318+
startTimer();
319+
}
320+
});
321+
149322
updateDisplay();
150323
script>
151324
body>

0 commit comments

Comments
(0)