yap-blog/src/app/admin/(panel)/settings/page.tsx
matt 3175bd9172 Add JSON import/export backup on the settings page
Export downloads a versioned JSON snapshot of all posts, pages, tags,
navigation, and settings from GET /api/admin/export. Cross-references
are keyed by slug rather than database id, so a backup restores cleanly
into any database. Import (a new settings-page section) validates the
file and atomically replaces all content in one transaction, sanitizing
bodies at the trust boundary; users, sessions, and uploaded files are
untouched. Server-action body limit raised so backups fit in the
import upload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:53:38 -04:00

37 lines
1.2 KiB
TypeScript

import type { Metadata } from "next";
import { importSiteAction, updateSettingsAction } from "@/actions/settings";
import { ImportExportSection } from "@/components/admin/ImportExportSection";
import { SettingsForm } from "@/components/admin/SettingsForm";
import { requireAdmin } from "@/lib/auth/dal";
import { listPublishedPages } from "@/lib/services/pages";
import { getSettings, listNavItems } from "@/lib/services/settings";
import { listAllTags } from "@/lib/services/tags";
export const metadata: Metadata = { title: "Site settings" };
export default async function AdminSettingsPage() {
await requireAdmin();
const [settings, navItems, allTags, publishedPages] = await Promise.all([
getSettings(),
listNavItems(),
listAllTags(),
listPublishedPages(),
]);
return (
<div>
<h1 className="mb-6 text-2xl font-bold tracking-tight text-ink-bright">Site settings</h1>
<SettingsForm
settings={settings}
navItems={navItems}
allTags={allTags}
publishedPages={publishedPages}
action={updateSettingsAction}
/>
<div className="mt-10">
<ImportExportSection importAction={importSiteAction} />
</div>
</div>
);
}