Initialize local Tabularium documentation monorepo
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import type { AppProps } from "next/app";
|
||||
import "@/styles/globals.css";
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Html, Head, Main, NextScript } from "next/document";
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html lang="zh-CN">
|
||||
<Head />
|
||||
<body><Main /><NextScript /></body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from "next";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import { listDocs, readDoc, type Doc, type DocLink } from "@/lib/docs";
|
||||
|
||||
type Props = { doc: Doc; docs: DocLink[] };
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => ({
|
||||
paths: (await listDocs()).map(({ slug }) => ({ params: { slug } })),
|
||||
fallback: false,
|
||||
});
|
||||
|
||||
export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
|
||||
const slug = params?.slug;
|
||||
if (typeof slug !== "string") return { notFound: true };
|
||||
const docs = await listDocs();
|
||||
if (!docs.some((doc) => doc.slug === slug)) return { notFound: true };
|
||||
return { props: { doc: await readDoc(slug), docs } };
|
||||
};
|
||||
|
||||
export default function DocPage({ doc, docs }: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
return (
|
||||
<>
|
||||
<Head><title>{doc.title} · Tabularium</title></Head>
|
||||
<div className="mx-auto max-w-7xl px-6 py-8">
|
||||
<header className="border-b border-stone-200 pb-6"><Link href="/" className="text-sm font-semibold tracking-widest">ENDOR / TABULARIUM</Link></header>
|
||||
<a href="#content" className="sr-only focus:not-sr-only">跳到正文</a>
|
||||
<div className="grid gap-10 py-10 md:grid-cols-[220px_minmax(0,1fr)] md:gap-16">
|
||||
<nav aria-label="文档导航" className="flex flex-wrap gap-2 self-start md:sticky md:top-8 md:flex-col">
|
||||
{docs.map((item) => <Link key={item.slug} href={`/docs/${item.slug}`} aria-current={item.slug === doc.slug ? "page" : undefined} className={`rounded-lg px-3 py-2 text-sm ${item.slug === doc.slug ? "bg-teal-50 font-medium text-teal-900" : "text-stone-600 hover:bg-stone-100"}`}>{item.title}</Link>)}
|
||||
</nav>
|
||||
<main id="content" className="min-w-0 max-w-3xl">
|
||||
<article className="prose prose-stone max-w-none prose-headings:tracking-tight prose-a:text-teal-800 prose-pre:bg-stone-900 prose-img:rounded-xl">
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]}>{doc.content}</ReactMarkdown>
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { GetStaticProps, InferGetStaticPropsType } from "next";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { listDocs, type DocLink } from "@/lib/docs";
|
||||
|
||||
export const getStaticProps: GetStaticProps<{ docs: DocLink[] }> = async () => ({
|
||||
props: { docs: await listDocs() },
|
||||
});
|
||||
|
||||
export default function Home({ docs }: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
return (
|
||||
<>
|
||||
<Head><title>Tabularium · Endor 文档</title><meta name="description" content="Endor 的本地文档、架构设计与制图档案。" /></Head>
|
||||
<main className="mx-auto max-w-5xl px-6 py-16 md:py-24">
|
||||
<div className="flex items-center justify-between border-b border-stone-200 pb-6 text-sm">
|
||||
<span className="font-semibold tracking-widest">ENDOR / TABULARIUM</span>
|
||||
<span className="rounded-full border border-stone-200 px-3 py-1 text-stone-500">本地文档工作台</span>
|
||||
</div>
|
||||
<p className="mt-16 text-sm tracking-widest text-teal-800">文档 · 设计 · 图形</p>
|
||||
<h1 className="mt-4 text-5xl font-semibold tracking-tight md:text-7xl">Endor 的知识档案。</h1>
|
||||
<p className="mt-6 max-w-2xl text-lg leading-8 text-stone-600">记录系统概念、架构讨论和开发约定,让文字与图形一起演进。</p>
|
||||
<div className="mt-14 grid gap-4 md:grid-cols-2">
|
||||
{docs.map((doc, index) => (
|
||||
<Link key={doc.slug} href={`/docs/${doc.slug}`} className="group rounded-xl border border-stone-200 bg-white p-6 transition hover:border-teal-700 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-teal-700">
|
||||
<span className="font-mono text-xs text-stone-400">{String(index + 1).padStart(2, "0")}</span>
|
||||
<h2 className="mt-4 text-xl font-medium group-hover:text-teal-800">{doc.title} <span aria-hidden="true">↗</span></h2>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user