This commit is contained in:
Your Name committed 2026-06-08 07:15:52 +07:00
1 parent c1c3a43d7d
commit a5f6e3171b
11 files changed
+351 -13

No files matched your search

+1
View File
@@ -12,6 +12,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@homaroma/types": "*",
"@elysiajs/cors": "^1.2.2",
"@elysiajs/jwt": "^1.4.1",
"@elysiajs/static": "^1.4.7",
+56 -6
View File
@@ -1,5 +1,12 @@
import { Elysia, t } from "elysia";
import prisma from "../lib/prisma";
import {
HeroArticlePayloadSchema,
RichTextPayloadSchema,
ScentNotesBreakdownPayloadSchema,
QuoteCalloutPayloadSchema,
ProductCarouselPayloadSchema
} from "@homaroma/types";
export const pagesRoute = new Elysia({ prefix: "/pages" })
.get("/", async () => {
@@ -113,15 +120,22 @@ export const pagesRoute = new Elysia({ prefix: "/pages" })
.post("/", async ({ body, set }) => {
try {
const data = body as any;
const { id, slug, title, isPublished } = data;
const { id, slug, title, isPublished, status, metadata } = data;
let finalIsPublished = true;
if (status !== undefined) {
finalIsPublished = status === "published";
} else if (isPublished !== undefined) {
finalIsPublished = isPublished;
}
if (id) {
return await prisma.page.update({
where: { id: Number(id) },
data: { slug, title, isPublished: isPublished !== false }
data: { slug, title, isPublished: finalIsPublished }
});
} else {
return await prisma.page.create({
data: { slug, title, isPublished: isPublished !== false }
data: { slug, title, isPublished: finalIsPublished }
});
}
} catch (err) {
@@ -134,7 +148,9 @@ export const pagesRoute = new Elysia({ prefix: "/pages" })
id: t.Optional(t.Number()),
slug: t.String(),
title: t.String(),
isPublished: t.Optional(t.Boolean())
isPublished: t.Optional(t.Boolean()),
status: t.Optional(t.String()),
metadata: t.Optional(t.Any())
})
})
.delete("/:slug", async ({ params: { slug }, set }) => {
@@ -170,11 +186,20 @@ export const pagesRoute = new Elysia({ prefix: "/pages" })
return { error: validationError };
}
let finalOrder = order;
if (finalOrder === undefined) {
const lastSection = await prisma.pageSection.findFirst({
where: { pageId },
orderBy: { order: "desc" }
});
finalOrder = lastSection ? lastSection.order + 1 : 1;
}
return await prisma.pageSection.create({
data: {
pageId,
type: type.toUpperCase(),
order,
order: finalOrder,
payload,
isActive: isActive !== false
}
@@ -187,7 +212,7 @@ export const pagesRoute = new Elysia({ prefix: "/pages" })
}, {
body: t.Object({
type: t.String(),
order: t.Number(),
order: t.Optional(t.Number()),
payload: t.Any(),
isActive: t.Optional(t.Boolean())
})
@@ -373,6 +398,31 @@ function validateSectionPayload(type: string, payload: any): string | null {
if (typeof slide.category !== 'string') return `Slide #${idx+1} must contain a category string`;
}
break;
case 'HERO_ARTICLE': {
const res = HeroArticlePayloadSchema.safeParse(payload);
if (!res.success) return res.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
break;
}
case 'RICH_TEXT': {
const res = RichTextPayloadSchema.safeParse(payload);
if (!res.success) return res.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
break;
}
case 'SCENT_NOTES_BREAKDOWN': {
const res = ScentNotesBreakdownPayloadSchema.safeParse(payload);
if (!res.success) return res.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
break;
}
case 'QUOTE_CALLOUT': {
const res = QuoteCalloutPayloadSchema.safeParse(payload);
if (!res.success) return res.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
break;
}
case 'PRODUCT_CAROUSEL': {
const res = ProductCarouselPayloadSchema.safeParse(payload);
if (!res.success) return res.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
break;
}
default:
return `Unknown section type: ${type}`;
}