Новые правки в компоенты
This commit is contained in:
parent
e85d1ce668
commit
6f727aae7b
23 changed files with 1483 additions and 37 deletions
248
frontend/src/pages/api/comments/index.ts
Normal file
248
frontend/src/pages/api/comments/index.ts
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
import type { APIRoute } from "astro";
|
||||
|
||||
const POCKETBASE_URL = import.meta.env.POCKETBASE_URL || "http://localhost:8090";
|
||||
|
||||
export const GET: APIRoute = async ({ url, cookies }) => {
|
||||
const postSlug = url.searchParams.get("post_slug");
|
||||
const parent = url.searchParams.get("parent");
|
||||
|
||||
if (!postSlug) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "post_slug required" }),
|
||||
{
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const pbAuthCookie = cookies.get("pb_auth")?.value;
|
||||
const token = pbAuthCookie?.trim();
|
||||
|
||||
// Фильтр: комментарии для поста + статус published
|
||||
let filter = `post_slug = "${postSlug}" && status = "published"`;
|
||||
|
||||
// Если parent = null — это основные комментарии (не ответы)
|
||||
// Если parent указан — это ответы на конкретный комментарий
|
||||
if (parent === "null" || parent === null) {
|
||||
filter += ` && parent = ""`;
|
||||
} else if (parent) {
|
||||
filter += ` && parent = "${parent}"`;
|
||||
}
|
||||
|
||||
const expand = "user";
|
||||
const sort = "-created";
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${POCKETBASE_URL}/api/collections/comments/records?expand=${expand}&filter=${encodeURIComponent(filter)}&sort=${sort}`,
|
||||
{
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
||||
}
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
return new Response(JSON.stringify(data), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[Comments API GET] Error:", error);
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Failed to fetch comments" }),
|
||||
{
|
||||
status: 500,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const POST: APIRoute = async ({ request, cookies }) => {
|
||||
const pbAuthCookie = cookies.get("pb_auth")?.value;
|
||||
const token = pbAuthCookie?.trim();
|
||||
|
||||
console.log("[Comments API POST] Токен получен:", !!token);
|
||||
console.log("[Comments API POST] Длина токена:", token?.length);
|
||||
console.log("[Comments API POST] Cookie:", pbAuthCookie ? "да" : "нет");
|
||||
|
||||
if (!token) {
|
||||
console.log("[Comments API POST] Токен не найден - 401");
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Unauthorized" }),
|
||||
{
|
||||
status: 401,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Получаем данные пользователя из токена
|
||||
let userId: string | null = null;
|
||||
try {
|
||||
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;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("[Comments API POST] Не удалось получить данные пользователя:", e);
|
||||
}
|
||||
|
||||
if (!userId) {
|
||||
console.log("[Comments API POST] Не удалось получить ID пользователя");
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Unauthorized" }),
|
||||
{
|
||||
status: 401,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { content, post_slug, parent = null } = body;
|
||||
|
||||
// Валидация
|
||||
if (!content || !post_slug) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "content and post_slug required" }),
|
||||
{
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (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" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Проверка: если это ответ на комментарий
|
||||
if (parent) {
|
||||
const parentCommentResponse = await fetch(
|
||||
`${POCKETBASE_URL}/api/collections/comments/records/${parent}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (parentCommentResponse.ok) {
|
||||
const parentComment = await parentCommentResponse.json();
|
||||
|
||||
// Если родительский комментарий уже сам является ответом — запрещаем (только 2 уровня)
|
||||
if (parentComment.parent && parentComment.parent !== "") {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Нельзя отвечать на ответы. Вы можете ответить только на основные комментарии." }),
|
||||
{
|
||||
status: 403,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Нельзя отвечать на свой комментарий
|
||||
if (parentComment.user === userId) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Нельзя отвечать на свой собственный коммен<D0B5><D0BD>арий" }),
|
||||
{
|
||||
status: 403,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Проверяем: если родительский комментарий уже имеет ответы — запрещаем (только 1 уровень ответов)
|
||||
const existingRepliesResponse = await fetch(
|
||||
`${POCKETBASE_URL}/api/collections/comments/records?filter=parent="${parent}"&perPage=1`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (existingRepliesResponse.ok) {
|
||||
const existingRepliesData = await existingRepliesResponse.json();
|
||||
if (existingRepliesData.totalItems > 0) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "На этот комментарий уже есть ответ. Вы можете ответить только на основные комментарии." }),
|
||||
{
|
||||
status: 403,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Родительский комментарий не найден" }),
|
||||
{
|
||||
status: 404,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${POCKETBASE_URL}/api/collections/comments/records`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content,
|
||||
post_slug,
|
||||
parent: parent || "",
|
||||
status: "published",
|
||||
user: userId, // Передаём ID текущего пользователя
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
console.log("[Comments API POST] Ответ PocketBase:", response.status, JSON.stringify(data));
|
||||
|
||||
if (!response.ok) {
|
||||
return new Response(JSON.stringify(data), {
|
||||
status: response.status,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
|
||||
return new Response(JSON.stringify(data), {
|
||||
status: 201,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[Comments API POST] Error:", error);
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Failed to create comment" }),
|
||||
{
|
||||
status: 500,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue