Skip to content

Commit f8b8dec

Browse files
authored
Merge pull request #11 from Thedevelop3r/dev
Dev
2 parents 74ffb52 + 799e9a6 commit f8b8dec

File tree

10 files changed

+180
-17
lines changed

10 files changed

+180
-17
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,7 @@ docker compose watch
4242
## License
4343

4444
[MIT](https://choosealicense.com/licenses/mit/)
45+
46+
## Permission
47+
You are free to use this code for your own projects, modify it, or publish it anywhere.
48+
please give me credit if you use it. (@Thedevelop3r), thanks.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "modern-todo-app",
2+
"name": "modern-todo-app-backend",
33
"version": "1.0.0",
44
"description": "headless backend for todo application",
55
"main": "server.js",
@@ -12,7 +12,7 @@
1212
"developer": "Bilal Amjad",
1313
"developer-github": "www.github.com/thedevelop3r",
1414
"username": "@thedevelop3r",
15-
"license": "ISC",
15+
"license": "MIT",
1616
"dependencies": {
1717
"bcrypt": "^5.1.1",
1818
"cookie-parser": "^1.4.6",

src/controller/Todo.controller.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { Todo } = require("../models");
1+
const { Todo, Trash } = require("../models");
22

33
class TodoController {
44
constructor() {}
@@ -48,11 +48,13 @@ class TodoController {
4848
if (body.description) parsedBody.description = body.description;
4949
if (body.status) parsedBody.status = body.status;
5050
const updatedTodo = await Todo.findOneAndUpdate({ _id: todoId, ownerId: userId }, parsedBody, { new: true });
51+
5152
return updatedTodo;
5253
}
5354

5455
async destroy({ todoId, userId }) {
5556
const deletedTodo = await Todo.findOneAndDelete({ _id: todoId, ownerId: userId });
57+
await Trash.create({ ...deletedTodo._doc, todoId: todoId });
5658
return deletedTodo;
5759
}
5860
}

src/controller/Trash.controller.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const { Todo, Trash } = require("../models");
2+
3+
class TrashController {
4+
constructor() {}
5+
6+
async getTodos({ limit = 10, page = 1 }, userId) {
7+
try {
8+
const todos = await Trash.find({
9+
ownerId: userId,
10+
})
11+
.limit(limit)
12+
.skip((page - 1) * limit)
13+
.sort({ created_at: -1 });
14+
// TODO: 1 Apply sorting and filters
15+
// provide additional information
16+
const totalPages = Math.ceil((await Trash.countDocuments()) / limit);
17+
const meta = {
18+
totalRecords: await Trash.countDocuments(),
19+
page: page,
20+
limit: limit,
21+
totalPages: totalPages,
22+
};
23+
return { data: todos, meta };
24+
} catch (err) {
25+
return err;
26+
}
27+
}
28+
29+
async getTodoById({ todoId, userId }) {
30+
const todo = await Trash.findOne({ _id: todoId, ownerId: userId });
31+
return todo;
32+
}
33+
34+
async create({ body, userId }) {
35+
body.ownerId = userId;
36+
const newTodo = await Trash.create(body);
37+
return newTodo;
38+
}
39+
40+
async createMany(todos) {
41+
const newTodos = await Trash.insertMany(todos);
42+
return newTodos;
43+
}
44+
45+
async update({ todoId, body, userId }) {
46+
const parsedBody = {};
47+
if (body.title) parsedBody.title = body.title;
48+
if (body.description) parsedBody.description = body.description;
49+
if (body.status) parsedBody.status = body.status;
50+
const updatedTodo = await Trash.findOneAndUpdate({ _id: todoId, ownerId: userId }, parsedBody, { new: true });
51+
52+
return updatedTodo;
53+
}
54+
async recover({ todoId, userId }) {
55+
const deletedTodo = await Trash.findOneAndDelete({ _id: todoId, ownerId: userId });
56+
const recoveredTodo = await Todo.create({ ...deletedTodo._doc, todoId: todoId });
57+
return recoveredTodo;
58+
}
59+
60+
async destroy({ todoId, userId }) {
61+
const deletedTodo = await Trash.findOneAndDelete({ _id: todoId, ownerId: userId });
62+
return deletedTodo;
63+
}
64+
}
65+
66+
module.exports = { TrashController: new TrashController() };

src/controller/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
const { TodoController } = require("./Todo.controller");
21
const { UserController } = require("./User.controller");
2+
const { TodoController } = require("./Todo.controller");
3+
const { TrashController } = require("./Trash.controller");
34

45
module.exports = {
5-
TodoController,
66
UserController,
7+
TodoController,
8+
TrashController,
79
};

src/models/Trash.model.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const { Mongoose } = require("../db.config");
2+
const { Schema, model } = Mongoose;
3+
4+
const trashSchema = new Schema(
5+
{
6+
title: {
7+
required: true,
8+
type: String,
9+
maxlength: 100,
10+
},
11+
todoId: {
12+
type: Schema.Types.ObjectId,
13+
ref: "Todo",
14+
required: true,
15+
},
16+
description: {
17+
type: String,
18+
maxlength: 1500,
19+
},
20+
ownerId: {
21+
type: Schema.Types.ObjectId,
22+
ref: "User",
23+
required: true,
24+
},
25+
status: {
26+
type: String,
27+
enum: ["pending", "progress", "completed"],
28+
default: "pending",
29+
},
30+
createdAt: Date,
31+
updatedAt: Date,
32+
},
33+
{ timestamps: true }
34+
);
35+
36+
const Trash = model("Trash", trashSchema);
37+
38+
module.exports = { Trash };

src/models/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
const { User } = require("./User.model");
22
const { Todo } = require("./Todo.model");
3+
const { Trash } = require("./Trash.model");
34

45
module.exports = {
56
User,
67
Todo,
8+
Trash,
79
};

src/routes/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
const router = require("express").Router();
33
const { userRouter } = require("./user.route");
44
const { todoRouter } = require("./todo.route");
5+
const { trashRouter } = require("./trash.route");
56

67
const { auth } = require("../middleware");
78

89
router.use("/user", userRouter);
910
router.use("/todo", auth, todoRouter);
11+
router.use("/trash", auth, trashRouter);
1012

1113
// export
1214
module.exports = { router: router };

src/routes/todo.route.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ router.get(
1818
asyncTryCatchWrapper(async (req, res) => {
1919
const { id } = req.params;
2020
const userId = req.user._id;
21-
console.log("userId -> ", userId, " get todo -> ", id);
2221
const todo = await TodoController.getTodoById({ todoId: id, userId });
2322
if (!todo) {
2423
res.status(404).json({ message: "Todo not found" });
@@ -34,17 +33,6 @@ router.post(
3433
const { body } = req;
3534
const userId = req.user._id;
3635
const userName = req.user.name;
37-
38-
console.log("user -> ", userName, " created todo -> ", body);
39-
// console.log("userId -> ", userId, " created todo -> ", req);
40-
// const newtodos = [];
41-
// for (let i = 0; i < 1000; i++) {
42-
// const newTodo = { ...body };
43-
// newTodo.ownerId = userId;
44-
// newtodos.push(newTodo);
45-
// }
46-
// await TodoController.createMany(newtodos);
47-
// console.log("thousands of todos created");
4836
const newTodo = await TodoController.create({ body, userId });
4937
res.status(201).json(newTodo);
5038
})

src/routes/trash.route.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const router = require("express").Router();
2+
const { asyncTryCatchWrapper } = require("../wrapper/async-trycatch");
3+
const { TrashController } = require("../controller");
4+
// const { Tools } = require("../utils/tools");
5+
6+
router.get(
7+
"/",
8+
asyncTryCatchWrapper(async (req, res) => {
9+
const { page, limit } = req.query;
10+
const userId = req.user._id;
11+
const { data, meta } = await TrashController.getTodos({ page, limit, limit: limit }, userId);
12+
res.status(200).json({ data, meta });
13+
})
14+
);
15+
16+
router.get(
17+
"/:id",
18+
asyncTryCatchWrapper(async (req, res) => {
19+
const { id } = req.params;
20+
const userId = req.user._id;
21+
const todo = await TrashController.getTodoById({ todoId: id, userId });
22+
if (!todo) {
23+
res.status(404).json({ message: "Todo not found" });
24+
return;
25+
}
26+
res.status(200).json(todo);
27+
})
28+
);
29+
30+
router.put(
31+
"/:id",
32+
asyncTryCatchWrapper(async (req, res) => {
33+
const { id } = req.params;
34+
const { body } = req;
35+
const userId = req.user._id;
36+
const updatedTodo = await TrashController.recover({ todoId: id, userId });
37+
if (!updatedTodo) {
38+
res.status(404).json({ message: "Todo not found" });
39+
return;
40+
}
41+
res.status(200).json(updatedTodo);
42+
})
43+
);
44+
45+
router.delete(
46+
"/:id",
47+
asyncTryCatchWrapper(async (req, res) => {
48+
const { id } = req.params;
49+
const userId = req.user._id;
50+
const deletedTodo = await TrashController.destroy({ todoId: id, userId });
51+
if (!deletedTodo) {
52+
res.status(404).json({ message: "Todo not found" });
53+
return;
54+
}
55+
res.status(200).json(deletedTodo);
56+
})
57+
);
58+
59+
module.exports = { trashRouter: router };

0 commit comments

Comments
 (0)