import type { Metadata } from 'next'; import Link from 'next/link'; import { AdminFilters, AdminTitle, Mono, StatusChip } from '@/components/admin/ui'; import { DataTable, EmptyRow, Td, Th } from '@/components/ui/data-table'; import { LiveAgo } from '@/components/ui/live'; import { Pagination, withParams } from '@/components/ui/pagination'; import { Unavailable } from '@/components/ui/unavailable'; import { adminApi, load, requireAdmin } from '@/lib/admin/admin-api'; import { fmtDateTime, fmtInt, num } from '@/lib/format'; import { routes } from '@/lib/site'; export const metadata: Metadata = { title: 'Documents', robots: { index: false, follow: false } }; export const dynamic = 'force-dynamic'; const LIMIT = 50; const STATUSES = ['active', 'gone', 'blocked', 'error', 'paused']; export default async function AdminDocumentsPage({ searchParams }: { searchParams: Promise> }) { await requireAdmin(); const sp = await searchParams; const current: Record = {}; for (const k of ['connector', 'status', 'q', 'offset']) if (sp[k]) current[k] = sp[k]; const offset = Math.max(0, Number(current.offset) || 0); const [docs, connectors] = await Promise.all([load(adminApi.documents({ connector: current.connector, status: current.status, q: current.q, limit: LIMIT, offset })), load(adminApi.connectors())]); const names = connectors.ok ? connectors.data.items.map((c) => c.name).sort() : []; const href = (patch: Record) => withParams('/admin/documents', current, patch); return ( <> ({ value: n, label: n })) }, { kind: 'select', name: 'status', label: 'Status', value: current.status, options: STATUSES.map((s) => ({ value: s, label: s })) }, { kind: 'text', name: 'q', label: 'URL / title', value: current.q, placeholder: 'contains…' }, ]} /> {!docs.ok ? ( ) : ( <> Document Connector Type Entity Fetched HTTP Snaps Changes Fails Status Processing {docs.data.items.length === 0 && No documents match.} {docs.data.items.map((d) => ( {d.title ?? d.url.replace(/^https?:\/\/(www\.)?/, '')} {d.url.replace(/^https?:\/\/(www\.)?/, '')} {d.connector_name ?? '—'} {d.doc_type ?? '—'} {d.entity_slug && d.entity_type ? ( {d.entity_name ?? d.entity_slug} ) : ( — )} = 400 ? 'text-danger' : 'text-ink-2'}`}>{fmtInt(d.last_status)} {typeof d.snapshots === 'number' ? fmtInt(d.snapshots) : Array.isArray(d.snapshots) ? fmtInt(d.snapshots.length) : '—'} {fmtInt(d.change_count)} {fmtInt(d.fail_count)} ))} href({ offset: o || undefined })} className="mt-4" /> )} ); }