@@ -0,0 +1,143 @@
1+import Head from "next/head";
2+import { useRouter } from "next/router";
3+import classnames from "classnames";
4+import Meta from "../../components/Meta";
5+import {
6+ Container,
7+ SingleColumn,
8+ Section,
9+ Markdown,
10+ IntraNav,
11+} from "foundation-design-system";
12+import { join } from "path";
13+import { getPage, getPreviousPost, getNextPost } from "../../lib/lib";
14+import Header from "../../components/Header";
15+import Footer from "../../components/Footer";
16+import Sidebar from "../../components/Sidebar";
17+import overviewTree from "../../cache/overview.json";
18+import Link from "next/link";
19+
20+export default function Overview({ posts, data, markdown, search }) {
21+ return (
22+ <Container>
23+ <Head>
24+ <title>{data.title} • Overview • Urbit</title>
25+ {Meta(data)}
26+ </Head>
27+ <IntraNav ourSite="https://urbit.org" search={search} />
28+ <SingleColumn>
29+ <Header />
30+ <Section>
31+ <h1>Overview</h1>
32+ </Section>
33+ <Section>
34+ <div className="flex space-x-16 justify-between sidebar">
35+ <Sidebar>{childPages("/overview", posts.pages)}</Sidebar>
36+ <div className="markdown max-w-prose">
37+ <h3>{data.title}</h3>
38+ <Markdown.render content={JSON.parse(markdown)} />
39+ </div>
40+ </div>
41+ </Section>
42+ </SingleColumn>
43+ <Footer />
44+ </Container>
45+ );
46+}
47+
48+const childPages = (thisLink, children, level = 0) => {
49+ const router = useRouter();
50+
51+ const isThisPage = router.asPath === thisLink;
52+
53+ const pageItemClasses = classnames({
54+ "text-base type-ui": level === 0,
55+ "text-wall-400": !isThisPage,
56+ "text-black": isThisPage,
57+ });
58+ return (
59+ <ul className="">
60+ <li className="pb-2">
61+ <Link href="/overview">
62+ <a className={`${pageItemClasses} cursor-pointer`}>Introduction</a>
63+ </Link>
64+ </li>
65+ {children?.map((child) => (
66+ <li className="pb-2">
67+ {pageTree(join(thisLink, child.slug), child, level)}
68+ </li>
69+ ))}
70+ </ul>
71+ );
72+};
73+
74+const pageTree = (thisLink, tree, level = 0) => {
75+ const router = useRouter();
76+
77+ const isThisPage = router.asPath === thisLink;
78+
79+ const pageItemClasses = classnames({
80+ "text-base type-ui": level === 0,
81+ "text-wall-400": !isThisPage,
82+ "text-black": isThisPage,
83+ });
84+
85+ return (
86+ <>
87+ <Link href={thisLink}>
88+ <a className={`${pageItemClasses} cursor-pointer`}>{tree.title}</a>
89+ </Link>
90+ </>
91+ );
92+};
93+
94+export async function getStaticProps({ params }) {
95+ const posts = overviewTree;
96+
97+ const { data, content } = getPage(
98+ join(process.cwd(), "content/overview", params.slug?.join("/") || "/")
99+ );
100+ const markdown = JSON.stringify(Markdown.parse({ post: { content } }));
101+
102+ const previousPost =
103+ getPreviousPost(
104+ params.slug?.slice(-1).join("") || "overview",
105+ ["title", "slug", "weight"],
106+ join("overview", params.slug?.slice(0, -1).join("/") || "/"),
107+ "weight"
108+ ) || null;
109+
110+ const nextPost =
111+ getNextPost(
112+ params.slug?.slice(-1).join("") || "overview",
113+ ["title", "slug", "weight"],
114+ join("overview", params.slug?.slice(0, -1).join("/") || "/"),
115+ "weight"
116+ ) || null;
117+
118+ return { props: { posts, data, markdown, params, previousPost, nextPost } };
119+}
120+
121+export async function getStaticPaths() {
122+ const posts = overviewTree;
123+
124+ const slugs = [];
125+
126+ const allHrefs = (thisLink, tree) => {
127+ slugs.push(thisLink, ...tree.pages.map((e) => join(thisLink, e.slug)));
128+ allHrefsChildren(thisLink, tree.children);
129+ };
130+
131+ const allHrefsChildren = (thisLink, children) => {
132+ Object.entries(children).map(([childSlug, child]) => {
133+ allHrefs(join(thisLink, childSlug), child);
134+ });
135+ };
136+
137+ allHrefs("/overview", posts);
138+
139+ return {
140+ paths: slugs,
141+ fallback: false,
142+ };
143+}