Skip to content

Commit 617522c

Browse files
committed
added API for other clients to use
1 parent 9a19656 commit 617522c

File tree

10 files changed

+217
-50
lines changed

10 files changed

+217
-50
lines changed

.env

-8
This file was deleted.

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ Database Hosting Provider: Vercel
1515
# References
1616
https://github.com/vercel/next.js/blob/main/examples/next-forms/
1717
https://github.com/vercel/next.js/blob/main/examples/with-postgres/
18+
https://www.prisma.io/docs/orm/more/help-and-troubleshooting/help-articles/vercel-caching-issue
19+
https://www.prisma.io/docs/orm/prisma-client/deployment/serverless/deploy-to-vercel

actions/note.ts

+38-33
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,59 @@
22

33
import { revalidatePath } from "next/cache";
44
import prisma from "@/lib/prisma";
5-
import { list, geById, create, update, remove } from "@/logic/note";
5+
// import { list, geById, create, update, remove } from "@/logic/note";
66

77
export async function getNotes(prevState: any, formData: FormData) {
88
const notes: any = await prisma.note.findMany();
99
return notes;
1010
}
1111
export async function getNoteById(prevState: any, formData: FormData) {
1212
const note: any = await prisma.note.findUnique({
13-
where: { id: parseInt(formData.get("id") as string) }
13+
where: {
14+
id: parseInt(formData.get("id") as string)
15+
}
1416
});
1517
return note;
1618
}
1719
export async function createNote(prevState: any, formData: FormData) {
18-
// try {
19-
// const result: any = await prisma.note.create({
20-
// data: {
21-
// title: formData.get("title") as string,
22-
// content: formData.get("content") as string,
23-
// },
24-
// });
25-
// revalidatePath("/");
26-
// return { pending: false, success: "Creation was successfull", error: "", data: result };
27-
// } catch (err: any) {
28-
// console.error(err.message);
29-
// return { pending: false, error: "Failed to create note" };
30-
// }
31-
const result: any = await create({ title: formData.get("title") as string, content: formData.get("content") as string });
32-
if(result.success) {
20+
/* 1. using try catch block */
21+
try {
22+
const result: any = await prisma.note.create({
23+
data: {
24+
title: formData.get("title") as string,
25+
content: formData.get("content") as string,
26+
},
27+
});
3328
revalidatePath("/");
29+
return { pending: false, success: "Created successfull", data: result }
30+
} catch (err: any) {
31+
return { pending: false, error: "Failed to create | " + err.message }
3432
}
35-
return result;
36-
}
37-
export async function updateNote(prevState: any, formData: FormData) {
38-
// try {
39-
// const note: any = await prisma.note.update({
40-
// data: {
41-
// title: formData.get("title") as string,
42-
// content: formData.get("content") as string,
43-
// },
44-
// where: {
45-
// id: parseInt(formData.get("id") as string)
46-
// },
47-
// });
33+
34+
/* 2. using promise's methods */
35+
// let result: any = await prisma.note.create({
36+
// data: {
37+
// title: formData.get("title") as string,
38+
// content: formData.get("content") as string,
39+
// },
40+
// })
41+
// .then((note: any) => {
42+
// revalidatePath("/");
43+
// return { success: "Created successfully" }
44+
// })
45+
// .catch((err: any) => {
46+
// return { error: `Failed to create | ${err.message}` }
47+
// });
48+
// return result;
49+
50+
/* 3. using logic in different file */
51+
// const result: any = await create({ title: formData.get("title") as string, content: formData.get("content") as string });
52+
// if(result.success) {
4853
// revalidatePath("/");
49-
// return { success: "Updated successfully", data: note };
50-
// } catch (error) {
51-
// return { error: `Failed to update | ${error.message}` };
5254
// }
55+
// return result;
56+
}
57+
export async function updateNote(prevState: any, formData: FormData) {
5358
let result: any = await prisma.note.update({
5459
data: {
5560
title: formData.get("title") as string,

app/api/note/[id]/route.ts

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { NextRequest, NextResponse } from 'next/server';
2+
import prisma from '@/lib/prisma';
3+
4+
// GET /api/note/:id
5+
export async function GET(request : NextRequest, { params }: { params: { id: number } }) {
6+
const note: any = await prisma.note.findUniqueOrThrow({
7+
where: {
8+
id: Number(params.id),
9+
},
10+
})
11+
.then((newNote) => {
12+
return NextResponse.json({ success: true, note: newNote }, { status: 200 });
13+
})
14+
.catch((error: any) => {
15+
return NextResponse.json({ error: error }, { status: 500 });
16+
});
17+
return note;
18+
}
19+
20+
// UPDATE /api/note/:id
21+
export async function PUT(req: NextRequest, { params }: { params: { id: number } }) {
22+
const body = await req.json();
23+
24+
const result = await prisma.note.update({
25+
data: {
26+
title: body.title,
27+
content: body.content
28+
},
29+
where: {
30+
id: Number(params.id),
31+
},
32+
})
33+
.then((updatedNote) => {
34+
return NextResponse.json({ success: true, note: updatedNote}, { status: 200 });
35+
})
36+
.catch((error) => {
37+
return NextResponse.json({ error: error }, { status: 500 });
38+
});
39+
return result;
40+
}
41+
42+
// DELETE /api/note/:id
43+
export async function DELETE(request : NextRequest, { params }: { params: { id: number } }) {
44+
const result = await prisma.note.delete({
45+
where: {
46+
id: Number(params.id),
47+
},
48+
})
49+
.then((deletedNote) => {
50+
return NextResponse.json({ success: true }, { status: 200 });
51+
})
52+
.catch((error) => {
53+
return NextResponse.json({ error: error }, { status: 500 });
54+
});
55+
return result;
56+
}

app/api/note/route.ts

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// import type { NextApiRequest, NextApiResponse } from 'next';
2+
import { NextRequest, NextResponse } from 'next/server';
3+
import prisma from '@/lib/prisma';
4+
// import { type Note, list, geById, create, update, remove } from "@/logic/note";
5+
6+
// GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, 405 Method Not Allowed
7+
8+
// export default async function handler(
9+
// req: NextApiRequest,
10+
// res: NextApiResponse<Note[] | string>,
11+
// ) {
12+
// console.log("handler", req.method);
13+
//
14+
// switch (req.method) {
15+
// case "GET":
16+
// return res.status(200).json(await list());
17+
// case "POST":
18+
// return res.status(201).json(await create(req.body));
19+
// case "PUT":
20+
// const updated = await update(req.body);
21+
// return res.status(updated.length > 0 ? 200 : 404).json(updated);
22+
// case "DELETE":
23+
// const removed = await remove(req.body);
24+
// return res.status(removed.length > 0 ? 204 : 404).end();
25+
// default:
26+
// return res.status(405).send("Method Not Allowed");
27+
// }
28+
// }
29+
30+
// get
31+
export async function GET(request: NextRequest) {
32+
const searchParams = request.nextUrl.searchParams;
33+
const id = searchParams.get('id');
34+
let response: NextResponse;
35+
36+
if(id) {
37+
response = await prisma.note.findUniqueOrThrow({
38+
where: { id: Number(id) },
39+
})
40+
.then((note) => {
41+
return NextResponse.json({ success: true, note: note }, { status: 200 });
42+
})
43+
.catch((error) => {
44+
return NextResponse.json({ error: error }, { status: 500 });
45+
});
46+
} else {
47+
response = await prisma.note.findMany()
48+
.then((notes) => {
49+
return NextResponse.json({ success: true, notes: notes }, { status: 200 });
50+
})
51+
.catch((error) => {
52+
return NextResponse.json({ error: error }, { status: 500 });
53+
});
54+
}
55+
56+
return response;
57+
}
58+
// create
59+
export async function POST(request: NextRequest) {
60+
const body = await request.json();
61+
62+
const newNote = await prisma.note.create({ data: body })
63+
.then((note) => {
64+
// res.status(201).json(note);
65+
return new Response(JSON.stringify({ success: true, note: note }), {
66+
status: 200,
67+
headers: { "Content-Type": "application/json" },
68+
});
69+
})
70+
.catch((error) => {
71+
return new Response(JSON.stringify({ error: error }), {
72+
status: 500,
73+
headers: { "Content-Type": "application/json" },
74+
});
75+
});
76+
77+
return newNote;
78+
}
79+
// update
80+
export async function PUT(request: NextRequest) {
81+
const body = await request.json();
82+
const { id, title, content } = body;
83+
84+
const result = await prisma.note.update({
85+
data: { title: title, content: content },
86+
where: { id: id },
87+
})
88+
.then((note) => {
89+
return NextResponse.json({ success: true, note: note }, { status: 200 });
90+
})
91+
.catch((error) => {
92+
return NextResponse.json({ error: error }, { status: 500 });
93+
});
94+
return result;
95+
}
96+
// delete
97+
export async function DELETE(request: NextRequest) {
98+
const body = await request.json();
99+
100+
const result = await prisma.note.delete({
101+
where: { id: body.id },
102+
})
103+
.then((note) => {
104+
return NextResponse.json({ success: true, note: note }, { status: 200 });
105+
})
106+
.catch((error) => {
107+
return NextResponse.json({ error: error }, { status: 500 });
108+
});
109+
return result;
110+
}

app/styles/globals.css

+6-6
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ body {
2727
}
2828
}
2929

30+
/*
3031
input {
3132
@apply p-1;
3233
}
3334
textarea {
3435
@apply p-1;
35-
}
36+
} */
3637
button {
37-
@apply bg-neutral-700 border rounded p-2 disabled:cursor-not-allowed; /* gray neutral slate zinc */
38+
@apply bg-neutral-700 border rounded p-2 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed; /* gray neutral slate zinc */
39+
}
40+
button[aria-disabled="true"], button:disabled {
41+
@apply bg-neutral-500;
3842
}
39-
40-
/* button[aria-disabled="true"] {
41-
@apply bg-neutral-400;
42-
} */
4343

4444
/* button {
4545
color: white;

components/NoteList.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default async function NoteList() {
2121
const noteItems: any = notes.map((note: Note) => <NoteItem key={note.id} note={note} />);
2222

2323
return (
24-
<div className='p-4 grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3'>
24+
<div className='grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3'>
2525
{noteItems}
2626
</div>
2727
);

components/NoteModal.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const initialState = {
1414
function SubmitButton() {
1515
const { action, data, method, pending }: any = useFormStatus();
1616
return (
17-
<button type="submit" aria-disabled={pending}>
17+
<button type="submit" disabled={pending}>
1818
Create
1919
</button>
2020
);

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"start": "next start",
99
"lint": "next lint",
1010
"postinstall": "prisma generate",
11+
"next-build": "next build",
12+
"prisma-generate": "prisma generate",
1113
"prisma:generate": "npx prisma generate",
1214
"prisma:migrate": "npx prisma migrate dev --name init",
1315
"prisma:db-push": "npx prisma db push",

prisma/schema.prisma

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ datasource db {
1313
// url = env("DATABASE_URL")
1414
// url = env("POSTGRES_URL")
1515
url = env("POSTGRES_PRISMA_URL") // uses connection pooling
16-
// directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
16+
// url = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
1717
}
1818

1919
model Note {

0 commit comments

Comments
 (0)