Spaces:
Running
Running
| === index.html === | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <meta name="description" content="Simple Todo App - Manage your tasks efficiently"> | |
| <title>Todo App - Manage Your Tasks</title> | |
| <link rel="stylesheet" href="assets/css/styles.css"> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| </head> | |
| <body> | |
| <header class="header"> | |
| <div class="container"> | |
| <nav class="nav"> | |
| <a href="index.html" class="logo">TodoApp</a> | |
| <ul class="nav-list"> | |
| <li class="nav-item"><a href="index.html" class="nav-link active">Home</a></li> | |
| <li class="nav-item"><a href="about.html" class="nav-link">About</a></li> | |
| <li class="nav-item"><a href="contact.html" class="nav-link">Contact</a></li> | |
| </ul> | |
| <button class="mobile-nav-toggle" aria-label="Toggle navigation"> | |
| <span></span> | |
| <span></span> | |
| <span></span> | |
| </button> | |
| </nav> | |
| </div> | |
| </header> | |
| <main class="main"> | |
| <div class="container"> | |
| <section class="todo-section"> | |
| <h1>My Todo List</h1> | |
| <p class="subtitle">Stay organized and productive</p> | |
| <div class="todo-input-section"> | |
| <form id="todo-form" class="todo-form"> | |
| <input type="text" id="todo-input" class="todo-input" placeholder="Add a new task..." required> | |
| <button type="submit" class="add-btn" aria-label="Add todo"> | |
| <i class="fas fa-plus"></i> Add | |
| </button> | |
| </form> | |
| </div> | |
| <div class="filters"> | |
| <button class="filter-btn active" data-filter="all">All</button> | |
| <button class="filter-btn" data-filter="active">Active</button> | |
| <button class="filter-btn" data-filter="completed">Completed</button> | |
| </div> | |
| <div id="todo-list" class="todo-list"> | |
| <!-- Todos will be dynamically added here --> | |
| </div> | |
| <div id="empty-state" class="empty-state"> | |
| <i class="fas fa-clipboard-list"></i> | |
| <p>No tasks yet. Add a task to get started!</p> | |
| </div> | |
| </section> | |
| </div> | |
| </main> | |
| <footer class="footer"> | |
| <div class="container"> | |
| <p>© 2023 Todo App. All rights reserved.</p> | |
| </div> | |
| </footer> | |
| <script src="assets/js/main.js"></script> | |
| </body> | |
| </html> | |
| === about.html === | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <meta name="description" content="About Todo App - Learn about our simple task management solution"> | |
| <title>About - Todo App</title> | |
| <link rel="stylesheet" href="assets/css/styles.css"> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| </head> | |
| <body> | |
| <header class="header"> | |
| <div class="container"> | |
| <nav class="nav"> | |
| <a href="index.html" class="logo">TodoApp</a> | |
| <ul class="nav-list"> | |
| <li class="nav-item"><a href="index.html" class="nav-link">Home</a></li> | |
| <li class="nav-item"><a href="about.html" class="nav-link active">About</a></li> | |
| <li class="nav-item"><a href="contact.html" class="nav-link">Contact</a></li> | |
| </ul> | |
| <button class="mobile-nav-toggle" aria-label="Toggle navigation"> | |
| <span></span> | |
| <span></span> | |
| <span></span> | |
| </button> | |
| </nav> | |
| </div> | |
| </header> | |
| <main class="main"> | |
| <div class="container"> | |
| <section class="about-section"> | |
| <h1>About Todo App</h1> | |
| <div class="about-content"> | |
| <p>Todo App is a simple, intuitive task management application designed to help you stay organized and productive.</p> | |
| <h2>Features</h2> | |
| <ul> | |
| <li>Add new tasks to your list</li> | |
| <li>Mark tasks as complete</li> | |
| <li>Delete tasks you no longer need</li> | |
| <li>Filter tasks by status (all, active, completed)</li> | |
| <li>Responsive design that works on all devices</li> | |
| </ul> | |
| <h2>How to Use</h2> | |
| <ol> | |
| <li>Type your task in the input field</li> | |
| <li>Click "Add" or press Enter to add it to your list</li> | |
| <li>Click the checkbox to mark a task as complete</li> | |
| <li>Use the delete button to remove tasks</li> | |
| <li>Filter your tasks using the filter buttons</li> | |
| </ol> | |
| <p>Our app stores your tasks locally in your browser, so they'll be there when you return!</p> | |
| </div> | |
| </section> | |
| </div> | |
| </main> | |
| <footer class="footer"> | |
| <div class="container"> | |
| <p>© 2023 Todo App. All rights reserved.</p> | |
| </div> | |
| </footer> | |
| <script src="assets/js/main.js"></script> | |
| </body> | |
| </html> | |
| === contact.html === | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <meta name="description" content="Contact Todo App - Get in touch with us"> | |
| <title>Contact - Todo App</title> | |
| <link rel="stylesheet" href="assets/css/styles.css"> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| </head> | |
| <body> | |
| <header class="header"> | |
| <div class="container"> | |
| <nav class="nav"> | |
| <a href="index.html" class="logo">TodoApp</a> | |
| <ul class="nav-list"> | |
| <li class="nav-item"><a href="index.html" class="nav-link">Home</a></li> | |
| <li class="nav-item"><a href="about.html" class="nav-link">About</a></li> | |
| <li class="nav-item"><a href="contact.html" class="nav-link active">Contact</a></li> | |
| </ul> | |
| <button class="mobile-nav-toggle" aria-label="Toggle navigation"> | |
| <span></span> | |
| <span></span> | |
| <span></span> | |
| </button> | |
| </nav> | |
| </div> | |
| </header> | |
| <main class="main"> | |
| <div class="container"> | |
| <section class="contact-section"> | |
| <h1>Contact Us</h1> | |
| <div class="contact-content"> | |
| <p>Have questions or feedback about our Todo App? We'd love to hear from you!</p> | |
| <form class="contact-form"> | |
| <div class="form-group"> | |
| <label for="name">Name</label> | |
| <input type="text" id="name" name="name" required> | |
| </div> | |
| <div class="form-group"> | |
| <label for="email">Email</label> | |
| <input type="email" id="email" name="email" required> | |
| </div> | |
| <div class="form-group"> | |
| <label for="message">Message</label> | |
| <textarea id="message" name="message" rows="5" required></textarea> | |
| </div> | |
| <button type="submit" class="submit-btn">Send Message</button> | |
| </form> | |
| <div class="contact-info"> | |
| <h2>Other Ways to Reach Us</h2> | |
| <p><i class="fas fa-envelope"></i> Email: support@todoapp.com</p> | |
| <p><i class="fas fa-map-marker-alt"></i> Address: 123 Productivity Street, Organization City</p> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| </main> | |
| <footer class="footer"> | |
| <div class="container"> | |
| <p>© 2023 Todo App. All rights reserved.</p> | |
| </div> | |
| </footer> | |
| <script src="assets/js/main.js"></script> | |
| </body> | |
| </html> | |
| === assets/css/styles.css === | |
| /* Reset and Base Styles */ | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| :root { | |
| --primary-color: #4f46e5; | |
| --primary-hover: #4338ca; | |
| --secondary-color: #f3f4f6; | |
| --text-color: #1f2937; | |
| --text-light: #6b7280; | |
| --success-color: #10b981; | |
| --danger-color: #ef4444; | |
| --border-color: #e5e7eb; | |
| --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); | |
| --radius: 8px; | |
| } | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| line-height: 1.6; | |
| color: var(--text-color); | |
| background-color: #f9fafb; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .container { | |
| width: 100%; | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 0 1rem; | |
| } | |
| /* Header Styles */ | |
| .header { | |
| background-color: white; | |
| box-shadow: var(--shadow); | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| } | |
| .nav { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 1rem 0; | |
| } | |
| .logo { | |
| font-size: 1.5rem; | |
| font-weight: 600; | |
| color: var(--primary-color); | |
| text-decoration: none; | |
| } | |
| .nav-list { | |
| display: flex; | |
| list-style: none; | |
| gap: 2rem; | |
| } | |
| .nav-link { | |
| text-decoration: none; | |
| color: var(--text-color); | |
| font-weight: 500; | |
| transition: color 0.3s ease; | |
| position: relative; | |
| } | |
| .nav-link:hover { | |
| color: var(--primary-color); | |
| } | |
| .nav-link.active { | |
| color: var(--primary-color); | |
| } | |
| .nav-link.active::after { | |
| content: ''; | |
| position: absolute; | |
| bottom: -5px; | |
| left: 0; | |
| width: 100%; | |
| height: 2px; | |
| background-color: var(--primary-color); | |
| } | |
| .mobile-nav-toggle { | |
| display: none; | |
| flex-direction: column; | |
| background: none; | |
| border: none; | |
| cursor: pointer; | |
| padding: 0.5rem; | |
| } | |
| .mobile-nav-toggle span { | |
| width: 25px; | |
| height: 3px; | |
| background-color: var(--text-color); | |
| margin: 2px 0; | |
| transition: 0.3s; | |
| } | |
| /* Main Content */ | |
| .main { | |
| flex: 1; | |
| padding: 2rem 0; | |
| } | |
| .todo-section, .about-section, .contact-section { | |
| background: white; | |
| border-radius: var(--radius); | |
| padding: 2rem; | |
| box-shadow: var(--shadow); | |
| margin-bottom: 2rem; | |
| } | |
| .todo-section h1, .about-section h1, .contact-section h1 { | |
| font-size: 2rem; | |
| margin-bottom: 0.5rem; | |
| color: var(--text-color); | |
| } | |
| .subtitle { | |
| color: var(--text-light); | |
| margin-bottom: 2rem; | |
| } | |
| /* Todo Form */ | |
| .todo-input-section { | |
| margin-bottom: 1.5rem; | |
| } | |
| .todo-form { | |
| display: flex; | |
| gap: 0.5rem; | |
| } | |
| .todo-input { | |
| flex: 1; | |
| padding: 0.75rem 1rem; | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius); | |
| font-size: 1rem; | |
| transition: border-color 0.3s; | |
| } | |
| .todo-input:focus { | |
| outline: none; | |
| border-color: var(--primary-color); | |
| box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); | |
| } | |
| .add-btn { | |
| padding: 0.75rem 1.5rem; | |
| background-color: var(--primary-color); | |
| color: white; | |
| border: none; | |
| border-radius: var(--radius); | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: background-color 0.3s; | |
| } | |
| .add-btn:hover { | |
| background-color: var(--primary-hover); | |
| } | |
| /* Filters */ | |
| .filters { | |
| display: flex; | |
| gap: 0.5rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| .filter-btn { | |
| padding: 0.5rem 1rem; | |
| background-color: var(--secondary-color); | |
| border: none; | |
| border-radius: var(--radius); | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| } | |
| .filter-btn:hover { | |
| background-color: #e5e7eb; | |
| } | |
| .filter-btn.active { | |
| background-color: var(--primary-color); | |
| color: white; | |
| } | |
| /* Todo List */ | |
| .todo-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| } | |
| .todo-item { | |
| display: flex; | |
| align-items: center; | |
| padding: 1rem; | |
| background-color: white; | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius); | |
| transition: all 0.3s; | |
| } | |
| .todo-item:hover { | |
| box-shadow: var(--shadow); | |
| } | |
| .todo-checkbox { | |
| margin-right: 1rem; | |
| width: 20px; | |
| height: 20px; | |
| cursor: pointer; | |
| } | |
| .todo-text { | |
| flex: 1; | |
| font-size: 1rem; | |
| } | |
| .todo-item.completed .todo-text { | |
| text-decoration: line-through; | |
| color: var(--text-light); | |
| } | |
| .todo-delete { | |
| background: none; | |
| border: none; | |
| color: var(--danger-color); | |
| cursor: pointer; | |
| font-size: 1.2rem; | |
| padding: 0.25rem; | |
| border-radius: 4px; | |
| transition: background-color 0.3s; | |
| } | |
| .todo-delete:hover { | |
| background-color: #fee2e2; | |
| } | |
| .empty-state { | |
| text-align: center; | |
| padding: 3rem 1rem; | |
| color: var(--text-light); | |
| } | |
| .empty-state i { | |
| font-size: 3rem; | |
| margin-bottom: 1rem; | |
| opacity: 0.5; | |
| } | |
| /* About Page */ | |
| .about-content h2 { | |
| margin: 1.5rem 0 0.5rem; | |
| color: var(--text-color); | |
| } | |
| .about-content ul, .about-content ol { | |
| margin-left: 1.5rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| .about-content li { | |
| margin-bottom: 0.5rem; | |
| } | |
| /* Contact Page */ | |
| .contact-form { | |
| margin: 2rem 0; | |
| } | |
| .form-group { | |
| margin-bottom: 1.5rem; | |
| } | |
| .form-group label { | |
| display: block; | |
| margin-bottom: 0.5rem; | |
| font-weight: 500; | |
| } | |
| .form-group input, .form-group textarea { | |
| width: 100%; | |
| padding: 0.75rem; | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--radius); | |
| font-family: inherit; | |
| font-size: 1rem; | |
| } | |
| .form-group input:focus, .form-group textarea:focus { | |
| outline: none; | |
| border-color: var(--primary-color); | |
| box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); | |
| } | |
| .submit-btn { | |
| padding: 0.75rem 2rem; | |
| background-color: var(--primary-color); | |
| color: white; | |
| border: none; | |
| border-radius: var(--radius); | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: background-color 0.3s; | |
| } | |
| .submit-btn:hover { | |
| background-color: var(--primary-hover); | |
| } | |
| .contact-info { | |
| margin-top: 2rem; | |
| padding-top: 2rem; | |
| border-top: 1px solid var(--border-color); | |
| } | |
| .contact-info p { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| margin-bottom: 0.5rem; | |
| } | |
| /* Footer */ | |
| .footer { | |
| background-color: white; | |
| padding: 1.5rem 0; | |
| text-align: center; | |
| border-top: 1px solid var(--border-color); | |
| margin-top: auto; | |
| } | |
| /* Responsive Design */ | |
| @media (max-width: 768px) { | |
| .nav-list { | |
| position: fixed; | |
| flex-direction: column; | |
| background: white; | |
| top: 70px; | |
| left: 0; | |
| width: 100%; | |
| padding: 1rem; | |
| box-shadow: var(--shadow); | |
| transform: translateY(-100%); | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: all 0.3s ease; | |
| } | |
| .nav-list.active { | |
| transform: translateY(0); | |
| opacity: 1; | |
| pointer-events: all; | |
| } | |
| .mobile-nav-toggle { | |
| display: flex; | |
| } | |
| .todo-form { | |
| flex-direction: column; | |
| } | |
| .filters { | |
| flex-wrap: wrap; | |
| } | |
| } | |
| === assets/js/main.js === | |
| // Todo functionality | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize todos from localStorage | |
| let todos = JSON.parse(localStorage.getItem('todos')) || []; | |
| let currentFilter = 'all'; | |
| // DOM elements | |
| const todoForm = document.getElementById('todo-form'); | |
| const todoInput = document.getElementById('todo-input'); | |
| const todoList = document.getElementById('todo-list'); | |
| const emptyState = document.getElementById('empty-state'); | |
| const filterButtons = document.querySelectorAll('.filter-btn'); | |
| const mobileNavToggle = document.querySelector('.mobile-nav-toggle'); | |
| const navList = document.querySelector('.nav-list'); | |
| // Mobile navigation toggle | |
| if (mobileNavToggle && navList) { | |
| mobileNavToggle.addEventListener('click', function() { | |
| navList.classList.toggle('active'); | |
| this.classList.toggle('active'); | |
| }); | |
| } | |
| // Contact form submission | |
| const contactForm = document.querySelector('.contact-form'); | |
| if (contactForm) { | |
| contactForm.addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| alert('Thank you for your message! This is a demo, so your message wasn\'t actually sent.'); | |
| contactForm.reset(); | |
| }); | |
| } | |
| // If we're not on the index page, don't initialize todo functionality | |
| if (!todoForm) return; | |
| // Render todos based on current filter | |
| function renderTodos() { | |
| todoList.innerHTML = ''; | |
| const filteredTodos = todos.filter(todo => { | |
| if (currentFilter === 'active') return !todo.completed; | |
| if (currentFilter === 'completed') return todo.completed; | |
| return true; | |
| }); | |
| if (filteredTodos.length === 0) { | |
| emptyState.style.display = 'block'; | |
| } else { | |
| emptyState.style.display = 'none'; | |
| filteredTodos.forEach(todo => { | |
| const todoElement = createTodoElement(todo); | |
| todoList.appendChild(todoElement); | |
| }); | |
| } | |
| } | |
| // Create todo element | |
| function createTodoElement(todo) { | |
| const li = document.createElement('li'); | |
| li.className = 'todo-item'; | |
| if (todo.completed) li.classList.add('completed'); | |
| li.innerHTML = ` | |
| <input type="checkbox" class="todo-checkbox" ${todo.completed ? 'checked' : ''}> | |
| <span class="todo-text">${todo.text}</span> | |
| <button class="todo-delete" aria-label="Delete todo"> | |
| <i class="fas fa-trash"></i> | |
| </button> | |
| `; | |
| // Add event listeners | |
| const checkbox = li.querySelector('.todo-checkbox'); | |
| const deleteBtn = li.querySelector('.todo-delete'); | |
| checkbox.addEventListener('change', () => toggleTodoComplete(todo.id)); | |
| deleteBtn.addEventListener('click', () => deleteTodo(todo.id)); | |
| return li; | |
| } | |
| // Add new todo | |
| function addTodo(text) { | |
| const newTodo = { | |
| id: Date.now(), | |
| text: text.trim(), | |
| completed: false | |
| }; | |
| todos.push(newTodo); | |
| saveTodos(); | |
| renderTodos(); | |
| } | |
| // Toggle todo completion | |
| function toggleTodoComplete(id) { | |
| todos = todos.map(todo => { | |
| if (todo.id === id) { | |
| return { ...todo, completed: !todo.completed }; | |
| } | |
| return todo; | |
| }); | |
| saveTodos(); | |
| renderTodos(); | |
| } | |
| // Delete todo | |
| function deleteTodo(id) { | |
| todos = todos.filter(todo => todo.id !== id); | |
| saveTodos(); | |
| renderTodos(); | |
| } | |
| // Save todos to localStorage | |
| function saveTodos() { | |
| localStorage.setItem('todos', JSON.stringify(todos)); | |
| } | |
| // Filter todos | |
| filterButtons.forEach(button => { | |
| button.addEventListener('click', () => { | |
| // Update active filter button | |
| filterButtons.forEach(btn => btn.classList.remove('active')); | |
| button.classList.add('active'); | |
| // Set current filter and re-render | |
| currentFilter = button.dataset.filter; | |
| renderTodos(); | |
| }); | |
| }); | |
| // Form submission | |
| todoForm.addEventListener('submit', e => { | |
| e.preventDefault(); | |
| const text = todoInput.value.trim(); | |
| if (text) { | |
| addTodo(text); | |
| todoInput.value = ''; | |
| } | |
| }); | |
| // Initial render | |
| renderTodos(); | |
| // Highlight current page in navigation | |
| const currentPage = window.location.pathname.split('/').pop() || 'index.html'; | |
| const navLinks = document.querySelectorAll('.nav-link'); | |
| navLinks.forEach(link => { | |
| const linkPage = link.getAttribute('href'); | |
| if (currentPage === linkPage) { | |
| link.classList.add('active'); | |
| } else { | |
| link.classList.remove('active'); | |
| } | |
| }); | |
| }); |