Skip to content

Commit e307032

Browse files
committed
Added Next.js BE & FE
1 parent ec7522d commit e307032

File tree

15 files changed

+907
-659
lines changed

15 files changed

+907
-659
lines changed

.github/CODE_OF_CONDUCT.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
4343
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version].
4444

4545
[homepage]: http://contributor-covenant.org
46-
[version]: http://contributor-covenant.org/version/1/4/
47-
---
46+
47+
## [version]: http://contributor-covenant.org/version/1/4/

README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ todo-app-fullstack-nextjs/
162162
Here's a table listing all the API endpoints provided by this application:
163163

164164
| HTTP Method | Endpoint | Description |
165-
|-------------|----------------------|-----------------------------------|
165+
| ----------- | -------------------- | --------------------------------- |
166166
| `POST` | `/api/auth/login` | Log in with username and password |
167167
| `POST` | `/api/auth/register` | Register a new user |
168168
| `GET` | `/api/todos` | Fetch all todos for a user |
@@ -254,8 +254,10 @@ The production build will be served at `http://localhost:3000`.
254254

255255
1. **Visit the Landing Page** (`/landing`): Introduces the app with the option to log in or register.
256256
2. **Authentication**:
257-
- Register: Create a new account via the `/auth/register` page.
258-
- Login: Access your account through the `/auth/login` page.
257+
258+
- Register: Create a new account via the `/auth/register` page.
259+
- Login: Access your account through the `/auth/login` page.
260+
259261
3. **Manage To-Dos**: Access the main to-do list page (`/`) where you can add, edit, and delete to-dos, as well as toggle dark mode.
260262

261263
## 💡 **Notes**
@@ -283,7 +285,7 @@ The tests will run and display the results in the terminal.
283285

284286
## 🚀 **Live Deployment**
285287

286-
The application is deployed live on **Vercel**. You can access it at [https://to-do-app-next-js-fullstack.vercel.app/](https://to-do-app-next-js-fullstack.vercel.app/).
288+
The application is deployed live on **Vercel**. You can access it at [https://todo-app-nextjs-stack.vercel.app/](https://todo-app-nextjs-stack.vercel.app/landing).
287289

288290
## 🐳 **Containerization**
289291

package-lock.json

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"dev": "next dev",
1010
"build": "next build",
1111
"start": "next start",
12-
"lint": "next lint"
12+
"lint": "next lint",
13+
"format": "prettier --write \"**/*.{js,ts,tsx,json,css,html,md}\""
1314
},
1415
"dependencies": {
1516
"@emotion/react": "^11.13.3",
@@ -22,6 +23,7 @@
2223
"better-sqlite3": "^11.3.0",
2324
"jsonwebtoken": "^9.0.2",
2425
"next": "14.2.13",
26+
"prettier": "^3.3.3",
2527
"react": "^18",
2628
"react-dom": "^18",
2729
"react-transition-group": "^4.4.5"

src/app/api/auth/login/route.ts

+25-16
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
// src/app/api/auth/login/route.ts
2-
import { NextResponse } from 'next/server';
2+
import { NextResponse } from "next/server";
33

44
interface User {
5-
id: number;
6-
username: string;
7-
password: string;
5+
id: number;
6+
username: string;
7+
password: string;
88
}
99

1010
const users: User[] = []; // In-memory user storage shared across requests
1111

1212
export async function POST(request: Request) {
13-
const { username, password } = await request.json();
13+
const { username, password } = await request.json();
1414

15-
// Validate input
16-
if (!username || !password) {
17-
return NextResponse.json({ error: 'Username and password are required' }, { status: 400 });
18-
}
15+
// Validate input
16+
if (!username || !password) {
17+
return NextResponse.json(
18+
{ error: "Username and password are required" },
19+
{ status: 400 },
20+
);
21+
}
1922

20-
// Find the user
21-
const user = users.find(user => user.username === username);
23+
// Find the user
24+
const user = users.find((user) => user.username === username);
2225

23-
// Validate user credentials
24-
if (!user || user.password !== password) {
25-
return NextResponse.json({ error: 'Invalid username or password' }, { status: 401 });
26-
}
26+
// Validate user credentials
27+
if (!user || user.password !== password) {
28+
return NextResponse.json(
29+
{ error: "Invalid username or password" },
30+
{ status: 401 },
31+
);
32+
}
2733

28-
return NextResponse.json({ message: 'Login successful', user: { id: user.id, username } }, { status: 200 });
34+
return NextResponse.json(
35+
{ message: "Login successful", user: { id: user.id, username } },
36+
{ status: 200 },
37+
);
2938
}

src/app/api/auth/register/route.ts

+26-17
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,40 @@
11
// src/app/api/auth/register/route.ts
2-
import { NextResponse } from 'next/server';
2+
import { NextResponse } from "next/server";
33

44
interface User {
5-
id: number;
6-
username: string;
7-
password: string;
5+
id: number;
6+
username: string;
7+
password: string;
88
}
99

1010
const users: User[] = []; // In-memory user storage
1111
let userIdCounter = 1;
1212

1313
export async function POST(request: Request) {
14-
const { username, password } = await request.json();
14+
const { username, password } = await request.json();
1515

16-
// Validate input
17-
if (!username || !password) {
18-
return NextResponse.json({ error: 'Username and password are required' }, { status: 400 });
19-
}
16+
// Validate input
17+
if (!username || !password) {
18+
return NextResponse.json(
19+
{ error: "Username and password are required" },
20+
{ status: 400 },
21+
);
22+
}
2023

21-
// Check if user already exists
22-
if (users.find(user => user.username === username)) {
23-
return NextResponse.json({ error: 'User already exists' }, { status: 400 });
24-
}
24+
// Check if user already exists
25+
if (users.find((user) => user.username === username)) {
26+
return NextResponse.json({ error: "User already exists" }, { status: 400 });
27+
}
2528

26-
// Create new user without encryption
27-
const newUser: User = { id: userIdCounter++, username, password };
28-
users.push(newUser);
29+
// Create new user without encryption
30+
const newUser: User = { id: userIdCounter++, username, password };
31+
users.push(newUser);
2932

30-
return NextResponse.json({ message: 'User registered successfully', user: { id: newUser.id, username } }, { status: 201 });
33+
return NextResponse.json(
34+
{
35+
message: "User registered successfully",
36+
user: { id: newUser.id, username },
37+
},
38+
{ status: 201 },
39+
);
3140
}

src/app/api/todo/route.ts

+46-28
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,73 @@
11
// src/app/api/todos/route.ts
2-
import { NextResponse } from 'next/server';
2+
import { NextResponse } from "next/server";
33

44
interface Todo {
5-
id: number;
6-
userId: number;
7-
task: string;
8-
category: string;
9-
completed: boolean;
5+
id: number;
6+
userId: number;
7+
task: string;
8+
category: string;
9+
completed: boolean;
1010
}
1111

1212
let todos: Todo[] = [];
1313
let currentTodoId = 1;
1414

1515
export async function GET(request: Request) {
16-
const userId = request.headers.get('user-id');
17-
if (!userId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
16+
const userId = request.headers.get("user-id");
17+
if (!userId)
18+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
1819

19-
const userTodos = todos.filter(todo => todo.userId === parseInt(userId));
20-
return NextResponse.json(userTodos);
20+
const userTodos = todos.filter((todo) => todo.userId === parseInt(userId));
21+
return NextResponse.json(userTodos);
2122
}
2223

2324
export async function POST(request: Request) {
24-
const { task, category } = await request.json();
25-
const userId = request.headers.get('user-id');
25+
const { task, category } = await request.json();
26+
const userId = request.headers.get("user-id");
2627

27-
if (!userId || !task || !category) {
28-
return NextResponse.json({ error: 'Unauthorized or invalid data' }, { status: 400 });
29-
}
28+
if (!userId || !task || !category) {
29+
return NextResponse.json(
30+
{ error: "Unauthorized or invalid data" },
31+
{ status: 400 },
32+
);
33+
}
3034

31-
const newTodo: Todo = { id: currentTodoId++, userId: parseInt(userId), task, category, completed: false };
32-
todos.push(newTodo);
35+
const newTodo: Todo = {
36+
id: currentTodoId++,
37+
userId: parseInt(userId),
38+
task,
39+
category,
40+
completed: false,
41+
};
42+
todos.push(newTodo);
3343

34-
return NextResponse.json(newTodo, { status: 201 });
44+
return NextResponse.json(newTodo, { status: 201 });
3545
}
3646

3747
export async function PUT(request: Request) {
38-
const { id, completed } = await request.json();
39-
const userId = request.headers.get('user-id');
48+
const { id, completed } = await request.json();
49+
const userId = request.headers.get("user-id");
4050

41-
if (!userId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
51+
if (!userId)
52+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
4253

43-
todos = todos.map(todo => (todo.id === id && todo.userId === parseInt(userId) ? { ...todo, completed } : todo));
44-
return NextResponse.json({ message: 'Task updated successfully' });
54+
todos = todos.map((todo) =>
55+
todo.id === id && todo.userId === parseInt(userId)
56+
? { ...todo, completed }
57+
: todo,
58+
);
59+
return NextResponse.json({ message: "Task updated successfully" });
4560
}
4661

4762
export async function DELETE(request: Request) {
48-
const { id } = await request.json();
49-
const userId = request.headers.get('user-id');
63+
const { id } = await request.json();
64+
const userId = request.headers.get("user-id");
5065

51-
if (!userId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
66+
if (!userId)
67+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
5268

53-
todos = todos.filter(todo => !(todo.id === id && todo.userId === parseInt(userId)));
54-
return NextResponse.json({ message: 'Task deleted successfully' });
69+
todos = todos.filter(
70+
(todo) => !(todo.id === id && todo.userId === parseInt(userId)),
71+
);
72+
return NextResponse.json({ message: "Task deleted successfully" });
5573
}

0 commit comments

Comments
 (0)