Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
140 lines (112 loc) · 4.64 KB
/
Copy pathscript.js
File metadata and controls
140 lines (112 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// This file does 4 things:
// 1. Load saved sessions from the browser's localStorage
// 2. Let the user add a new session through the form
// 3. Show all sessions on the page
// 4. Calculate simple stats (total sessions, total minutes, streak)
// Grab references to the HTML elements we'll need
const sessionForm = document.getElementById('sessionForm');
const instrumentInput = document.getElementById('instrument');
const pieceInput = document.getElementById('piece');
const durationInput = document.getElementById('duration');
const notesInput = document.getElementById('notes');
const sessionListEl = document.getElementById('sessionList');
const emptyStateEl = document.getElementById('emptyState');
const totalSessionsEl = document.getElementById('totalSessions');
const totalMinutesEl = document.getElementById('totalMinutes');
const currentStreakEl = document.getElementById('currentStreak');
// Load existing sessions, or start with an empty list
let sessions = JSON.parse(localStorage.getItem('practiceSessions')) || [];
function saveSessions() {
localStorage.setItem('practiceSessions', JSON.stringify(sessions));
}
// Handle the "Add session" form submit
sessionForm.addEventListener('submit', function (event) {
event.preventDefault(); // stops the page from refreshing (default form behaviour)
// Build one session object from the form's current values
const newSession = {
id: Date.now(), // a simple unique ID using the current timestamp
instrument: instrumentInput.value.trim(),
piece: pieceInput.value.trim(),
duration: Number(durationInput.value),
notes: notesInput.value.trim(),
date: new Date().toISOString() // store the exact date/time as text
};
// Add it to the FRONT of the array so newest sessions show first
sessions.unshift(newSession);
saveSessions();
renderEverything();
// Clear the form so it's ready for the next entry
sessionForm.reset();
});
// Handle deleting a session
sessionListEl.addEventListener('click', function (event) {
if (event.target.classList.contains('delete-btn')) {
const idToDelete = Number(event.target.dataset.id);
sessions = sessions.filter(function (session) {
return session.id !== idToDelete; // keep everything EXCEPT the deleted one
});
saveSessions();
renderEverything();
}
});
// Render the list of session cards
function renderSessionList() {
// Clear whatever is currently shown
sessionListEl.innerHTML = '';
// Show/hide the "no sessions yet" message
emptyStateEl.style.display = sessions.length === 0 ? 'block' : 'none';
// Build one <li> card per session
sessions.forEach(function (session) {
const li = document.createElement('li');
li.className = 'session-card';
// Format the date nicely
const dateLabel = new Date(session.date).toLocaleDateString('en-IN', {
day: 'numeric', month: 'short', year: 'numeric'
});
li.innerHTML = `
<div class="session-info">
<h3>${session.piece}</h3>
<p class="session-meta">${session.instrument} · ${dateLabel} · ${session.duration} min</p>
${session.notes ? `<p class="session-notes">${session.notes}</p>` : ''}
</div>
<button class="delete-btn" data-id="${session.id}">Delete</button>
`;
sessionListEl.appendChild(li);
});
}
// Calculate and render the stats (sessions, minutes, streak)
function renderStats() {
totalSessionsEl.textContent = sessions.length;
const totalMinutes = sessions.reduce(function (sum, session) {
return sum + session.duration;
}, 0);
totalMinutesEl.textContent = totalMinutes;
currentStreakEl.textContent = calculateStreak();
}
// Streak = how many days in a row (counting back from today) have at least one logged session.
function calculateStreak() {
if (sessions.length === 0) return 0;
// Get a Set of unique practice dates as "YYYY-MM-DD" strings.
// A Set automatically removes duplicates, which is perfect here
// since one day might have multiple sessions.
const practiceDates = new Set(
sessions.map(function (session) {
return session.date.slice(0, 10); // "2026-07-24T10:00:00Z" -> "2026-07-24"
})
);
let streak = 0;
let cursor = new Date(); // start checking from today
// Walk backwards one day at a time while that day exists in practiceDates
while (practiceDates.has(cursor.toISOString().slice(0, 10))) {
streak++;
cursor.setDate(cursor.getDate() - 1); // move to the previous day
}
return streak;
}
// One function that refreshes the whole page
function renderEverything() {
renderSessionList();
renderStats();
}
// Run once when the page first loads
renderEverything();