Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
8 views

Demo Code for Task Manager App using HTML,CSS and Modern JavaScrip concepts

The document outlines a demo code for a Task Manager App built using HTML, CSS, and Modern JavaScript concepts. It includes a structured layout with a form for adding tasks, task management functionalities, and error handling through various JavaScript modules. The app allows users to create, complete, and delete tasks while storing them in local storage.

Uploaded by

kavya.jagtap04
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Demo Code for Task Manager App using HTML,CSS and Modern JavaScrip concepts

The document outlines a demo code for a Task Manager App built using HTML, CSS, and Modern JavaScript concepts. It includes a structured layout with a form for adding tasks, task management functionalities, and error handling through various JavaScript modules. The app allows users to create, complete, and delete tasks while storing them in local storage.

Uploaded by

kavya.jagtap04
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

Lab-2 Day-3

Problem Solving & Doubt Clearing : Electives III - Modern JavaScript From
The Beginning 2.0 (2024)

Demo Code for Task Manager App using HTML,CSS and Modern JavaScrip concepts

Time:30 mins

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modern Task Manager</title>
<style>
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--danger-color: #e74c3c;
--background-color: #f5f6fa;
}

*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Segoe UI', sans-serif;
background-color: var(--background-color);
line-height: 1.6;
}

.container {
max-width: 800px;
margin: 2rem auto;
padding: 0 1rem;
}

.header {
text-align: center;
margin-bottom: 2rem;
}

.task-form {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 2rem;
}

.form-group {
margin-bottom: 1rem;
}

.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
}

.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1rem;
}

.btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
transition: opacity 0.2s;
}

.btn:hover {
opacity: 0.9;
}

.btn-primary {
background-color: var(--primary-color);
color: white;
}

.btn-danger {
background-color: var(--danger-color);
color: white;
}

.task-list {
display: grid;
gap: 1rem;
}

.task-item {
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
display: grid;
gap: 0.5rem;
opacity: 1;
transition: opacity 0.3s;
}

.task-item.completed {
opacity: 0.7;
}

.task-item h3 {
margin: 0;
color: var(--primary-color);
}

.task-actions {
display: flex;
gap: 0.5rem;
}

.loading {
text-align: center;
padding: 2rem;
}
.error {
color: var(--danger-color);
padding: 1rem;
background: rgba(231, 76, 60, 0.1);
border-radius: 4px;
margin-bottom: 1rem;
}
</style>
</head>
<body>
<div class="container">
<header class="header">
<h1>Task Manager</h1>
</header>

<form id="taskForm" class="task-form">


<div class="form-group">
<label for="taskTitle">Title</label>
<input type="text" id="taskTitle" required>
</div>
<div class="form-group">
<label for="taskDescription">Description</label>
<textarea id="taskDescription" rows="3"></textarea>
</div>
<div class="form-group">
<label for="taskPriority">Priority</label>
<select id="taskPriority">
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Add Task</button>
</form>

<div id="errorContainer"></div>
<div id="taskList" class="task-list"></div>
</div>

<script type="module">
// ES Modules
import { TaskManager } from './modules/TaskManager.js';
import { StorageService } from './modules/StorageService.js';
import { UIManager } from './modules/UIManager.js';
import { ValidationService } from './modules/ValidationService.js';

// Main application class


class App {
constructor() {
this.storageService = new StorageService();
this.taskManager = new TaskManager(this.storageService);
this.uiManager = new UIManager();
this.validationService = new ValidationService();

this.init();
}

async init() {
try {
// Initialize observers
this.setupIntersectionObserver();

// Load initial tasks


await this.loadTasks();

// Setup event listeners


this.setupEventListeners();
} catch (error) {
this.handleError(error);
}
}

setupIntersectionObserver() {
const options = {
root: null,
threshold: 0.1
};

const observer = new IntersectionObserver((entries) => {


entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, options);

// Observe task items


document.querySelectorAll('.task-item').forEach(item => {
observer.observe(item);
});
}

async loadTasks() {
const tasks = await this.taskManager.getAllTasks();
this.uiManager.renderTasks(tasks);
}

setupEventListeners() {
// Event delegation for task list
document.getElementById('taskList').addEventListener('click', async (e) => {
const taskId = e.target.closest('.task-item')?.dataset.id;

if (!taskId) return;

if (e.target.matches('.btn-complete')) {
await this.toggleTaskComplete(taskId);
} else if (e.target.matches('.btn-delete')) {
await this.deleteTask(taskId);
}
});

// Form submission
document.getElementById('taskForm').addEventListener('submit', async (e) => {
e.preventDefault();
await this.handleTaskSubmission(e);
});
}

async handleTaskSubmission(e) {
try {
const formData = new FormData(e.target);
const taskData = Object.fromEntries(formData.entries());

// Validate form data


if (!this.validationService.validateTask(taskData)) {
throw new Error('Invalid task data');
}

// Create new task


const task = await this.taskManager.createTask(taskData);
this.uiManager.addTaskToList(task);
e.target.reset();
} catch (error) {
this.handleError(error);
}
}

async toggleTaskComplete(taskId) {
try {
const updatedTask = await this.taskManager.toggleTaskComplete(taskId);
this.uiManager.updateTaskUI(updatedTask);
} catch (error) {
this.handleError(error);
}
}

async deleteTask(taskId) {
try {
await this.taskManager.deleteTask(taskId);
this.uiManager.removeTaskFromUI(taskId);
} catch (error) {
this.handleError(error);
}
}

handleError(error) {
console.error('Application Error:', error);
this.uiManager.showError(error.message);
}
}

// Initialize app
new App();
</script>

<!-- Module: TaskManager.js -->


<script type="module">
export class TaskManager {
constructor(storageService) {
this.storageService = storageService;
}

async getAllTasks() {
try {
return await this.storageService.getTasks();
} catch (error) {
throw new Error('Failed to fetch tasks');
}
}

async createTask({ title, description, priority }) {


const task = {
id: Date.now().toString(),
title,
description,
priority,
completed: false,
createdAt: new Date().toISOString()
};

await this.storageService.saveTask(task);
return task;
}

async toggleTaskComplete(taskId) {
const task = await this.storageService.getTask(taskId);
task.completed = !task.completed;
await this.storageService.updateTask(task);
return task;
}

async deleteTask(taskId) {
await this.storageService.deleteTask(taskId);
}
}
</script>

<!-- Module: StorageService.js -->


<script type="module">
export class StorageService {
constructor() {
this.STORAGE_KEY = 'taskManager_tasks';
}

async getTasks() {
const tasks = localStorage.getItem(this.STORAGE_KEY);
return tasks ? JSON.parse(tasks) : [];
}
async getTask(taskId) {
const tasks = await this.getTasks();
return tasks.find(task => task.id === taskId);
}

async saveTask(task) {
const tasks = await this.getTasks();
tasks.push(task);
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(tasks));
}

async updateTask(updatedTask) {
const tasks = await this.getTasks();
const index = tasks.findIndex(task => task.id === updatedTask.id);
if (index !== -1) {
tasks[index] = updatedTask;
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(tasks));
}
}

async deleteTask(taskId) {
const tasks = await this.getTasks();
const filteredTasks = tasks.filter(task => task.id !== taskId);
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(filteredTasks));
}
}
</script>

<!-- Module: UIManager.js -->


<script type="module">
export class UIManager {
constructor() {
this.taskList = document.getElementById('taskList');
this.errorContainer = document.getElementById('errorContainer');
}

renderTasks(tasks) {
this.taskList.innerHTML = tasks.map(task => this.createTaskHTML(task)).join('');
}

createTaskHTML(task) {
return `
<div class="task-item ${task.completed ? 'completed' : ''}" data-id="${task.id}">
<h3>${task.title}</h3>
<p>${task.description}</p>
<div class="task-meta">
<span class="priority ${task.priority}">${task.priority}</span>
<span class="date">${new Date(task.createdAt).toLocaleDateString()}</span>
</div>
<div class="task-actions">
<button class="btn btn-primary btn-complete">
${task.completed ? 'Undo' : 'Complete'}
</button>
<button class="btn btn-danger btn-delete">Delete</button>
</div>
</div>
`;
}

addTaskToList(task) {
this.taskList.insertAdjacentHTML('afterbegin', this.createTaskHTML(task));
}

updateTaskUI(task) {
const taskElement = this.taskList.querySelector(`[data-id="${task.id}"]`);
if (taskElement) {
taskElement.outerHTML = this.createTaskHTML(task);
}
}

removeTaskFromUI(taskId) {
const taskElement = this.taskList.querySelector(`[data-id="${taskId}"]`);
if (taskElement) {
taskElement.remove();
}
}

showError(message) {
this.errorContainer.innerHTML = `
<div class="error">
${message}
</div>
`;
setTimeout(() => {
this.errorContainer.innerHTML = '';
}, 3000);
}
}
</script>

<!-- Module: ValidationService.js -->


<script type="module">
export class ValidationService {
validateTask(taskData) {
const { title, description, priority } = taskData;

if (!title || title.trim().length < 3) {


throw new Error('Title must be at least 3 characters long');
}

if (!description || description.trim().length < 5) {


throw new Error('Description must be at least 5 characters long');
}

if (!['low', 'medium', 'high'].includes(priority)) {


throw new Error('Invalid priority level');
}

return true;
}
}
</script>
</body>
</html>

You might also like