${task.name} (${task.duration} mins)
`).join('');
};
const updateProgress = () => {
const calcProgress = (tasks) => {
if (tasks.length === 0) return 0;
const completedCount = tasks.filter(t => completions[todayKey] && completions[todayKey][t.id]).length;
return Math.round((completedCount / tasks.length) * 100);
};
DOM.morningProgressText.textContent = `${calcProgress(morningTasks)}%`;
DOM.eveningProgressText.textContent = `${calcProgress(eveningTasks)}%`;
};
// --- FIRESTORE OPERATIONS ---
const addTask = async (type, name, duration) => {
const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
const collectionPath = `/artifacts/${appId}/users/${userId}/${type}_tasks`;
await addDoc(collection(db, collectionPath), { name, duration: Number(duration), createdAt: new Date() });
};
const deleteTask = async (type, taskId) => {
if (!confirm("Are you sure you want to delete this task?")) return;
const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
await deleteDoc(doc(db, `/artifacts/${appId}/users/${userId}/${type}_tasks`, taskId));
};
const toggleCompletion = async (taskId) => {
const newCompletions = { ...(completions[todayKey] || {}) };
newCompletions[taskId] = !newCompletions[taskId];
const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
const completionRef = doc(db, `/artifacts/${appId}/users/${userId}/completions`, todayKey);
await setDoc(completionRef, newCompletions);
};
// --- PDF EXPORT ---
const downloadPDF = () => {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFontSize(18);
doc.text("My Daily Routine Plan", 14, 22);
doc.autoTable({
startY: 30,
head: [['Morning Routine', 'Duration (mins)']],
body: morningTasks.map(t => [t.name, t.duration]),
theme: 'grid',
headStyles: { fillColor: [79, 70, 229] }
});
doc.autoTable({
startY: doc.lastAutoTable.finalY + 10,
head: [['Evening Routine', 'Duration (mins)']],
body: eveningTasks.map(t => [t.name, t.duration]),
theme: 'grid',
headStyles: { fillColor: [79, 70, 229] }
});
doc.save("daily_routine_plan.pdf");
};
// --- INITIALIZATION ---
document.addEventListener('DOMContentLoaded', async () => {
// Assign DOM elements
Object.assign(DOM, {
currentDate: document.getElementById('current-date'),
morningRoutineList: document.getElementById('morning-routine-list'),
eveningRoutineList: document.getElementById('evening-routine-list'),
morningSettingsList: document.getElementById('morning-settings-list'),
eveningSettingsList: document.getElementById('evening-settings-list'),
addMorningTaskForm: document.getElementById('add-morning-task-form'),
addEveningTaskForm: document.getElementById('add-evening-task-form'),
morningProgressText: document.getElementById('morning-progress-text'),
eveningProgressText: document.getElementById('evening-progress-text'),
morningNoTasks: document.getElementById('morning-no-tasks'),
eveningNoTasks: document.getElementById('evening-no-tasks'),
downloadPdfBtn: document.getElementById('download-pdf-btn'),
loadingMessage: document.getElementById('loading-message')
});
DOM.currentDate.textContent = new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
// Event Listeners
DOM.addMorningTaskForm.addEventListener('submit', (e) => { e.preventDefault(); addTask('morning', document.getElementById('morning-task-name').value, document.getElementById('morning-task-duration').value); e.target.reset(); });
DOM.addEveningTaskForm.addEventListener('submit', (e) => { e.preventDefault(); addTask('evening', document.getElementById('evening-task-name').value, document.getElementById('evening-task-duration').value); e.target.reset(); });
document.getElementById('tab-content-settings').addEventListener('click', (e) => { if (e.target.closest('.delete-task-btn')) { const { taskId, type } = e.target.closest('.delete-task-btn').dataset; deleteTask(type, taskId); } });
document.getElementById('morning-routine-list').addEventListener('change', (e) => { if (e.target.classList.contains('task-checkbox')) toggleCompletion(e.target.dataset.taskId); });
document.getElementById('evening-routine-list').addEventListener('change', (e) => { if (e.target.classList.contains('task-checkbox')) toggleCompletion(e.target.dataset.taskId); });
DOM.downloadPdfBtn.addEventListener('click', downloadPDF);
// Firebase Initialization
try {
const firebaseConfig = JSON.parse(typeof __firebase_config !== 'undefined' ? __firebase_config : '{}');
const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
if (!firebaseConfig.apiKey) throw new Error("Firebase config missing.");
const app = initializeApp(firebaseConfig);
db = getFirestore(app); auth = getAuth(app);
onAuthStateChanged(auth, (user) => {
if (user) {
userId = user.uid;
if (morningTasksUnsubscribe) morningTasksUnsubscribe();
if (eveningTasksUnsubscribe) eveningTasksUnsubscribe();
if (completionsUnsubscribe) completionsUnsubscribe();
const createListener = (type) => {
const q = query(collection(db, `/artifacts/${appId}/users/${userId}/${type}_tasks`), orderBy("createdAt"));
return onSnapshot(q, (snap) => {
if (type === 'morning') morningTasks = snap.docs.map(d => ({ id: d.id, ...d.data() }));
else eveningTasks = snap.docs.map(d => ({ id: d.id, ...d.data() }));
renderRoutines();
});
};
morningTasksUnsubscribe = createListener('morning');
eveningTasksUnsubscribe = createListener('evening');
const completionRef = doc(db, `/artifacts/${appId}/users/${userId}/completions`, todayKey);
completionsUnsubscribe = onSnapshot(completionRef, (docSnap) => {
completions[todayKey] = docSnap.exists() ? docSnap.data() : {};
updateProgress();
});
}
});
if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) await signInWithCustomToken(auth, __initial_auth_token);
else await signInAnonymously(auth);
} catch (error) {
console.error("Init Error:", error);
DOM.loadingMessage.innerHTML = `Could not connect. ${error.message}
`; } lucide.createIcons(); });