@@ -0,0 +1,354 @@
1+import Head from "next/head";
2+import Link from "next/link";
3+import { useRouter } from "next/router";
4+import classnames from "classnames";
5+import React from "react";
6+import { DateTime } from "luxon";
7+import {
8+ Container,
9+ Section,
10+ SingleColumn,
11+ TwoUp,
12+ IntraNav,
13+ getAllPosts,
14+ generateRealtimeDate,
15+ getPage,
16+ Markdown,
17+ getPreviousPost,
18+ getNextPost,
19+} from "@urbit/foundation-design-system";
20+import { getAllEvents } from "../../lib/lib";
21+import { join } from 'path';
22+import Header from "../../components/Header";
23+import Footer from "../../components/Footer";
24+import Contact from "../../components/Contact";
25+import PostPreview from "../../components/PostPreview";
26+import EventPreview from "../../components/EventPreview";
27+import Sidebar from "../../components/Sidebar";
28+import { eventKeys } from "../../lib/constants";
29+import IndexCard from "../../components/ecosystem/IndexCard";
30+import HighlightCard from "../../components/HighlightCard";
31+import fs from "fs";
32+import path from "path";
33+import Meta from "../../components/Meta";
34+import campusTree from "../../cache/campus.json";
35+import { matchEcosystemPost } from "../../lib/lib";
36+
37+export default function Home({
38+ posts,
39+ highlights,
40+ ecosystem,
41+ events,
42+ grantNumbers,
43+ search,
44+ data,
45+ markdown,
46+}) {
47+ const post = {
48+ title: "Urbit",
49+ description: "A clean-slate OS and network for the 21st century.",
50+ image: "https://storage.googleapis.com/media.urbit.org/site/opengraph/urbit.png"
51+ };
52+ return (
53+ <Container>
54+ <Head>
55+ <title>Urbit</title>
56+ {Meta(post, false, true)}
57+ </Head>
58+ <IntraNav ourSite="https://urbit.org" search={search} />
59+
60+ <SingleColumn>
61+ <Header search={search} />
62+
63+ {/* Hero statement */}
64+ <Section className="pb-6">
65+ <div className="flex flex-col space-y-4">
66+ <h1 className="max-w-prose">
67+ [Hero statement goes here. Hero statement goes here.]
68+ </h1>
69+
70+ </div>
71+ </Section>
72+
73+
74+
75+ {/* Brief explanatory paragraph */}
76+ <Section narrow className="pb-1">
77+
78+ <div className="w-full space-y-8 max-w-prose">
79+
80+ <div className="space-y-4">
81+ <p className="">
82+ <span className="font-bold">The internet cannot be saved. </span>
83+ No matter how many unsuspecting youth are press-ganged into derivative careers maintaining,
84+ optimizing, and reskinning this house of cards, the web as we know it is doomed to crumble under
85+ its own weight. The platforms are closed, the data is siloed, and all the exits are shut tight.
86+ </p>
87+ <p>
88+ Well, <i>almost</i> all the exits. For those with the gall to think outside the box, there is another way.
89+ A complete reimagining of networked computing from the OS up, designed to facilitate the construction
90+ of powerful, enduring, and decentralized systems. On <span className="font-bold">Urbit</span>, every computer is a personal server, enabling
91+ all of the functionality of the legacy internet (and more) without requiring users to cede control of their
92+ digital identity to faceless corporations.
93+ </p>
94+ <p>
95+ The Urbit Foundation’s Campus Outreach Program aims to find ambitious students interested in leaving the old
96+ world behind and providing them with the information and resources to help build a better future.
97+ If you fit that description and want us to come to your university,{" "}
98+ <Link href="/campus#contact" passHref>
99+ <a>get in touch.</a>
100+ </Link>{" "}
101+ </p>
102+ </div>
103+ </div>
104+ </Section>
105+
106+ {/*
107+ how to make an in-page link (href to hashtag element id)
108+ <a href="#events"> cheebo </a>
109+ */}
110+
111+
112+ <Section className="pb-12">
113+ <div className="flex flex-col space-y-4 md:space-y-0 md:flex-row md:space-x-4">
114+ <Link href="/campus/software-developers#reading">
115+ <div className="cursor-pointer bg-wall-100 rounded-xl min-h-0 flex-1">
116+ <div className="flex flex-col p-4 h-full relative">
117+ <div className="pt-1">
118+ <p className="mb-2 font-semibold leading-5">Urbit for Software Developers</p>
119+ <p className="text-sm leading-5">Learn how to build on the clean-slate OS and network for the 21st century</p>
120+ </div>
121+ </div>
122+ </div>
123+ </Link>
124+ <Link href="/campus/blockchain-enthusiasts#reading">
125+ <div className="cursor-pointer bg-wall-100 rounded-xl min-h-0 flex-1">
126+ <div className="flex flex-col p-4 h-full relative">
127+ <div className="pt-1">
128+ <p className="mb-2 font-semibold leading-5">Urbit for Blockchain Enthusiasts</p>
129+ <p className="text-sm leading-5">Learn how sound computing and sound digital money fit together</p>
130+ </div>
131+ </div>
132+ </div>
133+ </Link>
134+ <Link href="/campus/everyone-else#reading">
135+ <div className="cursor-pointer bg-wall-100 rounded-xl min-h-0 flex-1">
136+ <div className="flex flex-col p-4 h-full relative">
137+ <div className="pt-1">
138+ <p className="mb-2 font-semibold leading-5">Urbit for Everyone Else</p>
139+ <p className="text-sm leading-5">For those without the technical chops</p>
140+ </div>
141+ </div>
142+ </div>
143+ </Link>
144+ <Link href="#events">
145+ <div className="cursor-pointer bg-wall-100 rounded-xl min-h-0 flex-1">
146+ <div className="flex flex-col p-4 h-full relative">
147+ <div className="pt-1">
148+ <p className="mb-2 font-semibold leading-5">Events</p>
149+ <p className="text-sm leading-5">Find upcoming events and schedule one at your campus</p>
150+ </div>
151+ </div>
152+ </div>
153+ </Link>
154+ </div>
155+ </Section>
156+
157+
158+
159+
160+ {
161+ //embedding test w/ overview page:
162+ }
163+
164+ <Section>
165+ <h3 className="mb-8" id="reading">Attended an event and interested in learning more? Start here:</h3>
166+ <hr></hr>
167+ <br></br>
168+ <div className="flex justify-between sidebar md:space-x-8">
169+ <Sidebar search={search}>
170+ {childPages("/campus", posts.pages)}
171+ </Sidebar>
172+ <div className="markdown max-w-prose">
173+ <h3>{data.title}</h3>
174+ <Markdown.render content={JSON.parse(markdown)} />
175+ </div>
176+ </div>
177+ </Section>
178+
179+ {
180+ //Events
181+ }
182+
183+ <Section className="pb-1">
184+ <hr></hr>
185+ <br></br>
186+ <div className="mt-6">
187+ <h2 className="mb-8" id="events">Events</h2>
188+ <TwoUp>
189+ <EventPreview event={events[0]} className="mb-8" />
190+ {events[1] ? <EventPreview event={events[1]} className="mb-8" /> : <div />}
191+ </TwoUp>
192+ <Link href="/events?tag=campus">
193+ <a className="bg-wall-600 text-white button-lg w-fit">
194+ View All
195+ </a>
196+ </Link>
197+ </div>
198+ </Section>
199+
200+ <div id="contact"></div>
201+
202+ <Section className="pb-12">
203+
204+ <div className="bg-wall-100 w-full p-4 md:p-8 rounded-3xl flex flex-wrap items-center">
205+
206+ <div className="basis-full sm:basis-1/3 pb-4 sm:pb-0">
207+ <img className="rounded-xl w-72" src="https://storage.googleapis.com/media.urbit.org/assembly/assembly-thumb2.jpg" />
208+ </div>
209+ <div className="sm:basis-2/3 sm:pl-6 align-middle">
210+ <h2 className=" text-2xl pb-2" >Get in touch</h2 >
211+ <p className="max-w-prose pb-4">
212+ Not sure how to get started after attending an event? Want to schedule one at your university?
213+ Don't be a stranger. Reach out at the email below, or{" "}
214+ <Link href="https://urbit.org/groups/~tidren-nosryg/campus-outreach" passHref>
215+ <a>find us on Urbit.</a>
216+ </Link>{" "}
217+ </p>
218+ <Link href="mailto:campus@urbit.org">
219+ <a className="button-sm border-2 border-wall-600 text-wall-600 type-sm max-w-fit">
220+ campus@urbit.org
221+ </a>
222+ </Link>
223+ </div>
224+ </div>
225+ </Section>
226+
227+
228+
229+
230+ </SingleColumn>
231+
232+
233+
234+ <Footer />
235+ </Container>
236+ );
237+}
238+
239+const childPages = (thisLink, children, level = 0) => {
240+ const router = useRouter();
241+
242+ const isThisPage = router.asPath === thisLink;
243+
244+ const pageItemClasses = classnames({
245+ "text-base type-ui": level === 0,
246+ "text-wall-400": !isThisPage,
247+ "text-black": isThisPage,
248+ });
249+ return (
250+ <ul className="">
251+ <li className="pb-2">
252+ <Link href="/campus">
253+ <a className={`${pageItemClasses} cursor-pointer`}>Get on Urbit</a>
254+ </Link>
255+ </li>
256+ {children?.map((child) => (
257+ <li className="pb-2">
258+ {pageTree(join(thisLink, child.slug), child, level)}
259+ </li>
260+ ))}
261+ </ul>
262+ );
263+};
264+
265+const pageTree = (thisLink, tree, level = 0) => {
266+ const router = useRouter();
267+
268+ const isThisPage = router.asPath === thisLink;
269+
270+ const pageItemClasses = classnames({
271+ "text-base type-ui": level === 0,
272+ "text-wall-400": !isThisPage,
273+ "text-black": isThisPage,
274+ });
275+
276+ return (
277+ <>
278+ <Link href={thisLink}>
279+ <a className={`${pageItemClasses} cursor-pointer`}>{tree.title}</a>
280+ </Link>
281+ </>
282+ );
283+};
284+
285+export async function getStaticPaths() {
286+ const posts = campusTree;
287+
288+ const slugs = [];
289+
290+ const allHrefs = (thisLink, tree) => {
291+ slugs.push(thisLink, ...tree.pages.map((e) => join(thisLink, e.slug)));
292+ allHrefsChildren(thisLink, tree.children);
293+ };
294+
295+ const allHrefsChildren = (thisLink, children) => {
296+ Object.entries(children).map(([childSlug, child]) => {
297+ allHrefs(join(thisLink, childSlug), child);
298+ });
299+ };
300+
301+ allHrefs("/campus", posts);
302+
303+ return {
304+ paths: slugs,
305+ fallback: false,
306+ };
307+}
308+
309+export async function getStaticProps({ params }) {
310+ const posts = campusTree;
311+
312+ const { data, content } = getPage(
313+ join(process.cwd(), "content/campus", params.slug?.join("/") || "/")
314+ );
315+ const markdown = JSON.stringify(Markdown.parse({ post: { content } }));
316+
317+ const previousPost =
318+ getPreviousPost(
319+ params.slug?.slice(-1).join("") || "campus",
320+ ["title", "slug", "weight"],
321+ join("campus", params.slug?.slice(0, -1).join("/") || "/"),
322+ "weight"
323+ ) || null;
324+
325+ const nextPost =
326+ getNextPost(
327+ params.slug?.slice(-1).join("") || "campus",
328+ ["title", "slug", "weight"],
329+ join("campus", params.slug?.slice(0, -1).join("/") || "/"),
330+ "weight"
331+ ) || null;
332+
333+ const events = getAllEvents(eventKeys, "events").filter((e) => e?.tags?.includes("campus"));
334+
335+ return { props: { posts, data, markdown, params, previousPost, nextPost, events } };
336+}
337+
338+
339+
340+
341+/* export async function getStaticProps() {
342+
343+
344+ const events = getAllEvents(eventKeys, "events").filter((e) => e?.tags?.includes("campus"));
345+
346+ // const { data, content } = getPage(join(process.cwd(), 'content', 'bitcoin'));
347+
348+ return {
349+ props: {
350+ events
351+ }
352+ }
353+}
354+ */