feat(export): enhance export routing to support /[section]/export, /[section]/[slug]/export, and dynamic route rendering
CI / typecheck + tests (push) Canceled after 0s
CI / build + deploy (Nix) — api (push) Canceled after 0s
CI / build + deploy (Nix) — mcp (push) Canceled after 0s
CI / build + deploy (Nix) — worker (push) Canceled after 0s
CI / build + deploy (web) (push) Canceled after 0s

This commit is contained in:
asepharyana
2026-08-22 11:55:58 +07:00
parent 96b8765966
commit 864911af20
3 changed files with 24 additions and 7 deletions
+21 -4
View File
@@ -1,12 +1,13 @@
import Link from "next/link";
import { notFound } from "next/navigation";
import { cookies } from "next/headers";
import { getDocument, getRelated, listRevisions, listDocuments } from "@mcpedia/core";
import { getDocument, getRelated, listRevisions, listDocuments, getExportDocuments } from "@mcpedia/core";
import { WEBHOOK_SECRET } from "@mcpedia/config";
import Markdown from "@/components/Markdown";
import DocForm from "@/components/DocForm";
import TOC from "@/components/TOC";
import DocActions from "@/components/DocActions";
import PdfExportView from "@/components/PdfExportView";
import { classifyPath, extractFoldersForSection } from "@mcpedia/core";
import { getSectionMeta } from "@mcpedia/config";
import type { DocumentMeta } from "@mcpedia/core";
@@ -15,7 +16,7 @@ export const dynamic = "force-dynamic";
interface DocPageProps {
params: Promise<{ section: string; slug: string[] }>;
searchParams: Promise<{ edit?: string }>;
searchParams: Promise<{ edit?: string; path?: string; sort?: string }>;
}
function getSectionInfo(section: string) {
@@ -191,7 +192,7 @@ function FolderIndexPage({
{immediateDocs.length + folders.length} item{folders.length + immediateDocs.length !== 1 ? "s" : ""}
</span>
<Link
href={`/export/pdf?path=${section}/${slug}`}
href={`/${section}/${slug}/export`}
className="inline-flex items-center gap-1.5 text-xs bg-[var(--brand)] hover:bg-[var(--brand-hover)] text-white px-3 py-1.5 rounded-lg font-medium transition-all shadow-xs"
title={`Export all ${folderName} documents as a single PDF report`}
>
@@ -288,7 +289,23 @@ function FolderIndexPage({
export default async function DocPage({ params, searchParams }: DocPageProps) {
const { section, slug } = await params;
const { edit } = await searchParams;
const searchParamsObj = await searchParams;
const { edit, path: queryPath, sort } = searchParamsObj;
// Handle direct export views: /[section]/export, /[section]/[...folder]/export, or /export/pdf
if (section === "export" || (slug && slug[slug.length - 1] === "export")) {
const isTrailingExport = slug && slug[slug.length - 1] === "export";
const targetSlug = isTrailingExport ? slug.slice(0, -1) : slug;
const targetPath = queryPath || (targetSlug.length > 0 ? `${section}/${targetSlug.join("/")}` : section);
const exportData = await getExportDocuments({
path: targetPath === "export" ? queryPath : targetPath,
section: targetPath === section ? section : undefined,
sortBy: (sort as any) || "category_points",
});
const backHref = targetPath && targetPath !== "export" ? `/${targetPath}` : section !== "export" ? `/${section}` : "/";
return <PdfExportView exportData={exportData} backHref={backHref} />;
}
const fullSlug = `${section}/${slug.join("/")}`;
const allDocs = await listDocuments();
+2 -2
View File
@@ -157,8 +157,8 @@ export default async function SectionIndexPage({
</span>
{sectionDocs.length > 0 && (
<Link
href={`/export/pdf?section=${section}`}
className="inline-flex items-center gap-1.5 text-xs bg-[var(--bg-elevated)] hover:bg-[var(--bg-elevated-hover)] border border-[var(--border-color)] hover:border-[var(--brand)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] px-3 py-1 rounded-md font-medium transition-all shadow-xs"
href={`/${section}/export`}
className="inline-flex items-center gap-1.5 text-xs bg-[var(--brand)]/10 hover:bg-[var(--brand)]/20 border border-[var(--brand)]/30 hover:border-[var(--brand)]/60 text-[var(--brand)] dark:text-[var(--accent)] px-3 py-1 rounded-md font-medium transition-all shadow-xs"
title={`Export all ${sectionInfo.label} documents to PDF`}
>
<span>📄</span>
+1 -1
View File
@@ -77,7 +77,7 @@ export default function DocActions({ slug, body, canEdit }: DocActionsProps) {
{/* Export PDF */}
<Link
href={`/export/pdf?path=${slug}`}
href={`/${slug}/export`}
title="Export document or parent folder to PDF"
className="inline-flex items-center gap-1 px-2.5 py-1 text-xs bg-[var(--bg-surface)] hover:bg-[var(--bg-elevated)] border border-[var(--border-color)] hover:border-[var(--brand)] text-[var(--text-muted)] hover:text-[var(--text-primary)] rounded-md transition-all shadow-sm"
>