diff --git a/README.md b/README.md index 73ff5c6..5667aa1 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ A simple habit tracker that runs entirely in your web browser. No installation, - **Check them off** – click **Mark done today** each day you do the habit. Click it again to undo. - **See your streak** – each habit shows how many days in a row you've kept it up. If you haven't checked it off yet today, your streak from yesterday still counts until the day is over. - **30-day grid** – a row of squares shows the last 30 days (oldest on the left, today on the right). Green means done. Click any square to fix a day you forgot to mark. +- **Weekly summary** – a "This week" box at the top shows how many days each habit was done so far this week (for example "4 of 7 days"), with a bar to compare at a glance. The week starts on the usual day for your region (Sunday or Monday) and resets automatically. - **Rename or delete** habits with the buttons next to each one. ## How to start it diff --git a/index.html b/index.html index f41dc85..830b75d 100644 --- a/index.html +++ b/index.html @@ -138,6 +138,33 @@ font-size: 0.8rem; margin-top: 4px; } + .week-summary { + background: var(--card); + border: 1px solid var(--border); + border-radius: 12px; + padding: 16px; + margin-bottom: 20px; + } + .week-summary h2 { margin: 0; font-size: 1.15rem; } + .week-range { color: var(--muted); font-size: 0.9rem; margin: 2px 0 12px; } + .week-row { + display: grid; + grid-template-columns: minmax(80px, 1.2fr) 2fr auto; + align-items: center; + gap: 12px; + padding: 6px 0; + } + .week-row + .week-row { border-top: 1px solid var(--border); } + .week-name { font-weight: 600; word-break: break-word; } + .week-bar { + height: 10px; + border-radius: 5px; + background: var(--empty); + overflow: hidden; + } + .week-bar-fill { height: 100%; background: var(--accent); border-radius: 5px; } + .week-count { color: var(--muted); font-size: 0.95rem; white-space: nowrap; } + .week-count strong { color: var(--text); } .hint { color: var(--muted); font-size: 0.85rem; @@ -160,6 +187,8 @@ + +

Tip: click any square in the 30-day grid to mark or unmark that day. @@ -234,6 +263,28 @@ } return count; } + // First day of the week for the user's region (0 = Sunday, 1 = Monday, ...). + // Uses the browser's regional settings when available, otherwise Monday. + function weekStartDay() { + try { + var loc = new Intl.Locale(navigator.language || "en"); + var info = typeof loc.getWeekInfo === "function" ? loc.getWeekInfo() : loc.weekInfo; + if (info && info.firstDay >= 1 && info.firstDay <= 7) return info.firstDay % 7; + } catch (e) { /* fall through */ } + return 1; + } + var WEEK_START = weekStartDay(); + // How many days of the current week have passed, counting today (1-7). + function daysIntoWeek() { + return ((daysAgo(0).getDay() - WEEK_START + 7) % 7) + 1; + } + function doneThisWeek(habit) { + var count = 0; + for (var i = 0; i < daysIntoWeek(); i++) { + if (habit.done[dateKey(daysAgo(i))]) count++; + } + return count; + } function toggleDay(habit, key) { if (habit.done[key]) delete habit.done[key]; else habit.done[key] = true; @@ -253,6 +304,7 @@ }); listEl.innerHTML = ""; + renderWeekSummary(); if (habits.length === 0) { var empty = document.createElement("div"); @@ -358,6 +410,53 @@ }); } + function renderWeekSummary() { + var box = document.getElementById("weekSummary"); + box.innerHTML = ""; + if (habits.length === 0) { box.hidden = true; return; } + box.hidden = false; + + var soFar = daysIntoWeek(); + var heading = document.createElement("h2"); + heading.textContent = "This week"; + var range = document.createElement("p"); + range.className = "week-range"; + range.textContent = prettyDate(daysAgo(soFar - 1)) + " – " + prettyDate(daysAgo(soFar - 7)) + + " · day " + soFar + " of 7"; + box.appendChild(heading); + box.appendChild(range); + + habits.forEach(function (habit) { + var count = doneThisWeek(habit); + var row = document.createElement("div"); + row.className = "week-row"; + + var name = document.createElement("div"); + name.className = "week-name"; + name.textContent = habit.name; + + var bar = document.createElement("div"); + bar.className = "week-bar"; + var fill = document.createElement("div"); + fill.className = "week-bar-fill"; + fill.style.width = (count / 7 * 100) + "%"; + bar.appendChild(fill); + + var countEl = document.createElement("div"); + countEl.className = "week-count"; + var strong = document.createElement("strong"); + strong.textContent = count; + countEl.appendChild(strong); + countEl.appendChild(document.createTextNode(" of 7 days")); + + row.title = habit.name + ": done " + count + (count === 1 ? " day" : " days") + " this week"; + row.appendChild(name); + row.appendChild(bar); + row.appendChild(countEl); + box.appendChild(row); + }); + } + // ---------- Adding habits ---------- document.getElementById("addForm").addEventListener("submit", function (e) { e.preventDefault();