diff --git a/habits.json b/habits.json index 1ad57b0..cfc7851 100644 --- a/habits.json +++ b/habits.json @@ -1 +1 @@ -{"_default": {"1": {"name": "Zocken Mega", "completed_dates": ["2025-07-16", "2025-07-14", "2025-08-01", "2025-08-09", "2025-08-17", "2025-07-15", "2025-07-01", "2025-06-29", "2025-06-19", "2025-06-20"]}}} \ No newline at end of file +{"_default": {"1": {"name": "Zocken Mega", "completed_dates": ["2025-07-16", "2025-07-14", "2025-08-01", "2025-08-09", "2025-08-17", "2025-07-15", "2025-07-01", "2025-06-29", "2025-06-19", "2025-06-20", "2025-07-13", "2025-07-12"]}, "2": {"name": "Laufen", "completed_dates": []}}} \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css index 57908a8..15f805a 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -106,12 +106,16 @@ h1 { .date-grid { display: grid; - grid-template-columns: repeat(30, 1fr); /* Adjust based on your date range */ + grid-template-columns: repeat(30, 1fr); + /* Adjust based on your date range */ gap: 2px; padding: 5px 0; - overflow-x: auto; /* Enable horizontal scrolling if dates exceed width */ - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + overflow-x: auto; + /* Enable horizontal scrolling if dates exceed width */ + -ms-overflow-style: none; + /* IE and Edge */ + scrollbar-width: none; + /* Firefox */ } /* Hide scrollbar for Chrome, Safari and Opera */ @@ -120,7 +124,8 @@ h1 { } .date-square { - width: 15px; /* Adjust size as needed */ + width: 15px; + /* Adjust size as needed */ height: 15px; background-color: #555; border-radius: 2px; @@ -133,15 +138,22 @@ h1 { /* Modal Styles */ .modal { - display: none; /* Hidden by default */ - position: fixed; /* Stay in place */ - z-index: 1; /* Sit on top */ + display: none; + /* Hidden by default */ + position: fixed; + /* Stay in place */ + z-index: 1; + /* Sit on top */ left: 0; top: 0; - width: 100%; /* Full width */ - height: 100%; /* Full height */ - overflow: auto; /* Enable scroll if needed */ - background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ + width: 100%; + /* Full width */ + height: 100%; + /* Full height */ + overflow: auto; + /* Enable scroll if needed */ + background-color: rgba(0, 0, 0, 0.4); + /* Black w/ opacity */ justify-content: center; align-items: center; } @@ -153,7 +165,7 @@ h1 { border-radius: 10px; width: 80%; max-width: 500px; - box-shadow: 0 5px 15px rgba(0,0,0,0.3); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); position: relative; } @@ -223,7 +235,8 @@ h1 { .date-grid-modal { display: grid; - grid-template-columns: repeat(7, 1fr); /* 7 days a week */ + grid-template-columns: repeat(7, 1fr); + /* 7 days a week */ gap: 5px; margin-bottom: 20px; } @@ -242,7 +255,8 @@ h1 { } .date-cell.today { - border: 2px solid #007bff; /* Highlight today */ + border: 2px solid #007bff; + /* Highlight today */ } .date-cell.empty { @@ -250,6 +264,30 @@ h1 { cursor: default; } +.streak-container { + display: flex; + align-items: center; + justify-content: center; + margin-top: 10px; + padding: 5px; + background-color: #444; + border-radius: 15px; + width: fit-content; + margin-left: auto; + margin-right: auto; +} + +.flame-icon { + font-size: 1.2em; + margin-right: 5px; +} + +.streak-count { + color: #e0e0e0; + font-size: 0.9em; + font-weight: bold; +} + .modal-actions { display: flex; justify-content: space-around; diff --git a/static/js/script.js b/static/js/script.js index 6b99540..24af1bc 100644 --- a/static/js/script.js +++ b/static/js/script.js @@ -34,6 +34,38 @@ function getPastDates(days) { return dates; } +function calculateStreak(completedDates) { + if (!completedDates || completedDates.length === 0) { + return 0; + } + + // Sort dates in descending order (newest first) + const sortedDates = completedDates.sort((a, b) => new Date(b) - new Date(a)); + const today = getCurrentDate(); + + let streak = 0; + let currentDate = new Date(); + + // Check if today is completed, if not, start from yesterday + if (!sortedDates.includes(today)) { + currentDate.setDate(currentDate.getDate() - 1); + } + + // Count consecutive days backwards from today (or yesterday) + while (true) { + const dateStr = `${currentDate.getFullYear()}-${String(currentDate.getMonth() + 1).padStart(2, '0')}-${String(currentDate.getDate()).padStart(2, '0')}`; + + if (sortedDates.includes(dateStr)) { + streak++; + currentDate.setDate(currentDate.getDate() - 1); + } else { + break; + } + } + + return streak; +} + async function fetchHabits() { try { const response = await fetch('/habits'); @@ -95,6 +127,23 @@ function renderHabits(habits) { }); habitItem.appendChild(dateGrid); + // Streak Counter hinzufügen + const streakContainer = document.createElement('div'); + streakContainer.className = 'streak-container'; + + const flameIcon = document.createElement('span'); + flameIcon.className = 'flame-icon'; + flameIcon.innerHTML = '🔥'; // Flammen-Emoji + + const streakCount = document.createElement('span'); + streakCount.className = 'streak-count'; + const currentStreak = calculateStreak(habit.completed_dates); + streakCount.textContent = `${currentStreak} Tag${currentStreak !== 1 ? 'e' : ''}`; + + streakContainer.appendChild(flameIcon); + streakContainer.appendChild(streakCount); + habitItem.appendChild(streakContainer); + habitListDiv.appendChild(habitItem); }); }