diff --git a/data/tasks.json b/data/tasks.json index 3747a16..d1a2033 100644 --- a/data/tasks.json +++ b/data/tasks.json @@ -152,5 +152,156 @@ "subtasks": [], "createdAt": "2025-07-23T04:22:47.898Z", "updatedAt": "2025-07-23T04:22:47.899Z" + }, + { + "id": 6, + "title": "Test", + "description": "Test task", + "status": "pending", + "priority": "medium", + "assignedTo": "" + }, + { + "id": 7, + "title": "Test", + "description": "Test task", + "status": "pending", + "priority": "medium", + "assignedTo": "" + }, + { + "id": 8, + "title": "Test", + "description": "Test task", + "status": "pending", + "priority": "medium", + "assignedTo": "", + "subtasks": [ + { + "id": "8.1", + "title": "Test", + "description": "Test task" + } + ], + "updatedAt": "2025-07-28T01:44:14.526Z" + }, + { + "id": 9, + "title": "Testmmmmm", + "description": "Test taskkkkk", + "status": "pending", + "priority": "medium", + "assignedTo": "", + "dueDate": null, + "subtasks": [ + { + "id": "9.1", + "title": "Testttttt", + "description": "Test taskkkkkmmmm", + "completed": false + }, + { + "id": "9.2", + "title": "Testttt", + "description": "Test task", + "completed": false + }, + { + "id": "9.3", + "title": "Test", + "description": "Test task", + "completed": false + } + ], + "createdAt": "2025-07-29T02:53:22.679Z", + "updatedAt": "2025-07-29T02:53:22.679Z" + }, + { + "id": 10, + "title": "Learn Node.js Fundamentals", + "description": "Complete the Node.js basics course and build a simple server", + "status": "in-progress", + "priority": "high", + "createdBy": { + "id": "", + "name": "Jane Smith", + "email": "john@example.com" + }, + "assignedBy": { + "id": "", + "name": "John Doe", + "email": "jane@example.com" + }, + "dueDate": "2024-01-15", + "assignedTo": "John Doe", + "subtasks": [ + { + "id": "10.1", + "title": "Install Node.js", + "description": "Download and install Node.js on your machine", + "completed": true + }, + { + "id": "10.2", + "title": "Create First Server", + "description": "Build a simple HTTP server using Express.js", + "completed": false + }, + { + "id": "10.3", + "title": "Handle Routes", + "description": "Learn how to create and handle different routes", + "completed": false + }, + { + "id": "10.4", + "title": "Test Subtask", + "description": "This is a test subtask", + "completed": false + } + ], + "createdAt": "2025-07-29T03:30:02.801Z", + "updatedAt": "2025-07-29T03:30:02.802Z" + }, + { + "id": 11, + "title": "Learn Node.js Fundamentals", + "description": "Completeyyyyy the Node.js basics course and build a simple server", + "status": "in-progress", + "priority": "high", + "createdBy": { + "name": "Jane Smith", + "email": "john@example.com" + }, + "assignedBy": { + "name": "John Doehhhh", + "email": "jane@example.com" + }, + "dueDate": "2024-01-15", + "assignedTo": "John Doe", + "subtasks": [ + { + "title": "Install Node.js", + "completed": true, + "description": "Downyyyyload and install Node.js on your machine" + }, + { + "title": "Create yyyFirst Server", + "completed": false, + "description": "Buildyyyy a simple HTTP server using Express.js" + }, + { + "title": "Handle Routes", + "completed": false, + "description": "Learn how to create and handle different routes" + }, + { + "title": "Test Subtask", + "description": "This is a test subtask", + "completed": false + } + ], + "createdAt": "2025-07-29T03:31:43.563Z", + "updatedAt": "2025-08-10T17:27:58.292Z" } ] \ No newline at end of file diff --git a/routes/tasks.js b/routes/tasks.js index b2bcfcb..a5951f7 100644 --- a/routes/tasks.js +++ b/routes/tasks.js @@ -88,6 +88,22 @@ router.get("/tasks", async (req, res) => { (task) => task.status === req.query.status ); } + // Filter by createdBy if provided + if (req.query.createdBy) { + filteredTasks = filteredTasks.filter((task) => + task.createdBy.name + .toLowerCase() + .includes(req.query.createdBy.toLowerCase()) + ); + } + // Filter by assignedBy if provided + if (req.query.assignedBy) { + filteredTasks = filteredTasks.filter((task) => + task.assignedBy.name + .toLowerCase() + .includes(req.query.assignedBy.toLowerCase()) + ); + } // Filter by priority if provided if (req.query.priority) { @@ -153,20 +169,93 @@ router.post("/tasks", async (req, res) => { try { // TODO: Implement task creation // 1. Extract data from req.body (title, description, status, priority, etc.) + const newtask = req.body; // 2. Validate the data using validateTaskData function + const validation = validateTaskData(newtask); + if (!validation.isValid) { + return res.status(400).json({ + success: false, + error: validation.error, + }); + } // 3. Get all existing tasks using getAllTasks() + const tasks = await getAllTasks(); + // 4. Generate a new ID for the task + const newId = tasks.length > 0 ? Math.max(...tasks.map((task) => task.id)) + 1 : 1; + + const subtasks = Array.isArray(newtask.subtasks) + ? newtask.subtasks.map((subtask, index) => ({ + id: `${newId}.${index + 1}`, + title: subtask.title || "", + description: subtask.description || "", + completed: subtask.completed || false, + })) + : []; + const createdBy = + newtask.createdBy && typeof newtask.createdBy === "object" + ? { + id: newId, + name: newtask.createdBy.name || "", + email: newtask.createdBy.email || "", + } + : null; + + const assignedBy = newtask.assignedBy && typeof newtask.assignedBy === "object" + ? { + id: newId, + name: newtask.assignedBy.name || "", + email: newtask.assignedBy.email || "", + } + : null; + // Validate createdBy information + + if (!createdBy || !createdBy.name || !createdBy.email) { + return res.status(400).json({ + success: false, + error: "Missing or invalid createdBy information", + }); + } + // Validate assignedBy information + if (!assignedBy || !assignedBy.name || !assignedBy.email) { + return res.status(400).json({ + success: false, + error: "Missing or invalid assignedBy information", + }); + } + // 5. Create a new task object with all required fields + const createdTask = { + id: newId, + title: newtask.title, + description: newtask.description, + status: newtask.status, + priority: newtask.priority, + createdBy, + assignedBy, + dueDate: newtask.dueDate || null, + assignedTo: newtask.assignedTo || "", + subtasks: subtasks, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }; + // 6. Add the task to the tasks array + tasks.push(createdTask); // 7. Save to file using writeTasks() + await writeTasks(tasks); // 8. Send success response with status 201 + res.status(201).json({ + success: true, + data: createdTask, + }); // Temporary response - remove this when you implement the above - res.status(501).json({ - success: false, - error: - "POST endpoint not implemented yet - implement task creation above", - }); + // res.status(501).json({ + // success: false, + // error: + // "POST endpoint not implemented yet - implement task creation above", + // }); } catch (error) { res.status(500).json({ success: false, @@ -182,19 +271,48 @@ router.put("/tasks/:id", async (req, res) => { try { // TODO: Implement task update // 1. Extract the task ID from req.params + const taskId = req.params.id; // 2. Get the update data from req.body + const updateData = req.body; // 3. Validate the data if status or priority is being updated + + const validation = validateTaskData(updateData); + if (!validation.isValid) { + return res.status(400).json({ + success: false, + error: validation.error, + }); + } + // 4. Get all tasks and find the task by ID + const tasks = await getAllTasks(); + const taskIndex = tasks.findIndex((task) => task.id.toString() === taskId); // 5. Check if task exists, return 404 if not found + if (taskIndex === -1) { + return res.status(404).json({ + success: false, + error: "Task not found", + }); + } // 6. Update the task with new data + const updatedTask = { + ...tasks[taskIndex], + ...updateData, + updatedAt: new Date().toISOString(), + }; + tasks[taskIndex] = updatedTask; // 7. Save to file using writeTasks() + await writeTasks(tasks); // 8. Send success response with the updated task - - // Temporary response - remove this when you implement the above - res.status(501).json({ - success: false, - error: "PUT endpoint not implemented yet - implement task update above", + res.status(200).json({ + success: true, + data: updatedTask, }); + // Temporary response - remove this when you implement the above + // res.status(501).json({ + // success: false, + // error: "PUT endpoint not implemented yet - implement task update above", + // }); } catch (error) { res.status(500).json({ success: false, @@ -209,19 +327,34 @@ router.delete("/tasks/:id", async (req, res) => { try { // TODO: Implement task deletion // 1. Extract the task ID from req.params + const taskId = req.params.id; // 2. Get all tasks and find the task by ID + const tasks = await getAllTasks(); // 3. Check if task exists, return 404 if not found + const taskIndex = tasks.findIndex((task) => task.id.toString() === taskId); + if (taskIndex === -1) { + return res.status(404).json({ + success: false, + error: "Task not found", + }); + } // 4. Store the task before deletion (for response) + const deletedTask = tasks[taskIndex]; // 5. Remove the task from the array + tasks.splice(taskIndex, 1); // 6. Save to file using writeTasks() + await writeTasks(tasks); // 7. Send success response with the deleted task - - // Temporary response - remove this when you implement the above - res.status(501).json({ - success: false, - error: - "DELETE endpoint not implemented yet - implement task deletion above", + res.status(200).json({ + success: true, + data: deletedTask, }); + // Temporary response - remove this when you implement the above + // res.status(501).json({ + // success: false, + // error: + // "DELETE endpoint not implemented yet - implement task deletion above", + // }); } catch (error) { res.status(500).json({ success: false,