/** * /d/[docId]/[page] — single-page chunks view. * * Scoped to one page (e.g., p007). Shows the PNG of the page alongside * the chunks for cross-reference. */ import Link from "next/link"; import Image from "next/image"; import { notFound } from "next/navigation"; import { readChunksByPage, readIndex, hasChunks } from "@/lib/chunks"; import { readDocument, listDocuments } from "@/lib/wiki"; import { AuthBar } from "@/components/auth-bar"; import { ChatBubble } from "@/components/chat-bubble"; import { DocRendererV2 } from "@/components/doc-renderer-v2"; export const dynamic = "force-dynamic"; export default async function DocPageView({ params, }: { params: Promise<{ docId: string; page: string }>; }) { const { docId, page } = await params; const stem = /^p\d{3}$/.test(page) ? page : `p${page.padStart(3, "0")}`; const m = stem.match(/^p(\d{3})$/); if (!m) notFound(); const pageNum = parseInt(m[1], 10); if (!(await hasChunks(docId))) { return (
← documento

▍ documento ainda não indexado

Este documento ainda não foi processado.

); } const [idx, byPage, doc, docList] = await Promise.all([ readIndex(docId), readChunksByPage(docId), readDocument(docId), listDocuments(), ]); if (!idx) notFound(); const pageChunks = byPage.get(pageNum) ?? []; const pngUrl = `/api/static/processing/png/${docId}/p-${m[1]}.png`; const totalPages = idx.total_pages; // ── Navigation: prev/next page within doc; at boundaries, prev/next document ── const pp = (n: number) => `p${String(n).padStart(3, "0")}`; const docIdx = docList.indexOf(docId); const prevDoc = docIdx > 0 ? docList[docIdx - 1] : null; const nextDoc = docIdx >= 0 && docIdx < docList.length - 1 ? docList[docIdx + 1] : null; const prevNav = pageNum > 1 ? { href: `/d/${docId}/${pp(pageNum - 1)}`, label: `← página ${pageNum - 1}`, kind: "page" as const } : prevDoc ? { href: `/d/${prevDoc}/${pp(1)}`, label: "← documento anterior", kind: "doc" as const } : null; const nextNav = pageNum < totalPages ? { href: `/d/${docId}/${pp(pageNum + 1)}`, label: `página ${pageNum + 1} →`, kind: "page" as const } : nextDoc ? { href: `/d/${nextDoc}/${pp(1)}`, label: "próximo documento →", kind: "doc" as const } : null; const navBar = ( ); return (
← documento inteiro
página {pageNum} de {totalPages} · {pageChunks.length} trechos · doc:{" "} {docId}

▍ {(doc?.fm.canonical_title as string) ?? docId} · p{pageNum}

{navBar}

trechos (ordem de leitura)

{pageChunks.length === 0 ? (

▍ página sem trechos extraídos

O scan existe (veja à esquerda) mas o processo de chunking não gerou trechos para esta página específica. Pode ser página em branco, divisor de seção ou conteúdo sem texto extraível. Próxima execução do chunker preencherá.

) : ( )}
{navBar}
); }