// ===== Task Manager Frontend Application ===== const API_BASE = '/api'; let tasks = []; let currentFilter = 'all'; // ===== DOM Elements ===== const taskList = document.getElementById('task-list'); const emptyState = document.getElementById('empty-state'); const loadingState = document.getElementById('loading-state'); const addTaskForm = document.getElementById('add-task-form'); const taskTitleInput = document.getElementById('task-title'); const taskDescInput = document.getElementById('task-description'); const filterTabs = document.querySelectorAll('.filter-tab'); const toast = document.getElementById('toast'); // ===== API Functions ===== async function apiRequest(url, options = {}) { try { const response = await fetch(`${API_BASE}${url}`, { headers: { 'Content-Type': 'application/json' }, ...options, }); if (!response.ok) { const err = await response.json().catch(() => ({})); throw new Error(err.error || `HTTP ${response.status}`); } return await response.json(); } catch (err) { if (err.name === 'TypeError') { throw new Error('Cannot connect to server. Is the API running?'); } throw err; } } async function fetchTasks() { const data = await apiRequest('/tasks'); tasks = data.tasks || []; // Update source indicator const sourceEl = document.querySelector('#stat-source .stat-value'); if (sourceEl) { sourceEl.textContent = data.source === 'cache' ? '⚡ Cache' : '🗄️ DB'; } return tasks; } async function createTask(title, description) { const data = await apiRequest('/tasks', { method: 'POST', body: JSON.stringify({ title, description }), }); return data.task; } async function updateTask(id, updates) { const data = await apiRequest(`/tasks/${id}`, { method: 'PUT', body: JSON.stringify(updates), }); return data.task; } async function deleteTask(id) { await apiRequest(`/tasks/${id}`, { method: 'DELETE' }); } // ===== UI Rendering ===== function getFilteredTasks() { switch (currentFilter) { case 'active': return tasks.filter(t => !t.completed); case 'completed': return tasks.filter(t => t.completed); default: return tasks; } } function formatDate(dateStr) { const date = new Date(dateStr); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); } function renderTasks() { const filtered = getFilteredTasks(); // Update stats const total = tasks.length; const completed = tasks.filter(t => t.completed).length; const active = total - completed; document.querySelector('#stat-total .stat-value').textContent = total; document.querySelector('#stat-active .stat-value').textContent = active; document.querySelector('#stat-completed .stat-value').textContent = completed; // Show/hide states loadingState.style.display = 'none'; if (filtered.length === 0) { taskList.innerHTML = ''; emptyState.style.display = 'block'; if (tasks.length > 0) { emptyState.querySelector('p').textContent = `No ${currentFilter} tasks.`; } else { emptyState.querySelector('p').textContent = 'No tasks yet. Add your first task above!'; } return; } emptyState.style.display = 'none'; taskList.innerHTML = filtered.map(task => `