mirror of
https://github.com/urbit/developers.urbit.org.git
synced 2024-09-19 09:49:25 +03:00
287 lines
9.1 KiB
JavaScript
287 lines
9.1 KiB
JavaScript
import Head from "next/head";
|
|
import Link from "next/link";
|
|
import Meta from "../../components/Meta";
|
|
import Header from "../../components/Header";
|
|
import Footer from "../../components/Footer";
|
|
import Card from "../../components/Card";
|
|
import CardText from "../../components/CardText";
|
|
import ContentArea from "../../components/ContentArea";
|
|
import Sidebar from "../../components/Sidebar";
|
|
import TallCard from "../../components/TallCard";
|
|
import Pagination from "../../components/Pagination";
|
|
import {
|
|
Container,
|
|
Section,
|
|
SingleColumn,
|
|
TwoUp,
|
|
Markdown,
|
|
RenderTree,
|
|
getPage,
|
|
getPreviousPost,
|
|
getNextPost,
|
|
} from "@urbit/foundation-design-system";
|
|
import { Comms, Ringsig, Squad } from "../../components/icons";
|
|
import guidesTree from "../../cache/guides.json";
|
|
import { join } from "path";
|
|
import { pair } from '../../lib/util';
|
|
|
|
export default function GuidePage({
|
|
search,
|
|
posts,
|
|
data,
|
|
markdown,
|
|
params,
|
|
previousPost,
|
|
nextPost,
|
|
}) {
|
|
if (!params.slug) {
|
|
return <Landing search={search} posts={posts} />;
|
|
}
|
|
return (
|
|
<>
|
|
<Head>
|
|
<title>{data.title} • Guides • developers.urbit.org</title>
|
|
{Meta(data)}
|
|
</Head>
|
|
<div className="flex h-screen min-h-screen w-screen sidebar">
|
|
<Sidebar search={search}>
|
|
<RenderTree root="/guides" posts={posts.children} />
|
|
</Sidebar>
|
|
<ContentArea
|
|
breadcrumbs={breadcrumbs(posts, params.slug?.slice(0, -1) || "")}
|
|
title={data.title}
|
|
search={search}
|
|
section="Guides"
|
|
params={params}
|
|
>
|
|
<div className="markdown technical">
|
|
<Markdown.render content={JSON.parse(markdown)} />
|
|
</div>
|
|
<div className="flex justify-between mt-16">
|
|
{previousPost === null ? (
|
|
<div className={""} />
|
|
) : (
|
|
<Pagination
|
|
previous
|
|
title="Previous Post"
|
|
post={previousPost}
|
|
className=""
|
|
section={join("guides", params.slug?.slice(0, -1).join("/"))}
|
|
/>
|
|
)}
|
|
{nextPost === null ? (
|
|
<div className={""} />
|
|
) : (
|
|
<Pagination
|
|
next
|
|
title="Next Post"
|
|
post={nextPost}
|
|
className=""
|
|
section={join("guides", params.slug?.slice(0, -1).join("/"))}
|
|
/>
|
|
)}
|
|
</div>
|
|
<div className="flex justify-between items-center mt-16">
|
|
<a
|
|
className="font-semibold rounded-xl block p-2 text-wall-400 hover:text-green-400"
|
|
target="_blank"
|
|
href={`https://github.com/urbit/developers.urbit.org/blob/main/content/guides/${params.slug?.join("/") || "_index"
|
|
}.md`}
|
|
>
|
|
Edit this page on GitHub
|
|
</a>
|
|
<p className="font-semibold block p-2 text-wall-400">Last modified {data.lastModified}</p>
|
|
</div>
|
|
</ContentArea>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const breadcrumbs = (posts, paths) => {
|
|
const results = [<Link href="/guides">Guides</Link>];
|
|
let thisLink = "/guides";
|
|
for (const path of paths) {
|
|
posts = posts.children[path];
|
|
thisLink = join(thisLink, path);
|
|
results.push(
|
|
<span className="px-1">/</span>,
|
|
<Link href={thisLink}>{posts.title}</Link>
|
|
);
|
|
}
|
|
return results;
|
|
};
|
|
|
|
function Landing({ search, posts }) {
|
|
const post = {
|
|
title: "Guides",
|
|
description:
|
|
"Everything you need to know to start building applications on Urbit.",
|
|
};
|
|
|
|
const additionalGuides = pair([
|
|
...posts.children.additional.pages,
|
|
...Object.entries(posts.children.additional.children)
|
|
.filter(([, e]) => e !== "pages").map(([k, v]) => ({ ...v, ...{ slug: k } }))]
|
|
.sort((a, b) => {
|
|
return a.title.toLowerCase().localeCompare(b.title.toLowerCase())
|
|
})
|
|
);
|
|
|
|
return (
|
|
<Container>
|
|
<Head>
|
|
<title>Guides • developers.urbit.org</title>
|
|
{Meta(post)}
|
|
</Head>
|
|
<Header search={search} />
|
|
<SingleColumn>
|
|
<Section>
|
|
<h1>Guides</h1>
|
|
</Section>
|
|
<Section short>
|
|
<h2 className="pt-12">Quickstart: Lightning Tutorials</h2>
|
|
<p className="pt-4">
|
|
Build an application on Urbit in 15 minutes with these instant
|
|
application guides.
|
|
</p>
|
|
<div className="flex flex-col space-y-8 md:space-y-0 md:flex-row md:space-x-8 pt-12">
|
|
<Card
|
|
icon={<Squad />}
|
|
title="Groups Application"
|
|
text="Build an app to create public or private groups"
|
|
className="basis-1/2"
|
|
href="/guides/quickstart/groups-guide"
|
|
/>
|
|
<Card
|
|
icon={<Comms />}
|
|
title="Encrypted Chat Application"
|
|
text="Build your own secure comms tool"
|
|
className="basis-1/2"
|
|
href="/guides/quickstart/chat-guide"
|
|
/>
|
|
</div>
|
|
<div className="flex flex-col space-y-8 md:space-y-0 md:flex-row md:space-x-8 pt-6 pb-12">
|
|
<Card
|
|
icon={<Ringsig />}
|
|
title="Ring Signature Voting App"
|
|
text="Build an anonymous voting app for groups"
|
|
className="basis-1/2"
|
|
href="/guides/quickstart/voting-guide"
|
|
/>
|
|
<div className="basis-1/2" />
|
|
</div>
|
|
</Section>
|
|
<Section short className="space-y-6">
|
|
<h2>Core Curriculum</h2>
|
|
<p>
|
|
Learn to code and how to build applications on Urbit.
|
|
</p>
|
|
<TwoUp>
|
|
<TallCard
|
|
title="Environment Setup"
|
|
description="Learn how to get your urbit development environment configured"
|
|
callout="View Guide"
|
|
href="/guides/core/environment"
|
|
image="https://storage.googleapis.com/media.urbit.org/developers/images/environment.svg"
|
|
className="h-full"
|
|
/>
|
|
<TallCard
|
|
title="Hoon School"
|
|
description="Learn the fundamentals of the Hoon programming language"
|
|
callout="View Guide"
|
|
href="/guides/core/hoon-school"
|
|
image="https://storage.googleapis.com/media.urbit.org/developers/images/hoon-school.svg"
|
|
className="h-full"
|
|
/>
|
|
</TwoUp>
|
|
<TwoUp className="!mt-0">
|
|
<TallCard
|
|
title="App School"
|
|
description="Learn how to build Urbit userspace applications by writing your own Gall agents"
|
|
callout="View Guide"
|
|
href="/guides/core/app-school"
|
|
image="https://storage.googleapis.com/media.urbit.org/developers/images/app-school.svg"
|
|
className="h-full"
|
|
/>
|
|
<TallCard
|
|
title="App School II (Full Stack)"
|
|
description="Learn how to create Gall agents and integrate them into a React front-end"
|
|
callout="View Guide"
|
|
href="/guides/core/app-school-full-stack"
|
|
image="https://storage.googleapis.com/media.urbit.org/developers/images/app-school-fullstack.svg"
|
|
className="h-full"
|
|
/>
|
|
</TwoUp>
|
|
</Section>
|
|
|
|
<Section short>
|
|
<h2 className="my-12">Additional Guides</h2>
|
|
{additionalGuides.map((pair) => {
|
|
return <TwoUp>
|
|
{pair.map((guide) => {
|
|
return <CardText
|
|
title={guide.title}
|
|
text={guide.description}
|
|
className="basis-1/2"
|
|
href={`/guides/additional/${guide.slug}`}
|
|
/>
|
|
})}
|
|
</TwoUp>
|
|
})}
|
|
</Section>
|
|
</SingleColumn>
|
|
<Footer />
|
|
</Container>
|
|
);
|
|
}
|
|
|
|
export async function getStaticProps({ params }) {
|
|
let posts = guidesTree;
|
|
|
|
const { data, content } = getPage(
|
|
join(process.cwd(), "content/guides", params.slug?.join("/") || "/"), true
|
|
);
|
|
|
|
const previousPost =
|
|
getPreviousPost(
|
|
params.slug?.slice(-1).join("") || "guides",
|
|
["title", "slug", "weight"],
|
|
join("guides", params.slug?.slice(0, -1).join("/") || "/"),
|
|
"weight"
|
|
) || null;
|
|
|
|
const nextPost =
|
|
getNextPost(
|
|
params.slug?.slice(-1).join("") || "guides",
|
|
["title", "slug", "weight"],
|
|
join("guides", params.slug?.slice(0, -1).join("/") || "/"),
|
|
"weight"
|
|
) || null;
|
|
|
|
const markdown = JSON.stringify(Markdown.parse({ post: { content: String.raw`${content}` } }));
|
|
return { props: { posts, data, markdown, params, previousPost, nextPost } };
|
|
}
|
|
|
|
export async function getStaticPaths() {
|
|
const posts = guidesTree;
|
|
const slugs = [];
|
|
|
|
const allHrefs = (thisLink, tree) => {
|
|
slugs.push(thisLink, ...tree.pages.map((e) => join(thisLink, e.slug)));
|
|
allHrefsChildren(thisLink, tree.children);
|
|
};
|
|
|
|
const allHrefsChildren = (thisLink, children) => {
|
|
Object.entries(children).map(([childSlug, child]) => {
|
|
allHrefs(join(thisLink, childSlug), child);
|
|
});
|
|
};
|
|
|
|
allHrefs("/guides", posts);
|
|
return {
|
|
paths: slugs,
|
|
fallback: false,
|
|
};
|
|
}
|