Streak Counter
This commit is contained in:
@@ -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"]}}}
|
{"_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": []}}}
|
||||||
@@ -106,12 +106,16 @@ h1 {
|
|||||||
|
|
||||||
.date-grid {
|
.date-grid {
|
||||||
display: 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;
|
gap: 2px;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
overflow-x: auto; /* Enable horizontal scrolling if dates exceed width */
|
overflow-x: auto;
|
||||||
-ms-overflow-style: none; /* IE and Edge */
|
/* Enable horizontal scrolling if dates exceed width */
|
||||||
scrollbar-width: none; /* Firefox */
|
-ms-overflow-style: none;
|
||||||
|
/* IE and Edge */
|
||||||
|
scrollbar-width: none;
|
||||||
|
/* Firefox */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||||
@@ -120,7 +124,8 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.date-square {
|
.date-square {
|
||||||
width: 15px; /* Adjust size as needed */
|
width: 15px;
|
||||||
|
/* Adjust size as needed */
|
||||||
height: 15px;
|
height: 15px;
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
@@ -133,15 +138,22 @@ h1 {
|
|||||||
|
|
||||||
/* Modal Styles */
|
/* Modal Styles */
|
||||||
.modal {
|
.modal {
|
||||||
display: none; /* Hidden by default */
|
display: none;
|
||||||
position: fixed; /* Stay in place */
|
/* Hidden by default */
|
||||||
z-index: 1; /* Sit on top */
|
position: fixed;
|
||||||
|
/* Stay in place */
|
||||||
|
z-index: 1;
|
||||||
|
/* Sit on top */
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%; /* Full width */
|
width: 100%;
|
||||||
height: 100%; /* Full height */
|
/* Full width */
|
||||||
overflow: auto; /* Enable scroll if needed */
|
height: 100%;
|
||||||
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
/* Full height */
|
||||||
|
overflow: auto;
|
||||||
|
/* Enable scroll if needed */
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
/* Black w/ opacity */
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
@@ -223,7 +235,8 @@ h1 {
|
|||||||
|
|
||||||
.date-grid-modal {
|
.date-grid-modal {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(7, 1fr); /* 7 days a week */
|
grid-template-columns: repeat(7, 1fr);
|
||||||
|
/* 7 days a week */
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
@@ -242,7 +255,8 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.date-cell.today {
|
.date-cell.today {
|
||||||
border: 2px solid #007bff; /* Highlight today */
|
border: 2px solid #007bff;
|
||||||
|
/* Highlight today */
|
||||||
}
|
}
|
||||||
|
|
||||||
.date-cell.empty {
|
.date-cell.empty {
|
||||||
@@ -250,6 +264,30 @@ h1 {
|
|||||||
cursor: default;
|
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 {
|
.modal-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
|
|||||||
@@ -34,6 +34,38 @@ function getPastDates(days) {
|
|||||||
return dates;
|
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() {
|
async function fetchHabits() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/habits');
|
const response = await fetch('/habits');
|
||||||
@@ -95,6 +127,23 @@ function renderHabits(habits) {
|
|||||||
});
|
});
|
||||||
habitItem.appendChild(dateGrid);
|
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);
|
habitListDiv.appendChild(habitItem);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user