blog-refresh / todo.html
muranja's picture
fix the todo app
a967a04 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo App - Productivity Tracker</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<style>
.task-item {
transition: all 0.3s ease;
}
.task-item:hover {
transform: translateX(5px);
}
.completed {
text-decoration: line-through;
color: #9ca3af;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="flex justify-between items-center mb-10">
<h1 class="text-3xl font-bold text-gray-800">Todo App</h1>
<nav>
<ul class="flex space-x-6">
<li><a href="index.html" class="text-gray-600 hover:text-gray-900">Home</a></li>
<li><a href="productivity.html" class="text-gray-600 hover:text-gray-900">Productivity</a></li>
</ul>
</nav>
</header>
<!-- Todo Section -->
<main class="max-w-2xl mx-auto">
<section class="bg-white rounded-xl shadow-md p-6 mb-8">
<h2 class="text-2xl font-semibold mb-6">My Tasks</h2>
<!-- Add Task Form -->
<form id="taskForm" class="mb-6 flex">
<input
type="text"
id="taskInput"
placeholder="Add a new task..."
class="flex-grow px-4 py-2 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required
>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-r-lg font-medium transition"
>
Add
</button>
</form>
<!-- Task List -->
<div id="taskList" class="space-y-3">
<!-- Tasks will be added here dynamically -->
</div>
<!-- Stats -->
<div class="mt-6 pt-4 border-t border-gray-200 flex justify-between text-sm text-gray-500">
<span id="totalTasks">Total: 0 tasks</span>
<span id="completedTasks">Completed: 0</span>
</div>
</section>
</main>
<!-- Footer -->
<footer class="mt-12 text-center text-gray-500 text-sm">
<p>© 2023 Productivity Tracker. All rights reserved.</p>
</footer>
</div>
<script>
// Initialize Feather icons
feather.replace();
// Todo App Functionality
document.addEventListener('DOMContentLoaded', function() {
const taskForm = document.getElementById('taskForm');
const taskInput = document.getElementById('taskInput');
const taskList = document.getElementById('taskList');
const totalTasksSpan = document.getElementById('totalTasks');
const completedTasksSpan = document.getElementById('completedTasks');
let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
// Render tasks
function renderTasks() {
taskList.innerHTML = '';
if (tasks.length === 0) {
taskList.innerHTML = '<p class="text-gray-500 text-center py-4">No tasks yet. Add your first task!</p>';
updateStats();
return;
}
tasks.forEach((task, index) => {
const taskElement = document.createElement('div');
taskElement.className = `task-item flex items-center justify-between p-3 rounded-lg ${task.completed ? 'bg-green-50' : 'bg-gray-50'}`;
taskElement.innerHTML = `
<div class="flex items-center">
<input
type="checkbox"
${task.completed ? 'checked' : ''}
data-index="${index}"
class="mr-3 h-5 w-5 text-blue-500 rounded focus:ring-blue-400"
>
<span class="${task.completed ? 'completed' : ''}">${task.text}</span>
</div>
<button
data-index="${index}"
class="delete-btn text-red-500 hover:text-red-700"
>
<i data-feather="trash-2" class="w-5 h-5"></i>
</button>
`;
taskList.appendChild(taskElement);
});
// Reinitialize Feather icons
feather.replace();
updateStats();
saveTasks();
}
if (tasks.length === 0) {
taskList.innerHTML = '<p class="text-gray-500 text-center py-4">No tasks yet. Add your first task!</p>';
totalTasksSpan.textContent = 'Total: 0 tasks';
completedTasksSpan.textContent = 'Completed: 0';
return;
}
tasks.forEach((task, index) => {
const taskElement = document.createElement('div');
taskElement.className = `task-item flex items-center justify-between p-3 rounded-lg ${task.completed ? 'bg-green-50' : 'bg-gray-50'}`;
taskElement.innerHTML = `
<div class="flex items-center">
<input
type="checkbox"
${task.completed ? 'checked' : ''}
data-index="${index}"
class="mr-3 h-5 w-5 text-blue-500 rounded focus:ring-blue-400"
>
<span class="${task.completed ? 'completed' : ''}">${task.text}</span>
</div>
<button
data-index="${index}"
class="delete-btn text-red-500 hover:text-red-700"
>
<i data-feather="trash-2" class="w-5 h-5"></i>
</button>
`;
taskList.appendChild(taskElement);
});
// Reinitialize Feather icons
feather.replace();
// Update stats
function updateStats() {
const total = tasks.length;
const completed = tasks.filter(task => task.completed).length;
totalTasksSpan.textContent = `Total: ${total} ${total === 1 ? 'task' : 'tasks'}`;
completedTasksSpan.textContent = `Completed: ${completed}`;
}
// Save tasks to localStorage
function saveTasks() {
localStorage.setItem('tasks', JSON.stringify(tasks));
}
// Load tasks from localStorage
function loadTasks() {
const storedTasks = localStorage.getItem('tasks');
if (storedTasks) {
tasks = JSON.parse(storedTasks);
}
}
// Add task
taskForm.addEventListener('submit', function(e) {
e.preventDefault();
const text = taskInput.value.trim();
if (text) {
tasks.push({
text: text,
completed: false,
createdAt: new Date().toISOString()
});
taskInput.value = '';
renderTasks();
}
});
// Toggle task completion
taskList.addEventListener('change', function(e) {
if (e.target.type === 'checkbox') {
const index = parseInt(e.target.dataset.index);
tasks[index].completed = e.target.checked;
renderTasks();
}
});
// Delete task
taskList.addEventListener('click', function(e) {
if (e.target.closest('.delete-btn')) {
const index = parseInt(e.target.closest('.delete-btn').dataset.index);
tasks.splice(index, 1);
renderTasks();
}
});
// Initialize the app
loadTasks();
renderTasks();
});
</script>
</body>
</html>
=======
// Update stats
function updateStats() {
const total = tasks.length;
const completed = tasks.filter(task => task.completed).length;
totalTasksSpan.textContent = `Total: ${total} ${total === 1 ? 'task' : 'tasks'}`;
completedTasksSpan.textContent = `Completed: ${completed}`;
}
// Save tasks to localStorage
function saveTasks() {
localStorage.setItem('tasks', JSON.stringify(tasks));
}
// Load tasks from localStorage
function loadTasks() {
const storedTasks = localStorage.getItem('tasks');
if (storedTasks) {
tasks = JSON.parse(storedTasks);
}
}
// Add task
taskForm.addEventListener('submit', function(e) {
e.preventDefault();
const text = taskInput.value.trim();
if (text) {
tasks.push({
text: text,
completed: false,
createdAt: new Date().toISOString()
});
taskInput.value = '';
renderTasks();
}
});
// Toggle task completion
taskList.addEventListener('change', function(e) {
if (e.target.type === 'checkbox') {
const index = parseInt(e.target.dataset.index);
tasks[index].completed = e.target.checked;
renderTasks();
}
});
// Delete task
taskList.addEventListener('click', function(e) {
if (e.target.closest('.delete-btn')) {
const index = parseInt(e.target.closest('.delete-btn').dataset.index);
tasks.splice(index, 1);
renderTasks();
}
});
// Initialize the app
loadTasks();
renderTasks();
});
</script>
</body>
</html>
taskForm.addEventListener('submit', function(e) {
e.preventDefault();
const text = taskInput.value.trim();
if (text) {
tasks.push({
text: text,
completed: false,
createdAt: new Date()
});
taskInput.value = '';
renderTasks();
}
});
// Toggle task completion
taskList.addEventListener('change', function(e) {
if (e.target.type === 'checkbox') {
const index = e.target.dataset.index;
tasks[index].completed = e.target.checked;
renderTasks();
}
});
// Delete task
taskList.addEventListener('click', function(e) {
if (e.target.closest('.delete-btn')) {
const index = e.target.closest('.delete-btn').dataset.index;
tasks.splice(index, 1);
renderTasks();
}
});
// Initial render
renderTasks();
});
</script>
</body>
</html>