document.addEventListener('DOMContentLoaded', fetchHabits); const habitListDiv = document.getElementById('habitList'); const dateModal = document.getElementById('dateModal'); const modalHabitName = document.getElementById('modalHabitName'); const modalDateGrid = document.getElementById('modalDateGrid'); const modalCompleteTodayBtn = document.getElementById('modalCompleteTodayBtn'); let currentHabitId = null; function getCurrentDate() { const today = new Date(); const year = today.getFullYear(); const month = String(today.getMonth() + 1).padStart(2, '0'); const day = String(today.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } function getPastDates(days) { const dates = []; for (let i = days - 1; i >= 0; i--) { const d = new Date(); d.setDate(d.getDate() - i); const year = d.getFullYear(); const month = String(d.getMonth() + 1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0'); dates.push(`${year}-${month}-${day}`); } return dates; } async function fetchHabits() { try { const response = await fetch('/habits'); const habits = await response.json(); renderHabits(habits); } catch (error) { console.error('Error fetching habits:', error); } } function renderHabits(habits) { habitListDiv.innerHTML = ''; // Clear previous habits const last30Days = getPastDates(30); habits.forEach(habit => { const habitItem = document.createElement('div'); habitItem.className = 'habit-item'; habitItem.dataset.id = habit.id; // Store habit ID const habitHeader = document.createElement('div'); habitHeader.className = 'habit-header'; const habitName = document.createElement('div'); habitName.className = 'habit-name'; habitName.textContent = habit.name; habitHeader.appendChild(habitName); const habitActions = document.createElement('div'); habitActions.className = 'habit-actions'; const openModalButton = document.createElement('button'); openModalButton.innerHTML = '✔'; // Checkmark symbol openModalButton.onclick = () => openHabitModal(habit.id, habit.name, habit.completed_dates); habitActions.appendChild(openModalButton); habitHeader.appendChild(habitActions); habitItem.appendChild(habitHeader); const dateGrid = document.createElement('div'); dateGrid.className = 'date-grid'; last30Days.forEach(date => { const dateSquare = document.createElement('div'); dateSquare.className = 'date-square'; if (habit.completed_dates && habit.completed_dates.includes(date)) { dateSquare.classList.add('completed'); } dateSquare.title = date; // Show date on hover dateGrid.appendChild(dateSquare); }); habitItem.appendChild(dateGrid); habitListDiv.appendChild(habitItem); }); } async function addHabit() { const newHabitNameInput = document.getElementById('newHabitName'); const name = newHabitNameInput.value.trim(); if (name) { try { const response = await fetch('/habits', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name }) }); const newHabit = await response.json(); if (response.ok) { newHabitNameInput.value = ''; fetchHabits(); // Re-fetch and re-render all habits } else { console.error('Failed to add habit:', newHabit.error); } } catch (error) { console.error('Error adding habit:', error); } } } async function openHabitModal(habitId, habitName, completedDates) { currentHabitId = habitId; modalHabitName.textContent = habitName; modalCompleteTodayBtn.dataset.habitId = habitId; // Store habit ID for button modalDateGrid.innerHTML = ''; const today = getCurrentDate(); const startOfWeek = new Date(); startOfWeek.setDate(startOfWeek.getDate() - (startOfWeek.getDay() + 6) % 7); // Go back to Monday for (let i = 0; i < 35; i++) { // Display 5 weeks (5 * 7 days) const d = new Date(startOfWeek); d.setDate(startOfWeek.getDate() + i); const dateStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; const dateCell = document.createElement('div'); dateCell.className = 'date-cell'; dateCell.textContent = d.getDate(); if (completedDates.includes(dateStr)) { dateCell.classList.add('completed'); } if (dateStr === today) { dateCell.classList.add('today'); } dateCell.dataset.date = dateStr; dateCell.onclick = (event) => toggleCompletionForDate(event, habitId, dateStr); modalDateGrid.appendChild(dateCell); } dateModal.style.display = 'flex'; // Show the modal } function closeModal() { dateModal.style.display = 'none'; currentHabitId = null; fetchHabits(); // Refresh habits after closing modal } async function toggleCompletionForDate(event, habitId, date) { const cell = event.target; let response; let data; if (cell.classList.contains('completed')) { // Mark as uncompleted response = await fetch(`/habits/${habitId}/uncomplete`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ date: date }) }); data = await response.json(); if (response.ok) { cell.classList.remove('completed'); // Update the completion_history in the rendered habits // (You might need to re-fetch or update the local habit data for the main view) } } else { // Mark as completed response = await fetch(`/habits/${habitId}/complete`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ date: date }) }); data = await response.json(); if (response.ok) { cell.classList.add('completed'); // Update the completion_history } } } async function completeHabitForDate(event, habitId, date) { try { const response = await fetch(`/habits/${habitId}/complete`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ date: date }) }); const data = await response.json(); if (response.ok) { // Update the modal's date grid immediately const dateCells = modalDateGrid.querySelectorAll('.date-cell'); dateCells.forEach(cell => { if (cell.dataset.date === date) { cell.classList.add('completed'); } }); // Optionally, disable the "Today erledigen" button if already completed // modalCompleteTodayBtn.disabled = true; } else { console.error('Failed to complete habit:', data.error); } } catch (error) { console.error('Error completing habit:', error); } } async function editHabitName() { const newName = prompt("Neuen Namen für die Gewohnheit eingeben:", modalHabitName.textContent); if (newName && newName.trim() !== "") { try { const response = await fetch(`/habits/${currentHabitId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: newName.trim() }) }); const data = await response.json(); if (response.ok) { modalHabitName.textContent = newName.trim(); fetchHabits(); // Re-fetch and re-render all habits to update the main view } else { console.error('Failed to update habit:', data.error); } } catch (error) { console.error('Error updating habit:', error); } } } async function deleteHabitFromModal() { if (confirm("Bist du sicher, dass du diese Gewohnheit löschen möchtest?")) { try { const response = await fetch(`/habits/${currentHabitId}`, { method: 'DELETE' }); const data = await response.json(); if (response.ok) { closeModal(); fetchHabits(); // Re-fetch and re-render all habits } else { console.error('Failed to delete habit:', data.error); } } catch (error) { console.error('Error deleting habit:', error); } } }