Skip to content

Commit 68f44ab

Browse files
committed
use astro actions
1 parent d71f7a5 commit 68f44ab

File tree

8 files changed

+499
-140
lines changed

8 files changed

+499
-140
lines changed

apps/0-json-server/db.json

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4333,20 +4333,6 @@
43334333
"name": "ex eaque eum natus",
43344334
"email": "[email protected]",
43354335
"body": "perspiciatis quis doloremque\nveniam nisi eos velit sed\nid totam inventore voluptatem laborum et eveniet\naut aut aut maxime quia temporibus ut omnis"
4336-
},
4337-
{
4338-
"body": "lksfds",
4339-
"email": "[email protected]",
4340-
"name": "User",
4341-
"postId": 1,
4342-
"id": 501
4343-
},
4344-
{
4345-
"body": "asfasf",
4346-
"email": "[email protected]",
4347-
"name": "User",
4348-
"postId": 1,
4349-
"id": 502
43504336
}
43514337
]
43524338
}

apps/4-streaming/4-4-astro-server-islands/astro.config.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ import { defineConfig } from "astro/config";
33

44
import tailwindcss from "@tailwindcss/vite";
55

6+
import vercel from "@astrojs/vercel";
7+
68
// https://astro.build/config
79
export default defineConfig({
810
vite: {
911
plugins: [tailwindcss()],
1012
},
13+
1114
output: "server",
12-
});
15+
adapter: vercel(),
16+
});

apps/4-streaming/4-4-astro-server-islands/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"astro": "astro"
1010
},
1111
"dependencies": {
12+
"@astrojs/vercel": "^8.0.7",
1213
"@tailwindcss/vite": "^4.0.7",
1314
"astro": "^5.3.0",
1415
"tailwindcss": "^4.0.7"
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { defineAction } from "astro:actions";
2+
import { z } from "astro:schema";
3+
4+
export const server = {
5+
addComment: defineAction({
6+
accept: "form",
7+
input: z.object({
8+
postId: z.string(),
9+
text: z.string(),
10+
}),
11+
handler: async ({ postId, text }) => {
12+
console.log({ postId, text });
13+
try {
14+
const newComment = {
15+
body: text,
16+
17+
name: "User",
18+
postId: Number(postId),
19+
};
20+
21+
const response = await fetch("http://localhost:3300/comments", {
22+
method: "POST",
23+
headers: {
24+
"Content-Type": "application/json",
25+
},
26+
body: JSON.stringify(newComment),
27+
});
28+
29+
if (!response.ok) {
30+
throw new Error("Failed to create comment");
31+
}
32+
33+
return {
34+
success: true,
35+
};
36+
} catch (error) {
37+
console.error("Error creating comment:", error);
38+
return {
39+
success: false,
40+
error: "Error creating comment",
41+
};
42+
}
43+
},
44+
}),
45+
46+
deleteComment: defineAction({
47+
accept: "form",
48+
input: z.object({
49+
commentId: z.string(),
50+
postId: z.string(),
51+
}),
52+
handler: async ({ commentId }) => {
53+
try {
54+
const response = await fetch(
55+
`http://localhost:3300/comments/${commentId}`,
56+
{
57+
method: "DELETE",
58+
}
59+
);
60+
61+
if (!response.ok) {
62+
throw new Error("Failed to delete comment");
63+
}
64+
65+
return {
66+
success: true,
67+
};
68+
} catch (error) {
69+
console.error("Error deleting comment:", error);
70+
return {
71+
success: false,
72+
error: "Error deleting comment",
73+
};
74+
}
75+
},
76+
}),
77+
};

apps/4-streaming/4-4-astro-server-islands/src/components/Comments.astro

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ interface Props {
88
const { postId } = Astro.props;
99
1010
// Fetch comments for this post with artificial delay
11-
await new Promise(resolve => setTimeout(resolve, 3000));
11+
await new Promise((resolve) => setTimeout(resolve, 1000));
1212
const commentsResponse = await fetch(
1313
`http://localhost:3300/posts/${postId}/comments`,
1414
{
1515
headers: {
16-
'Cache-Control': 'public, max-age=60, stale-while-revalidate=30'
17-
}
16+
"Cache-Control": "public, max-age=60, stale-while-revalidate=30",
17+
},
1818
}
1919
);
2020
const comments = (await commentsResponse.json()) as IComment[];
@@ -54,9 +54,8 @@ const comments = (await commentsResponse.json()) as IComment[];
5454
>
5555
{comment.email === "[email protected]" && (
5656
<form
57-
method="POST"
58-
action={`/api/delete-comment?redirectHash=comments`}
5957
class="absolute right-2 top-2"
58+
id={`delete-comment-${comment.id}`}
6059
>
6160
<input type="hidden" name="commentId" value={comment.id} />
6261
<input type="hidden" name="postId" value={postId} />
@@ -84,29 +83,27 @@ const comments = (await commentsResponse.json()) as IComment[];
8483
</form>
8584
)}
8685
<h4 class="text-lg font-bold mb-1">{comment.name}</h4>
87-
<h5 class="text-md font-medium text-gray-600 mb-2">{comment.email}</h5>
86+
<h5 class="text-md font-medium text-gray-600 mb-2">
87+
{comment.email}
88+
</h5>
8889
<p class="text-gray-700">{comment.body}</p>
8990
</div>
9091
))
9192
}
9293
</div>
93-
<form
94-
method="POST"
95-
action={`/api/add-comment?postId=${postId}&redirectHash=comments`}
96-
class="space-y-4"
97-
enctype="multipart/form-data"
98-
>
94+
<form id="comment-form" class="space-y-4">
95+
<input type="hidden" name="postId" value={postId} />
9996
<div>
10097
<label for="comment" class="block text-sm font-medium text-gray-700"
10198
>Post a Comment</label
10299
>
103-
<textarea
100+
<input
101+
type="text"
104102
id="comment"
105-
name="body"
106-
rows="3"
103+
name="text"
107104
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
108105
required
109-
></textarea>
106+
/>
110107
</div>
111108
<button
112109
type="submit"
@@ -116,3 +113,36 @@ const comments = (await commentsResponse.json()) as IComment[];
116113
</button>
117114
</form>
118115
</div>
116+
117+
<script>
118+
import { actions } from "astro:actions";
119+
120+
const form = document.querySelector("#comment-form") as HTMLFormElement;
121+
form?.addEventListener("submit", async (event) => {
122+
event.preventDefault();
123+
const formData = new FormData(form);
124+
const { error } = await actions.addComment(formData);
125+
if (!error) {
126+
form.reset();
127+
location.reload();
128+
}
129+
});
130+
131+
// Handle delete comment forms
132+
const deleteForms = document.querySelectorAll(
133+
"form[id^='delete-comment-']"
134+
) as NodeListOf<HTMLFormElement>;
135+
deleteForms.forEach((form) => {
136+
form.addEventListener("submit", async (event: Event) => {
137+
event.preventDefault();
138+
if (confirm("Are you sure you want to delete this comment?")) {
139+
const formData = new FormData(form as HTMLFormElement);
140+
const { error } = await actions.deleteComment(formData);
141+
if (!error) {
142+
form.reset();
143+
location.reload();
144+
}
145+
}
146+
});
147+
});
148+
</script>

apps/4-streaming/4-4-astro-server-islands/src/pages/api/add-comment.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

apps/4-streaming/4-4-astro-server-islands/src/pages/api/delete-comment.ts

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)