@@ -0,0 +1,314 @@
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";
14+ generateRealtimeDate,
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";
32+import path from "path";
33+import Meta from "../../components/Meta";
34+import campusTree from "../../cache/campus.json";
35+import { matchEcosystemPost } from "../../lib/lib";
37+export default function Home({
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"
56+ {Meta(post, false, true)}
58+ <IntraNav ourSite="https://urbit.org" search={search} />
61+ <Header search={search} />
63+ {/* Hero statement */}
64+ <Section className="pb-6">
65+ <div className="flex flex-col space-y-4">
66+ <h1 className="max-w-prose">
67+ Campus Outreach Program
70+ Leave your mark on the future. Build on Urbit.
77+ {/* Brief explanatory paragraph */}
78+ <Section className="sm:flex sm:space-x-8 space-y-8 sm:space-y-0">
80+ <div className="sm:w-2/3 space-y-8">
81+ <div className="space-y-4">
82+ <p className="type-ui">
83+ For those with the will to think outside the box: a complete reimagining of networked computing from the OS up, designed to facilitate the construction
84+ of powerful, enduring, and decentralized systems.
86+ <p className="type-ui">
87+ The Urbit Foundation’s Campus Outreach Program aims to find ambitious students interested in leaving the old
88+ world behind and providing them with the information and resources to help build a better future.
89+ If you fit that description and want us to come to your university,{" "}
90+ <Link href="/campus#contact" passHref>
98+ <div className="sm:w-1/3">
100+ <Link href="https://airtable.com/shrmfUVpMskWw145u" passHref>
101+ <a className="button-lg bg-green-400 text-white type-ui max-w-fit">
110+ how to make an in-page link (href to hashtag element id)
111+ <a href="#events"> cheebo </a>
117+ //funnel, repurposed from /overview page:
119+ <div id="reading"></div>
123+ <h2 className="pb-16">Learn about Urbit for</h2>
125+ <div className="flex justify-between sidebar md:space-x-8">
126+ <Sidebar search={search}>
127+ {childPages("/campus", posts.pages)}
129+ <div className={'markdown max-w-prose ' + data.slug }>
130+ <Markdown.render content={JSON.parse(markdown)} />
141+ <Section className="pb-1">
144+ <div className="mt-6">
145+ <h2 className="mb-8" id="events">Events</h2>
146+ {events.length > 0 ? (
148+ <EventPreview event={events[0]} className="mb-8" />
149+ {events[1] ? <EventPreview event={events[1]} className="mb-8" /> : <div />}
152+ <p className="pb-8">No events yet — check back later.</p>
154+ <Link href="/events?tag=campus">
155+ <a className="bg-wall-600 text-white button-lg w-fit">
162+ <div id="contact"></div>
164+ <Section className="pb-12">
166+ <div className="bg-wall-100 w-full p-4 md:p-8 rounded-3xl flex flex-wrap items-center">
168+ <div className="sm:pl-2 align-middle">
169+ <h2 className=" text-2xl pb-2" >Get in touch</h2 >
170+ <p className="max-w-prose pb-4">
171+ Not sure how to get started after attending an event? Want to schedule one at your university?
172+ Don't be a stranger. Reach out at the email below, or{" "}
173+ <Link href="https://urbit.org/groups/~tidren-nosryg/campus-outreach" passHref>
174+ <a>find us on Urbit.</a>
177+ <Link href="mailto:campus@urbit.org">
178+ <a className="button-sm border-2 border-wall-600 text-wall-600 type-sm max-w-fit">
198+const childPages = (thisLink, children, level = 0) => {
199+ const router = useRouter();
201+ const isThisPage = router.asPath === thisLink || router.asPath === `${thisLink}#reading`;
203+ const pageItemClasses = classnames({
204+ "text-base type-ui": level === 0,
205+ "text-wall-400": !isThisPage,
206+ "text-black": isThisPage,
210+ <li className="pb-2">
211+ <Link href="/campus#reading">
212+ <a className={`${pageItemClasses} cursor-pointer`}>Software Developers</a>
215+ {children?.map((child) => (
216+ <li className="pb-2">
217+ {pageTree(join(thisLink, child.slug), child, level)}
224+const pageTree = (thisLink, tree, level = 0) => {
225+ const router = useRouter();
228+ const isThisPage = router.asPath.includes(thisLink);
230+ const pageItemClasses = classnames({
231+ "text-base type-ui": level === 0,
232+ "text-wall-400": !isThisPage,
233+ "text-black": isThisPage,
238+ <Link href={thisLink + "#reading"}>
239+ <a className={`${pageItemClasses} cursor-pointer`}>{tree.title}</a>
245+export async function getStaticPaths() {
246+ const posts = campusTree;
250+ const allHrefs = (thisLink, tree) => {
251+ slugs.push(thisLink, ...tree.pages.map((e) => join(thisLink, e.slug)));
252+ allHrefsChildren(thisLink, tree.children);
255+ const allHrefsChildren = (thisLink, children) => {
256+ Object.entries(children).map(([childSlug, child]) => {
257+ allHrefs(join(thisLink, childSlug), child);
261+ allHrefs("/campus", posts);
269+export async function getStaticProps({ params }) {
270+ const posts = campusTree;
272+ const { data, content } = getPage(
273+ join(process.cwd(), "content/campus", params.slug?.join("/") || "/")
275+ const markdown = JSON.stringify(Markdown.parse({ post: { content } }));
277+ const previousPost =
279+ params.slug?.slice(-1).join("") || "campus",
280+ ["title", "slug", "weight"],
281+ join("campus", params.slug?.slice(0, -1).join("/") || "/"),
287+ params.slug?.slice(-1).join("") || "campus",
288+ ["title", "slug", "weight"],
289+ join("campus", params.slug?.slice(0, -1).join("/") || "/"),
293+ const allEvents = getAllEvents(eventKeys, "events");
294+ const events = allEvents.filter((e) => e?.tags?.includes("campus")) || [];
296+ return { props: { posts, data, markdown, params, previousPost, nextPost, events } };
301+/* export async function getStaticProps() {
304+ const events = getAllEvents(eventKeys, "events").filter((e) => e?.tags?.includes("campus"));
306+ // const { data, content } = getPage(join(process.cwd(), 'content', 'bitcoin'));