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
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:
@@ -1,12 +1,13 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { cookies } from "next/headers";
|
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 { WEBHOOK_SECRET } from "@mcpedia/config";
|
||||||
import Markdown from "@/components/Markdown";
|
import Markdown from "@/components/Markdown";
|
||||||
import DocForm from "@/components/DocForm";
|
import DocForm from "@/components/DocForm";
|
||||||
import TOC from "@/components/TOC";
|
import TOC from "@/components/TOC";
|
||||||
import DocActions from "@/components/DocActions";
|
import DocActions from "@/components/DocActions";
|
||||||
|
import PdfExportView from "@/components/PdfExportView";
|
||||||
import { classifyPath, extractFoldersForSection } from "@mcpedia/core";
|
import { classifyPath, extractFoldersForSection } from "@mcpedia/core";
|
||||||
import { getSectionMeta } from "@mcpedia/config";
|
import { getSectionMeta } from "@mcpedia/config";
|
||||||
import type { DocumentMeta } from "@mcpedia/core";
|
import type { DocumentMeta } from "@mcpedia/core";
|
||||||
@@ -15,7 +16,7 @@ export const dynamic = "force-dynamic";
|
|||||||
|
|
||||||
interface DocPageProps {
|
interface DocPageProps {
|
||||||
params: Promise<{ section: string; slug: string[] }>;
|
params: Promise<{ section: string; slug: string[] }>;
|
||||||
searchParams: Promise<{ edit?: string }>;
|
searchParams: Promise<{ edit?: string; path?: string; sort?: string }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSectionInfo(section: string) {
|
function getSectionInfo(section: string) {
|
||||||
@@ -191,7 +192,7 @@ function FolderIndexPage({
|
|||||||
{immediateDocs.length + folders.length} item{folders.length + immediateDocs.length !== 1 ? "s" : ""}
|
{immediateDocs.length + folders.length} item{folders.length + immediateDocs.length !== 1 ? "s" : ""}
|
||||||
</span>
|
</span>
|
||||||
<Link
|
<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"
|
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`}
|
title={`Export all ${folderName} documents as a single PDF report`}
|
||||||
>
|
>
|
||||||
@@ -288,7 +289,23 @@ function FolderIndexPage({
|
|||||||
|
|
||||||
export default async function DocPage({ params, searchParams }: DocPageProps) {
|
export default async function DocPage({ params, searchParams }: DocPageProps) {
|
||||||
const { section, slug } = await params;
|
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 fullSlug = `${section}/${slug.join("/")}`;
|
||||||
|
|
||||||
const allDocs = await listDocuments();
|
const allDocs = await listDocuments();
|
||||||
|
|||||||
@@ -157,8 +157,8 @@ export default async function SectionIndexPage({
|
|||||||
</span>
|
</span>
|
||||||
{sectionDocs.length > 0 && (
|
{sectionDocs.length > 0 && (
|
||||||
<Link
|
<Link
|
||||||
href={`/export/pdf?section=${section}`}
|
href={`/${section}/export`}
|
||||||
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"
|
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`}
|
title={`Export all ${sectionInfo.label} documents to PDF`}
|
||||||
>
|
>
|
||||||
<span>📄</span>
|
<span>📄</span>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export default function DocActions({ slug, body, canEdit }: DocActionsProps) {
|
|||||||
|
|
||||||
{/* Export PDF */}
|
{/* Export PDF */}
|
||||||
<Link
|
<Link
|
||||||
href={`/export/pdf?path=${slug}`}
|
href={`/${slug}/export`}
|
||||||
title="Export document or parent folder to PDF"
|
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"
|
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"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user