Streak Counter

This commit is contained in:
jafreli
2025-07-16 22:37:35 +02:00
parent 5bc7faa451
commit 04c40b29d9
3 changed files with 103 additions and 16 deletions

View File

@@ -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;

View File

@@ -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);
});
}