2026-08-19 17:40:14 +07:00
|
|
|
import Link from "next/link";
|
|
|
|
|
import { listDocuments } from "@mcpedia/core";
|
|
|
|
|
import type { DocumentMeta } from "@mcpedia/core";
|
2026-08-20 13:08:27 +07:00
|
|
|
import { cookies } from "next/headers";
|
2026-08-19 17:40:14 +07:00
|
|
|
|
2026-08-19 22:56:01 +07:00
|
|
|
// Render at request time — content is in Postgres (not available at build in
|
|
|
|
|
// CI, which has no DB). Request-time rendering is instant at this corpus scale.
|
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
|
|
2026-08-19 17:40:14 +07:00
|
|
|
const SECTIONS = ["docs", "writeups", "research", "notes"] as const;
|
|
|
|
|
|
|
|
|
|
export default async function Home() {
|
|
|
|
|
const all = await listDocuments();
|
|
|
|
|
const bySection = SECTIONS.map((section) => ({
|
|
|
|
|
section,
|
|
|
|
|
docs: all.filter((d) => d.section === section),
|
|
|
|
|
}));
|
|
|
|
|
|
2026-08-20 13:08:27 +07:00
|
|
|
// Auth check for edit/create buttons.
|
|
|
|
|
const cookieStore = await cookies();
|
|
|
|
|
const canEdit = cookieStore.get("mcpedia_admin")?.value != null;
|
|
|
|
|
|
2026-08-19 17:40:14 +07:00
|
|
|
return (
|
|
|
|
|
<div className="space-y-8">
|
|
|
|
|
<section>
|
|
|
|
|
<h1 className="text-2xl font-semibold tracking-tight">MCPedia</h1>
|
|
|
|
|
<p className="mt-2 text-zinc-600 dark:text-zinc-400">
|
|
|
|
|
A content-first knowledge base. Humans read the Web UI; AI agents use
|
|
|
|
|
the MCP server. Both share one Core.
|
|
|
|
|
</p>
|
2026-08-20 13:08:27 +07:00
|
|
|
{canEdit && (
|
|
|
|
|
<Link
|
|
|
|
|
href="/create"
|
|
|
|
|
className="inline-block mt-3 px-4 py-2 text-sm border border-zinc-300 dark:border-zinc-700 rounded hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
|
|
|
|
>
|
|
|
|
|
+ Create Document
|
|
|
|
|
</Link>
|
|
|
|
|
)}
|
2026-08-19 17:40:14 +07:00
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
{bySection.map(({ section, docs }) => (
|
|
|
|
|
<section key={section}>
|
|
|
|
|
<h2 className="text-lg font-medium capitalize mb-2">{section}</h2>
|
|
|
|
|
{docs.length === 0 ? (
|
|
|
|
|
<p className="text-sm text-zinc-500">No documents yet.</p>
|
|
|
|
|
) : (
|
|
|
|
|
<ul className="divide-y divide-zinc-200 dark:divide-zinc-800">
|
|
|
|
|
{docs.map((d: DocumentMeta) => (
|
2026-08-20 13:08:27 +07:00
|
|
|
<li key={d.slug} className="py-2">
|
|
|
|
|
<Link
|
|
|
|
|
href={`/${d.slug}`}
|
|
|
|
|
className="hover:underline font-medium"
|
|
|
|
|
>
|
|
|
|
|
{d.title}
|
|
|
|
|
</Link>
|
|
|
|
|
{canEdit && (
|
2026-08-19 17:40:14 +07:00
|
|
|
<Link
|
2026-08-20 13:08:27 +07:00
|
|
|
href={`/${d.slug}/edit`}
|
|
|
|
|
className="ml-2 text-xs text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300"
|
2026-08-19 17:40:14 +07:00
|
|
|
>
|
2026-08-20 13:08:27 +07:00
|
|
|
✎
|
2026-08-19 17:40:14 +07:00
|
|
|
</Link>
|
2026-08-20 13:08:27 +07:00
|
|
|
)}
|
|
|
|
|
<div className="text-xs text-zinc-500 mt-0.5">
|
|
|
|
|
{d.tags.map((t) => `#${t}`).join(" ")}
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
2026-08-19 17:40:14 +07:00
|
|
|
))}
|
|
|
|
|
</ul>
|
|
|
|
|
)}
|
|
|
|
|
</section>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|