// Calendar functionality for Todo app
document.addEventListener('DOMContentLoaded', () => {
// Set up event listeners
const calendarBtn = document.getElementById('tab-calendar-btn');
const calendarModal = document.getElementById('calendar-modal');
const calendarCloseBtn = document.getElementById('calendar-close-btn');
if (calendarBtn) {
calendarBtn.addEventListener('click', showCalendarModal);
}
if (calendarCloseBtn) {
calendarCloseBtn.addEventListener('click', () => {
calendarModal.style.display = 'none';
});
}
// Close modal when clicking outside of it
window.addEventListener('click', (e) => {
if (e.target === calendarModal) {
calendarModal.style.display = 'none';
}
});
});
// Function to show the calendar modal
function showCalendarModal() {
const calendarModal = document.getElementById('calendar-modal');
const calendarContainer = document.getElementById('calendar-container');
if (!calendarModal || !calendarContainer) {
console.error('Calendar modal elements not found');
return;
}
// Get todos from various sources
let todos = [];
// First try to get todos from the global window.todos array
if (window.todos && Array.isArray(window.todos)) {
todos = window.todos.slice(); // Make a copy of the array
console.log('Using todos from window.todos:', todos.length);
}
// If window.todos is empty, try the localStorage
if (!todos.length) {
try {
const STORAGE_KEY = 'todos-v1'; // Match the key used in app.js
const storedTodos = localStorage.getItem(STORAGE_KEY);
if (storedTodos) {
todos = JSON.parse(storedTodos);
console.log('Using todos from localStorage:', todos.length);
}
} catch (e) {
console.error('Error loading todos from localStorage:', e);
}
}
// If we still don't have todos, try one more approach
if (!todos.length) {
// Force a load from localStorage via the app's loadTodos function if available
if (typeof loadTodos === 'function') {
try {
loadTodos();
if (window.todos && window.todos.length) {
todos = window.todos.slice();
console.log('Loaded todos using loadTodos():', todos.length);
}
} catch (e) {
console.error('Error using loadTodos():', e);
}
}
}
// Log the todos we found
console.log('Found todos for calendar:', todos);
// Only add sample data for testing if explicitly requested
// We're not adding sample data by default now to prioritize real tasks
// Generate the calendar HTML
const calendarHTML = generateCalendarHTML(todos);
// Update the calendar container
calendarContainer.innerHTML = calendarHTML;
// Show the modal
calendarModal.style.display = 'flex';
}
// Function to generate the HTML for the calendar modal content
function generateCalendarHTML(todos) {
// Get the current date
const currentDate = new Date();
const currentMonth = currentDate.getMonth();
const currentYear = currentDate.getFullYear();
// Ensure todos is an array
todos = todos || [];
// Debug log the todos
console.log('Generating calendar with todos:', todos.length);
// Generate the calendar HTML for the modal
return `
${generateCalendarDays(currentMonth, currentYear, todos)}
`;
}
// Helper function to get month name
function getMonthName(month) {
const monthNames = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
return monthNames[month];
}
// Function to generate calendar days
function generateCalendarDays(month, year, todos) {
const today = new Date();
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const daysInMonth = lastDay.getDate();
// Adjust day of week to start from Monday (0 = Monday, 6 = Sunday)
let startingDayOfWeek = firstDay.getDay() - 1;
if (startingDayOfWeek === -1) startingDayOfWeek = 6; // Sunday becomes 6
// Get previous month's last days to fill in the first week
const prevMonth = month === 0 ? 11 : month - 1;
const prevMonthYear = month === 0 ? year - 1 : year;
const prevMonthLastDay = new Date(prevMonthYear, prevMonth + 1, 0).getDate();
let calendarHTML = '';
// Previous month's days
for (let i = 0; i < startingDayOfWeek; i++) {
const day = prevMonthLastDay - startingDayOfWeek + i + 1;
calendarHTML += `
`;
}
// Current month's days
for (let day = 1; day <= daysInMonth; day++) {
const date = new Date(year, month, day);
const isToday = date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear();
// Format the date as YYYY-MM-DD for comparison with todos
const formattedDate = formatDateYYYYMMDD(date);
// Filter todos for this day
const todosForDay = todos.filter(todo => {
// Debug log to check date formats
if (day === 1) {
console.log('Todo dates for debugging:', {
id: todo.id,
nextDate: todo.nextDate,
dueDate: todo.dueDate,
formattedDate: formattedDate
});
}
// Normalize date formats for comparison
const todoNextDate = todo.nextDate ? todo.nextDate.substring(0, 10) : null;
const todoDueDate = todo.dueDate ? todo.dueDate.substring(0, 10) : null;
return (
(todoNextDate && todoNextDate === formattedDate) ||
(todoDueDate && todoDueDate === formattedDate)
);
});
// Debug log for this day's todos
if (todosForDay.length > 0) {
console.log(`Todos for ${formattedDate}:`, todosForDay);
}
calendarHTML += `
${day}
${generateTodoItemsHTML(todosForDay, formattedDate)}
`;
}
// Next month's days to complete the grid (6 rows x 7 columns = 42 cells)
const totalCells = 42;
const remainingCells = totalCells - (startingDayOfWeek + daysInMonth);
for (let day = 1; day <= remainingCells; day++) {
calendarHTML += `
`;
}
return calendarHTML;
}
// Helper function to format date as YYYY-MM-DD
function formatDateYYYYMMDD(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
// Function to generate HTML for todo items in a day
function generateTodoItemsHTML(todos, date) {
if (!todos.length) return '';
let html = '';
todos.forEach(todo => {
const isDueToday = todo.dueDate === date;
const isUrgent = todo.urgent >= 5;
const className = isDueToday ? 'todo-item due-today' : (isUrgent ? 'todo-item urgent' : 'todo-item');
// Make the todo item clickable to open the edit modal
html += `
#${todo.id}: ${truncateText(todo.task, 25)}
`;
});
return html;
}
// Helper function to truncate text
function truncateText(text, maxLength) {
if (!text) return '';
return text.length > maxLength ? text.substring(0, maxLength) + '...' : text;
}