Make /admin/catalog a full-screen catalog studio that replaces the old listing plus separate [id]/builder-club detail pages: - Embed CatalogManagerWorkspace on /admin/catalog with a Normal/Builder Club toggle, Catalog Sync status, packages (normal), Organize imports and a diagnostics link to /admin/studio/maintenance. - Manage BC items directly in the studio Items tab (new BcItemsEditor, CRUD via existing bc actions; /api/admin/catalog/items now serves BC). - Inline editor: add pageTextTeaser field for both catalogs and remove the legacy full-editor links. - Remove the 'Open full editor' context action from the tree. - Move catalog-items-table (dir + barrel) and catalog-translate-tab out of the app route into src/components/admin/catalog and update all importers. - Keep /admin/catalog/[id], builder-club/[id] and /admin/catalog/maintenance as redirects into the new studio; consolidate maintenance panels into /admin/studio/maintenance and point the nav item there. - Delete the old listing/table/tabs/forms and the standalone bc-manager.
34 lines
1.1 KiB
TypeScript
34 lines
1.1 KiB
TypeScript
import { asc, eq } from "drizzle-orm";
|
|
import { apiError, apiOk } from "@/lib/api";
|
|
import { withAdmin } from "@/lib/api-handler";
|
|
import { CatalogItemsBc, db } from "@/lib/db";
|
|
import { PERMS } from "@/lib/permissions";
|
|
import { loadCatalogItemsData } from "@/lib/services/catalog-items-loader";
|
|
|
|
function jsonSafe<T>(data: T): T {
|
|
return JSON.parse(
|
|
JSON.stringify(data, (_k, v) => (typeof v === "bigint" ? Number(v) : v)),
|
|
) as T;
|
|
}
|
|
|
|
export const GET = withAdmin(
|
|
{ permission: PERMS.CATALOG_VIEW },
|
|
async (request) => {
|
|
const pageId = Number(request.nextUrl.searchParams.get("pageId"));
|
|
if (!Number.isFinite(pageId) || pageId <= 0) {
|
|
return apiError("Invalid pageId");
|
|
}
|
|
const isBc = request.nextUrl.searchParams.get("catalog") === "bc";
|
|
if (isBc) {
|
|
const items = await db
|
|
.select()
|
|
.from(CatalogItemsBc)
|
|
.where(eq(CatalogItemsBc.pageId, pageId))
|
|
.orderBy(asc(CatalogItemsBc.orderNumber));
|
|
return apiOk({ items: jsonSafe(items) });
|
|
}
|
|
const data = await loadCatalogItemsData(pageId);
|
|
return apiOk(jsonSafe(data) as unknown as Record<string, unknown>);
|
|
},
|
|
);
|