diff --git a/src/actions/admin-settings.ts b/src/actions/admin-settings.ts new file mode 100644 index 00000000..bc9ab1ff --- /dev/null +++ b/src/actions/admin-settings.ts @@ -0,0 +1,40 @@ +"use server"; + +import { revalidatePath } from "next/cache"; +import { requireStaff } from "@/lib/admin/guard"; +import { prisma } from "@/lib/prisma"; +import { siteSettings } from "@/lib/services/site-settings"; + +export async function updateSetting(formData: FormData): Promise { + await requireStaff(); + const key = String(formData.get("key") ?? "").trim(); + const value = String(formData.get("value") ?? ""); + if (!key) return; + await prisma.websiteSetting.update({ where: { key }, data: { value } }); + siteSettings.reload(); + revalidatePath("/admin/settings"); +} + +export async function createSetting(formData: FormData): Promise { + await requireStaff(); + const key = String(formData.get("key") ?? "").trim().slice(0, 255); + const value = String(formData.get("value") ?? ""); + const comment = String(formData.get("comment") ?? "").trim().slice(0, 255); + if (!key) return; + await prisma.websiteSetting.upsert({ + where: { key }, + update: { value }, + create: { key, value, comment: comment || null }, + }); + siteSettings.reload(); + revalidatePath("/admin/settings"); +} + +export async function deleteSetting(formData: FormData): Promise { + await requireStaff(); + const key = String(formData.get("key") ?? "").trim(); + if (!key) return; + await prisma.websiteSetting.delete({ where: { key } }); + siteSettings.reload(); + revalidatePath("/admin/settings"); +} diff --git a/src/app/admin/layout.tsx b/src/app/admin/layout.tsx index a18bc74f..0bcf846c 100644 --- a/src/app/admin/layout.tsx +++ b/src/app/admin/layout.tsx @@ -18,6 +18,7 @@ export default async function AdminLayout({ children }: { children: ReactNode }) Users Articles Bans + Settings
{children}
diff --git a/src/app/admin/settings/page.tsx b/src/app/admin/settings/page.tsx new file mode 100644 index 00000000..1dbea986 --- /dev/null +++ b/src/app/admin/settings/page.tsx @@ -0,0 +1,55 @@ +import { createSetting, deleteSetting, updateSetting } from "@/actions/admin-settings"; +import { prisma } from "@/lib/prisma"; + +export const dynamic = "force-dynamic"; + +export default async function AdminSettings() { + const settings = await prisma.websiteSetting.findMany({ orderBy: { key: "asc" } }); + + return ( +
+

CMS Settings

+

+ Key/value config read at runtime via siteSettings.get(). Saving busts the cache. +

+ +
+

Add / overwrite

+
+ + + + +
+
+ +
+ {settings.map((s) => ( +
+
+ {s.key} +
+ + + +
+
+ + +
+
+ {s.comment ? ( +

+ {s.comment} +

+ ) : null} +
+ ))} +
+ {settings.length === 0 ?

No settings yet.

: null} +
+ ); +}