Add dynamic footer badge marquee with admin management.
Store badges in Postgres, expose public/admin APIs, render an infinite footer slider, and ship /admin for paste-embed CRUD. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
42ad9c38e3
commit
7d22f722f6
@@ -0,0 +1,48 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { requireAdmin } from "@/lib/admin-auth";
|
||||
import { prisma } from "@/lib/db";
|
||||
import { normalizeBadgeFields, validateBadgeFields } from "@/lib/footer-badges";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const denied = requireAdmin(req);
|
||||
if (denied) return denied;
|
||||
|
||||
const badges = await prisma.footerBadge.findMany({
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
});
|
||||
|
||||
return NextResponse.json({ badges });
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const denied = requireAdmin(req);
|
||||
if (denied) return denied;
|
||||
|
||||
let body: unknown;
|
||||
try {
|
||||
body = await req.json();
|
||||
} catch {
|
||||
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
||||
}
|
||||
|
||||
const input = (body ?? {}) as Record<string, unknown>;
|
||||
const fields = normalizeBadgeFields({
|
||||
name: typeof input.name === "string" ? input.name : "",
|
||||
embedHtml: typeof input.embedHtml === "string" ? input.embedHtml : null,
|
||||
imageUrl: typeof input.imageUrl === "string" ? input.imageUrl : null,
|
||||
linkUrl: typeof input.linkUrl === "string" ? input.linkUrl : null,
|
||||
isActive: typeof input.isActive === "boolean" ? input.isActive : true,
|
||||
sortOrder: typeof input.sortOrder === "number" ? input.sortOrder : undefined,
|
||||
});
|
||||
|
||||
const error = validateBadgeFields(fields);
|
||||
if (error) return NextResponse.json({ error }, { status: 400 });
|
||||
|
||||
if (fields.sortOrder === 0) {
|
||||
const max = await prisma.footerBadge.aggregate({ _max: { sortOrder: true } });
|
||||
fields.sortOrder = (max._max.sortOrder ?? -1) + 1;
|
||||
}
|
||||
|
||||
const badge = await prisma.footerBadge.create({ data: fields });
|
||||
return NextResponse.json({ badge }, { status: 201 });
|
||||
}
|
||||
Reference in New Issue
Block a user