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>
37 lines
1.2 KiB
TypeScript
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>
|
|
);
|
|
}
|