Новые изменения

This commit is contained in:
Web-serfer 2026-04-18 20:55:07 +05:00
parent 6f727aae7b
commit b5b31f8a88
9 changed files with 600 additions and 166 deletions

View file

@ -0,0 +1,208 @@
import type { APIRoute } from "astro";
const POCKETBASE_URL = import.meta.env.POCKETBASE_URL || "http://localhost:8090";
export const PATCH: APIRoute = async ({ params, request, cookies }) => {
const pbAuthCookie = cookies.get("pb_auth")?.value;
const token = pbAuthCookie?.trim();
if (!token) {
return new Response(
JSON.stringify({ error: "Unauthorized" }),
{ status: 401, headers: { "Content-Type": "application/json" } }
);
}
try {
let userId: string | null = null;
const userResponse = await fetch(
`${POCKETBASE_URL}/api/collections/users/auth-refresh`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
}
);
if (userResponse.ok) {
const userData = await userResponse.json();
userId = userData.record?.id;
}
if (!userId) {
return new Response(
JSON.stringify({ error: "Unauthorized" }),
{ status: 401, headers: { "Content-Type": "application/json" } }
);
}
const commentId = params.id;
if (!commentId) {
return new Response(
JSON.stringify({ error: "Comment ID required" }),
{ status: 400, headers: { "Content-Type": "application/json" } }
);
}
const commentResponse = await fetch(
`${POCKETBASE_URL}/api/collections/comments/records/${commentId}`,
{
headers: { Authorization: `Bearer ${token}` },
}
);
if (!commentResponse.ok) {
return new Response(
JSON.stringify({ error: "Comment not found" }),
{ status: 404, headers: { "Content-Type": "application/json" } }
);
}
const comment = await commentResponse.json();
if (comment.user !== userId) {
return new Response(
JSON.stringify({ error: "Нет прав на редактирование" }),
{ status: 403, headers: { "Content-Type": "application/json" } }
);
}
const body = await request.json();
const { content } = body;
if (!content || content.length < 10 || content.length > 2000) {
return new Response(
JSON.stringify({ error: "content must be between 10 and 2000 characters" }),
{ status: 400, headers: { "Content-Type": "application/json" } }
);
}
const updateResponse = await fetch(
`${POCKETBASE_URL}/api/collections/comments/records/${commentId}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ content }),
}
);
if (!updateResponse.ok) {
const errorData = await updateResponse.json();
return new Response(JSON.stringify(errorData), {
status: updateResponse.status,
headers: { "Content-Type": "application/json" },
});
}
const updatedComment = await updateResponse.json();
return new Response(JSON.stringify(updatedComment), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
console.error("[Comments API PATCH] Error:", error);
return new Response(
JSON.stringify({ error: "Failed to update comment" }),
{ status: 500, headers: { "Content-Type": "application/json" } }
);
}
};
export const DELETE: APIRoute = async ({ params, cookies }) => {
const pbAuthCookie = cookies.get("pb_auth")?.value;
const token = pbAuthCookie?.trim();
if (!token) {
return new Response(
JSON.stringify({ error: "Unauthorized" }),
{ status: 401, headers: { "Content-Type": "application/json" } }
);
}
try {
let userId: string | null = null;
const userResponse = await fetch(
`${POCKETBASE_URL}/api/collections/users/auth-refresh`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
}
);
if (userResponse.ok) {
const userData = await userResponse.json();
userId = userData.record?.id;
}
if (!userId) {
return new Response(
JSON.stringify({ error: "Unauthorized" }),
{ status: 401, headers: { "Content-Type": "application/json" } }
);
}
const commentId = params.id;
if (!commentId) {
return new Response(
JSON.stringify({ error: "Comment ID required" }),
{ status: 400, headers: { "Content-Type": "application/json" } }
);
}
const commentResponse = await fetch(
`${POCKETBASE_URL}/api/collections/comments/records/${commentId}`,
{
headers: { Authorization: `Bearer ${token}` },
}
);
if (!commentResponse.ok) {
return new Response(
JSON.stringify({ error: "Comment not found" }),
{ status: 404, headers: { "Content-Type": "application/json" } }
);
}
const comment = await commentResponse.json();
if (comment.user !== userId) {
return new Response(
JSON.stringify({ error: "Нет прав на удаление" }),
{ status: 403, headers: { "Content-Type": "application/json" } }
);
}
const deleteResponse = await fetch(
`${POCKETBASE_URL}/api/collections/comments/records/${commentId}`,
{
method: "DELETE",
headers: { Authorization: `Bearer ${token}` },
}
);
if (!deleteResponse.ok) {
const errorData = await deleteResponse.json();
return new Response(JSON.stringify(errorData), {
status: deleteResponse.status,
headers: { "Content-Type": "application/json" },
});
}
return new Response(JSON.stringify({ success: true }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
console.error("[Comments API DELETE] Error:", error);
return new Response(
JSON.stringify({ error: "Failed to delete comment" }),
{ status: 500, headers: { "Content-Type": "application/json" } }
);
}
};

View file

@ -1,7 +1,7 @@
---
import ArticleLayout from '@layouts/ArticleLayout.astro';
import { SITE_URL } from '@constants';
import Comments from '@components/blog/comments/Comments';
import Comments from '@components/blog/comments/Comments.astro';
import RelatedPosts from '@components/blog/RelatedPosts.astro';
import ArticleTableOfContents from '@components/blog/ArticleTableOfContents.astro';
import { getPostBySlug, getPosts, getPostImageUrl, getPostVotesStats } from '@lib/pb';
@ -82,7 +82,7 @@ const heroImage = getPostImageUrl(post);
<!-- Система комментариев -->
<div class="comments-wrapper">
<Comments client:only="solid-js" postSlug={post.slug} />
<Comments postSlug={post.slug} />
</div>
<!-- Похожие статьи -->