From 4e2c09b7701388a7e59593446220bec7f5d97e5a Mon Sep 17 00:00:00 2001 From: lew Date: Fri, 23 Jan 2026 03:55:11 +0000 Subject: [PATCH] feat: add guestbook api routes --- apps/blog/src/pages/api/guestbook.ts | 30 +++++++++++++ apps/blog/src/pages/api/guestbook/[id].ts | 54 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 apps/blog/src/pages/api/guestbook.ts create mode 100644 apps/blog/src/pages/api/guestbook/[id].ts diff --git a/apps/blog/src/pages/api/guestbook.ts b/apps/blog/src/pages/api/guestbook.ts new file mode 100644 index 0000000..822e1d8 --- /dev/null +++ b/apps/blog/src/pages/api/guestbook.ts @@ -0,0 +1,30 @@ +import type { APIRoute } from 'astro'; +import { createEntry } from '../../lib/db'; + +export const prerender = false; + +export const POST: APIRoute = async ({ request }) => { + try { + const data = await request.json(); + const { name, message, url } = data; + + if (!name || !message) { + return new Response(JSON.stringify({ error: 'Name and message are required' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); + } + + await createEntry(name.slice(0, 100), message.slice(0, 500), url?.slice(0, 200) || null); + + return new Response(JSON.stringify({ success: true }), { + status: 201, + headers: { 'Content-Type': 'application/json' }, + }); + } catch (error) { + return new Response(JSON.stringify({ error: 'Failed to create entry' }), { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }); + } +}; diff --git a/apps/blog/src/pages/api/guestbook/[id].ts b/apps/blog/src/pages/api/guestbook/[id].ts new file mode 100644 index 0000000..286987e --- /dev/null +++ b/apps/blog/src/pages/api/guestbook/[id].ts @@ -0,0 +1,54 @@ +import type { APIRoute } from 'astro'; +import { getSession } from 'auth-astro/server'; +import { approveEntry, deleteEntry } from '../../../lib/db'; +import { isAdmin } from '../../../lib/auth'; + +export const prerender = false; + +export const PATCH: APIRoute = async ({ params, request }) => { + const session = await getSession(request); + + if (!session?.user?.id || !isAdmin(session.user.id)) { + return new Response(JSON.stringify({ error: 'Unauthorized' }), { + status: 403, + headers: { 'Content-Type': 'application/json' }, + }); + } + + const id = parseInt(params.id!, 10); + if (isNaN(id)) { + return new Response(JSON.stringify({ error: 'Invalid ID' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); + } + + await approveEntry(id); + return new Response(JSON.stringify({ success: true }), { + headers: { 'Content-Type': 'application/json' }, + }); +}; + +export const DELETE: APIRoute = async ({ params, request }) => { + const session = await getSession(request); + + if (!session?.user?.id || !isAdmin(session.user.id)) { + return new Response(JSON.stringify({ error: 'Unauthorized' }), { + status: 403, + headers: { 'Content-Type': 'application/json' }, + }); + } + + const id = parseInt(params.id!, 10); + if (isNaN(id)) { + return new Response(JSON.stringify({ error: 'Invalid ID' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); + } + + await deleteEntry(id); + return new Response(JSON.stringify({ success: true }), { + headers: { 'Content-Type': 'application/json' }, + }); +};