${!isCompleted ? `${status}` : ''}
${!isCompleted ? `` : ''}
`;
return div;
};
/**
* Determines the status and corresponding color of a reminder based on its due date.
* @param {string} dueDateString - The ISO string of the due date.
* @returns {object} - An object containing the status text and border color class.
*/
const getReminderStatus = (dueDateString) => {
const now = new Date();
const dueDate = new Date(dueDateString);
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const dueDay = new Date(dueDate.getFullYear(), dueDate.getMonth(), dueDate.getDate());
if (dueDate < now) {
return { status: 'Overdue', statusColor: 'border-red-500' };
} else if (dueDay.getTime() === today.getTime()) {
return { status: 'Due Today', statusColor: 'border-yellow-500' };
} else {
return { status: 'Upcoming', statusColor: 'border-blue-500' };
}
};
// --- EVENT HANDLERS & LOGIC ---
/**
* Handles the submission of the 'Add Reminder' form.
* @param {Event} e - The form submission event.
*/
const handleAddReminder = (e) => {
e.preventDefault();
const title = document.getElementById('title').value;
const description = document.getElementById('description').value;
const dueDate = document.getElementById('due-date').value;
const dueTime = document.getElementById('due-time').value;
const priority = document.getElementById('priority').value;
const recurrence = document.getElementById('recurrence').value;
// Combine date and time for a full ISO string
const fullDueDate = new Date(`${dueDate}T${dueTime}`);
const newReminder = {
id: Date.now().toString(), // Simple unique ID
title,
description,
dueDate: fullDueDate.toISOString(),
priority,
recurrence,
};
reminders.push(newReminder);
saveReminders();
renderReminders();
addReminderForm.reset(); // Clear the form
showTab(0); // Switch to dashboard view after adding
};
/**
* Marks a reminder as complete and moves it to the completed list.
* @param {string} id - The ID of the reminder to complete.
*/
window.markAsComplete = (id) => {
const index = reminders.findIndex(r => r.id === id);
if (index > -1) {
const [completed] = reminders.splice(index, 1);
completedReminders.unshift(completed); // Add to the top of the completed list
saveReminders();
renderAll();
}
};
/**
* Deletes a reminder from either the active or completed list.
* @param {string} id - The ID of the reminder to delete.
* @param {boolean} isCompleted - Flag to check which list to delete from.
*/
window.deleteReminder = (id, isCompleted) => {
if (isCompleted) {
completedReminders = completedReminders.filter(r => r.id !== id);
} else {
reminders = reminders.filter(r => r.id !== id);
}
saveReminders();
renderAll();
};
// --- TAB NAVIGATION ---
/**
* Shows a specific tab and hides others.
* @param {number} tabIndex - The index of the tab to show.
*/
window.showTab = (tabIndex) => {
// Ensure index is within bounds
if (tabIndex < 0 || tabIndex >= tabs.length) return;
currentTab = tabIndex;
// Update tab buttons styling
tabs.forEach((tab, index) => {
if (index === tabIndex) {
tab.classList.add('tab-active');
tab.classList.remove('text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
} else {
tab.classList.remove('tab-active');
tab.classList.add('text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
}
});
// Show/hide tab content
tabContents.forEach((content, index) => {
if (index === tabIndex) {
content.classList.remove('hidden');
} else {
content.classList.add('hidden');
}
});
updateNavButtons();
};
/**
* Updates the visibility and state of Next/Previous buttons.
*/
const updateNavButtons = () => {
prevButton.disabled = currentTab === 0;
nextButton.disabled = currentTab === tabs.length - 1;
prevButton.classList.toggle('opacity-50', prevButton.disabled);
nextButton.classList.toggle('opacity-50', nextButton.disabled);
};
// --- PDF DOWNLOAD FUNCTIONALITY ---
/**
* Generates and downloads a PDF of the active reminders.
*/
const downloadPDF = () => {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFontSize(18);
doc.text("Your Reminders List", 14, 22);
doc.setFontSize(11);
doc.setTextColor(100);
doc.text(`Generated on: ${new Date().toLocaleDateString()}`, 14, 29);
const tableColumn = ["Title", "Due Date", "Priority", "Status"];
const tableRows = [];
reminders.forEach(reminder => {
const formattedDate = new Date(reminder.dueDate).toLocaleDateString('en-US', {
month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit'
});
const { status } = getReminderStatus(reminder.dueDate);
const reminderData = [
reminder.title,
formattedDate,
reminder.priority,
status
];
tableRows.push(reminderData);
});
doc.autoTable({
head: [tableColumn],
body: tableRows,
startY: 35,
theme: 'grid',
headStyles: { fillColor: [59, 130, 246] }, // blue-500
});
doc.save("smart_reminders.pdf");
};
// --- INITIALIZATION ---
// Attach event listeners
addReminderForm.addEventListener('submit', handleAddReminder);
prevButton.addEventListener('click', () => showTab(currentTab - 1));
nextButton.addEventListener('click', () => showTab(currentTab + 1));
pdfDownloadButton.addEventListener('click', downloadPDF);
// Initial setup
loadReminders();
renderAll();
showTab(0); // Show the first tab by default
});
