on master help sign in
add Section component WIP
commit0e1e5442521790cd387c32c60bc43d53799a36e7 authorGavin Atkinson <gvnatknsn@protonmail.com> dateTue 13 Jul 2021, 11:49 (5 years ago) parentfa25c37
16 files changed+327−183
components/Footer.js+76−32 components/GrantPreview.js+42 components/Header.js+2−1 components/MenuTray.js+1 components/NewletterSignup.js+1−1 components/Section.js+21 lib/lib.js+45 pages/blog.js+5−4 pages/blog/[slug].js+13−10 pages/events.js+7−6 pages/events/[slug].js+4−2 pages/grants.js+32−56 pages/grants/[slug].js+44−52 pages/index.js+18−15 styles/globals.css+12−4 styles/markdown.module.css+4
components/Footer.js+76−32
@@ -4,101 +4,145 @@ import { contact } from "../lib/constants";
44
55export default function Footer() {
66 return (
7− <footer className="py-32 bg-wall w-full mt-48 flex justify-center">
7+ <footer className="pt-16 md:pt-20 lg:pt-24 bg-wall w-full mt-48 flex justify-center">
88 <SingleColumn>
9− <div className="flex layout-wide">
9+ <div className="flex layout-wide-short">
1010 <div className="w-1/3 flex flex-col flex-shrink">
11− <h4 className="mb-12">Use Urbit</h4>
11+ <h4 className="mb-8">Use Urbit</h4>
1212 <Link href="">
13− <a className="type-sub text-gray">Urbit Client</a>
13+ <div>
14+ <a className="type-sub text-gray">Urbit Client</a>
15+ </div>
1416 </Link>
1517 <Link href="">
16− <a className="mt-2 type-sub text-gray">Urbit Binaries</a>
18+ <div>
19+ <a className="mt-2 type-sub text-gray">Urbit Binaries</a>
20+ </div>
1721 </Link>
1822 <Link href="">
19− <a className="mt-2 type-sub text-gray">Urbit Apps</a>
23+ <div>
24+ <a className="mt-2 type-sub text-gray">Urbit Apps</a>
25+ </div>
2026 </Link>
2127 <Link href="">
22− <a className="mt-2 type-sub text-gray">Hosting Providers</a>
28+ <div>
29+ <a className="mt-2 type-sub text-gray">Hosting Providers</a>
30+ </div>
2331 </Link>
2432 </div>
2533 <div className="w-1/3 flex flex-col flex-shrink">
26− <h4 className="mb-12">About</h4>
34+ <h4 className="mb-8">About</h4>
2735 <Link href="/understanding-urbit">
28− <a className="type-sub text-gray">What's Urbit?</a>
36+ <div>
37+ <a className="type-sub text-gray">What's Urbit?</a>
38+ </div>
2939 </Link>
3040 <Link href="/understanding-urbit/urbit-id">
31− <a className="mt-2 type-sub text-gray">Urbit ID</a>
41+ <div>
42+ <a className="mt-2 type-sub text-gray">Urbit ID</a>
43+ </div>
3244 </Link>
3345 <Link href="/understanding-urbit/urbit-os">
34− <a className="mt-2 type-sub text-gray">Urbit OS</a>
46+ <div>
47+ <a className="mt-2 type-sub text-gray">Urbit OS</a>
48+ </div>
3549 </Link>
3650 <Link href="/faq">
37− <a className="mt-2 type-sub text-gray">FAQ</a>
51+ <div>
52+ <a className="mt-2 type-sub text-gray">FAQ</a>
53+ </div>
3854 </Link>
3955 </div>
4056 <div className="w-1/3 flex flex-col flex-shrink">
41− <h4 className="mb-12">News</h4>
57+ <h4 className="mb-8">News</h4>
4258 <Link href="/blog">
43− <a className="type-sub text-gray">Blog</a>
59+ <div>
60+ <a className="type-sub text-gray">Blog</a>
61+ </div>
4462 </Link>
4563 <Link href="/events">
46− <a className="mt-2 type-sub text-gray">Events</a>
64+ <div>
65+ <a className="mt-2 type-sub text-gray">Events</a>
66+ </div>
4767 </Link>
4868 </div>
4969 </div>
50− <div className="flex layout-wide">
70+ <div className="flex layout-wide-short">
5171 <div className="w-1/3 flex flex-col">
52− <h4 className="mb-12">Develop</h4>
72+ <h4 className="mb-8">Develop</h4>
5373 <Link href="/docs">
54− <a className="type-sub text-gray">Documentation</a>
74+ <div>
75+ <a className="type-sub text-gray">Documentation</a>
76+ </div>
5577 </Link>
5678 <Link href="https://github.com/urbit">
57− <a className="mt-2 type-sub text-gray">Github</a>
79+ <div>
80+ <a className="mt-2 type-sub text-gray">Github</a>
81+ </div>
5882 </Link>
5983 <Link href="https://github.com/urbit/awesome-urbit#http-apis-airlock">
60− <a className="mt-2 type-sub text-gray">Airlock APIs</a>
84+ <div>
85+ <a className="mt-2 type-sub text-gray">Airlock APIs</a>
86+ </div>
6187 </Link>
6288 </div>
6389 <div className="w-1/3 flex flex-col">
64− <h4 className="mb-12">Contribute</h4>
90+ <h4 className="mb-8">Contribute</h4>
6591 <Link href="https://github.com/urbit/urbit/issues">
66− <a className="type-sub text-gray">Issue Tracker</a>
92+ <div>
93+ <a className="type-sub text-gray">Issue Tracker</a>
94+ </div>
6795 </Link>
6896 <Link href="/grants">
69− <a className="mt-2 type-sub text-gray">Urbit Grants</a>
97+ <div>
98+ <a className="mt-2 type-sub text-gray">Urbit Grants</a>
99+ </div>
70100 </Link>
71101 </div>
72102 <div className="w-1/3 flex flex-col">
73− <h4 className="mb-12">Community</h4>
103+ <h4 className="mb-8">Community</h4>
74104 <Link href="https://groups.google.com/a/urbit.org/g/dev?pli=1">
75− <a className="type-sub text-gray">Dev Mailing List</a>
105+ <div>
106+ <a className="type-sub text-gray">Dev Mailing List</a>
107+ </div>
76108 </Link>
77109 <Link href="https://discord.gg/CfSKKaB2ep">
78− <a className="mt-2 type-sub text-gray">Support Discord</a>
110+ <div>
111+ <a className="mt-2 type-sub text-gray">Support Discord</a>
112+ </div>
79113 </Link>
80114 <Link href="https://github.com/urbit/azimuth">
81− <a className="mt-2 type-sub text-gray">Governance</a>
115+ <div>
116+ <a className="mt-2 type-sub text-gray">Governance</a>
117+ </div>
82118 </Link>
83119 <Link href="https://twitter.com/urbit">
84− <a className="mt-2 type-sub text-gray">Twitter</a>
120+ <div>
121+ <a className="mt-2 type-sub text-gray">Twitter</a>
122+ </div>
85123 </Link>
86124 </div>
87125 </div>
88− <div className="flex layout-wide">
126+ <div className="flex layout-wide-short">
89127 <div className="w-1/3">
90128 <Link href="">
91− <a className="type-sub text-gray">Privacy Policy</a>
129+ <div>
130+ <a className="type-sub text-gray">Privacy Policy</a>
131+ </div>
92132 </Link>
93133 </div>
94134 <div className="w-1/3">
95135 <Link href="">
96− <a className="type-sub text-gray">Terms of Service</a>
136+ <div>
137+ <a className="type-sub text-gray">Terms of Service</a>
138+ </div>
97139 </Link>
98140 </div>
99141 <div className="w-1/3">
100142 <Link href="">
101− <a className="type-sub text-gray">{contact.email}</a>
143+ <div>
144+ <a className="type-sub text-gray">{contact.email}</a>
145+ </div>
102146 </Link>
103147 </div>
104148 </div>
components/GrantPreview.jsnew file+42
@@ -0,0 +1,42 @@
1+import classnames from "classnames";
2+import Link from "next/link";
3+
4+export default function GrantPreview({ post }) {
5+ console.log(post);
6+ return (
7+ <div key={post.slug} className="mb-4 cursor-pointer bg-wall rounded-lg">
8+ <Link href={`/grants/${post.slug}`}>
9+ <div className="p-8">
10+ <h3 className="type-ui mb-4">{post.title}</h3>
11+ <p className="mb-4">{post.extra.description}</p>
12+ <div className="flex w-full flex-col md:flex-row md:items-center justify-between">
13+ <p className="text-gray">
14+ <strong>Reward: </strong>
15+ {post.extra.reward} star
16+ {post.extra.reward === 1 ? "" : "s"}
17+ </p>
18+ <div className="flex items-center flex-wrap md:mt-0 mt-4">
19+ {post.taxonomies.grant_type.map((category) => {
20+ const className = classnames({
21+ "bg-blue text-white": category === "Proposal",
22+ "bg-green text-white": category === "Apprenticeship",
23+ "bg-yellow": category === "Bounty",
24+ });
25+ return (
26+ <div className={`${className} badge-sm mr-1 my-1`}>
27+ {category}
28+ </div>
29+ );
30+ })}
31+ {post.taxonomies.grant_category.map((category) => (
32+ <div className="bg-gray text-wall badge-sm mr-1 my-1">
33+ {category}
34+ </div>
35+ ))}
36+ </div>
37+ </div>
38+ </div>
39+ </Link>
40+ </div>
41+ );
42+}
components/Header.js+2−1
@@ -4,6 +4,7 @@ import { useState } from "react";
44import classnames from "classnames";
55import path from "path";
66import MenuTray from "../components/MenuTray";
7+import Section from "../components/Section";
78
89function ActiveLink({ children, href, className }) {
910 const router = useRouter();
@@ -27,7 +28,7 @@ export default function Header(props) {
2728 const [isOpen, toggleTray] = useState(false);
2829
2930 return (
30− <header className="layout-wide flex justify-between items-center pt-12">
31+ <header className="w-full md:w-10/12 flex flex-row justify-between items-center py-8 md:py-10 lg:py-12">
3132 <Link href="/">
3233 <a className="type-ui">Urbit</a>
3334 </Link>
components/MenuTray.js+1
@@ -2,6 +2,7 @@ import classnames from "classnames";
22
33export default function MenuTray(props) {
44 // Locks document scrolling when menu is open
5+
56 if (typeof document !== "undefined") {
67 if (props.isOpen) {
78 document.body.style.overflow = "hidden";
components/NewletterSignup.js+1−1
@@ -12,7 +12,7 @@ export default function NewsletterSignup(props) {
1212 <div className="input-group" id="mc_embed_signup_scroll">
1313 <div className="mc-field-group w-full relative">
1414 <input
15− className={`appearance-none text-gray type-ui black border-${
15+ className={`appearance-none outline-none text-gray type-ui black border-${
1616 props.color || "green"
1717 } border-4 px-3 w-full mb-2 h-16 rounded-xl`}
1818 type="email"
components/Section.jsnew file+21
@@ -0,0 +1,21 @@
1+import classnames from "classnames";
2+
3+// Provides a flexible layout building block
4+export default function Section({
5+ children,
6+ className = "",
7+ short = false,
8+ narrow = false,
9+}) {
10+ const spacing = classnames({
11+ "py-6 md:py-8 lg:py-10": short,
12+ "py-10 md:py-12 lg:py-24": !short,
13+ "md:w-8/12": narrow,
14+ "md:w-10/12": !narrow,
15+ });
16+ return (
17+ <section className={`w-full px-4 md:px-8 ${spacing} ${className}`}>
18+ {children}
19+ </section>
20+ );
21+}
lib/lib.js+45
@@ -301,3 +301,48 @@ export function getOpenGrantsCount() {
301301 }, 0);
302302 return count;
303303}
304+
305+// export function getGrantsByCategory(category, num) {
306+// const paths = fs.readdirSync(directories.grants);
307+// const matches = paths
308+// // Get only markdown files
309+// .filter((path) => parse(path).ext === ".md")
310+// // Parse frontmatter
311+// .map((path) =>
312+// matter(fs.readFileSync(join(directories.grants, path)), options)
313+// )
314+// .filter(grant => grant.data.taxonomies.grant_type === category)
315+// return matches
316+// }
317+
318+export function getSimilarGrants(type, category, num) {
319+ // const paths = getAllPosts(directories.grants);
320+ const bestMatches = getAllPosts(
321+ ["title", "slug", "date", "description", "extra", "taxonomies"],
322+ "grants"
323+ )
324+ .map((grant) => {
325+ return {
326+ grant: grant,
327+ typeWeight: grant.taxonomies.grant_type.reduce((acc, _type) => {
328+ if (type === _type) {
329+ return acc + 1;
330+ }
331+ return acc;
332+ }),
333+ tagWeight: grant.taxonomies.grant_category.reduce((acc, _category) => {
334+ if (category === _category) {
335+ return acc + 1;
336+ }
337+ return acc;
338+ }),
339+ };
340+ })
341+ .sort((a, b) => a.typeWeight + a.tagWeight - b.typeWeight + b.tagWeight)
342+ .map((wrappedGrant) => {
343+ // wrappedGrant.grant.date = JSON.stringify(wrappedGrant.grant.date).replace(/\"/g, "");
344+ return wrappedGrant.grant;
345+ });
346+
347+ return bestMatches.slice(0, num);
348+}
pages/blog.js+5−4
@@ -5,6 +5,7 @@ import Footer from "../components/Footer";
55import Header from "../components/Header";
66import SingleColumn from "../components/SingleColumn";
77import BackgroundImage from "../components/BackgroundImage";
8+import Section from "../components/Section";
89import { getAllPosts, formatDate } from "../lib/lib";
910
1011export default function Blog({ posts, search }) {
@@ -12,7 +13,7 @@ export default function Blog({ posts, search }) {
1213 <Container>
1314 <SingleColumn>
1415 <Header search={search} />
15− <section className="layout-narrow">
16+ <Section narrow>
1617 <div className="measure">
1718 <h2 className="pb-16">Urbit Blog</h2>
1819 <p className="pb-6">
@@ -24,8 +25,8 @@ export default function Blog({ posts, search }) {
2425 new blog posts and events.
2526 </p>
2627 </div>
27− </section>
28− <section className="layout-narrow">
28+ </Section>
29+ <Section narrow>
2930 {posts.map((post) => {
3031 return (
3132 <div key={post.slug} className="mb-24 cursor-pointer">
@@ -66,7 +67,7 @@ export default function Blog({ posts, search }) {
6667 </div>
6768 );
6869 })}
69− </section>
70+ </Section>
7071 </SingleColumn>
7172 <Footer />
7273 </Container>
pages/blog/[slug].js+13−10
@@ -15,6 +15,7 @@ import Header from "../../components/Header";
1515import Footer from "../../components/Footer";
1616import BackgroundImage from "../../components/BackgroundImage";
1717import SingleColumn from "../../components/SingleColumn";
18+import Section from "../../components/Section";
1819import NewsletterSignup from "../../components/NewletterSignup";
1920import PostPreview from "../../components/PostPreview";
2021import { name, contact } from "../../lib/constants";
@@ -36,24 +37,26 @@ export default function Post({
3637 <Container>
3738 <SingleColumn>
3839 <Header search={search} />
39− <section className="flex flex-col layout-narrow">
40+ <Section short narrow>
4041 <h1>{post.title}</h1>
4142 {post.extra.author ? (
42− <div className="type-ui text-gray mt-4">{post.extra.author}</div>
43+ <div className="type-ui text-gray mt-4 md:mt-8 lg:mt-10">
44+ {post.extra.author}
45+ </div>
4346 ) : null}
4447 {post.extra.ship ? (
4548 <div className="type-ui text-gray font-mono">{post.extra.ship}</div>
4649 ) : null}
47− <div className="type-ui text-gray mt-8 md:mt-12 lg:mt-16">
50+ <div className="type-ui text-gray mt-4 md:mt-8 lg:mt-10">
4851 {formatDate(new Date(post.date))}
4952 </div>
50− </section>
51− <div className={"layout-narrow " + markdownStyles["markdown"]}>
53+ </Section>
54+ <Section narrow className={markdownStyles["markdown"]}>
5255 <article
5356 dangerouslySetInnerHTML={{ __html: decode(markdown) }}
5457 ></article>
55− </div>
56− <section className="layout-narrow">
58+ </Section>
59+ <Section narrow>
5760 <div className="measure">
5861 <h4 className="pb-6">
5962 If you’d like to follow our progress, we send monthly updates via
@@ -85,8 +88,8 @@ export default function Post({
8588 {contact.urbitCommunity}
8689 </code>
8790 </h4>
88− </section>
89− <section className="layout-wide flex">
91+ </Section>
92+ <Section className="flex">
9093 {previousPost === null ? (
9194 <div className={"w-1/2 mr-4"} />
9295 ) : (
@@ -105,7 +108,7 @@ export default function Post({
105108 className="ml-4 w-1/2"
106109 />
107110 )}
108− </section>
111+ </Section>
109112 </SingleColumn>
110113 <Footer />
111114 </Container>
pages/events.js+7−6
@@ -6,6 +6,7 @@ import Footer from "../components/Footer";
66import Header from "../components/Header";
77import Search from "../components/Search";
88import SingleColumn from "../components/SingleColumn";
9+import Section from "../components/Section";
910import BackgroundImage from "../components/BackgroundImage";
1011import { getAllPosts, formatDate } from "../lib/lib";
1112
@@ -74,7 +75,7 @@ export default function Events({ pastEvents, currentEvents, search }) {
7475 <Container>
7576 <SingleColumn>
7677 <Header search={search} />
77− <section className="layout-narrow">
78+ <Section narrow>
7879 <div className="measure">
7980 <h2 className="pb-16">Urbit Events</h2>
8081 <p className="pb-6">
@@ -85,24 +86,24 @@ export default function Events({ pastEvents, currentEvents, search }) {
8586 new blog posts and events.
8687 </p>
8788 </div>
88− </section>
89− <section className="layout-narrow">
89+ </Section>
90+ <Section narrow>
9091 <div className="mb-8 table">
9192 <span className="bg-green text-white badge-lg">Coming Soon</span>
9293 </div>
9394 {currentEvents.map((post) => {
9495 return <EventCard event={post} />;
9596 })}
96− </section>
97+ </Section>
9798
98− <section className="layout-narrow">
99+ <Section narrow>
99100 <div className="mb-8 table">
100101 <span className="bg-wall text-gray badge-lg">Past Events</span>
101102 </div>
102103 {pastEvents.map((post) => {
103104 return <EventCard event={post} />;
104105 })}
105− </section>
106+ </Section>
106107 </SingleColumn>
107108 <Footer />
108109 </Container>
pages/events/[slug].js+4−2
@@ -36,10 +36,12 @@ export default function Event({
3636 <Container>
3737 <SingleColumn>
3838 <Header search={search} />
39− <section className="flex flex-col layout-narrow pt-24">
39+ <section className="flex flex-col layout-narrow-heading pt-24">
4040 <h1>{post.title}</h1>
4141 {post.extra.author ? (
42− <div className="type-ui text-gray mt-4">{post.extra.author}</div>
42+ <div className="type-ui text-gray mt-4 md:mt-8 lg:mt-10">
43+ {post.extra.author}
44+ </div>
4345 ) : null}
4446 {post.extra.ship ? (
4547 <div className="type-ui text-gray font-mono">{post.extra.ship}</div>
pages/grants.js+32−56
@@ -9,6 +9,7 @@ import Search from "../components/Search";
99import SingleColumn from "../components/SingleColumn";
1010import BackgroundImage from "../components/BackgroundImage";
1111import TabCarousel from "../components/TabCarousel";
12+import GrantPreview from "../components/GrantPreview";
1213import {
1314 getAllPosts,
1415 formatDate,
@@ -168,19 +169,27 @@ export default function Grants({
168169 }
169170 <section className="layout-wide">
170171 <h2 className="pb-8">Find A Grant</h2>
171− <div className="flex items-center measure pb-2">
172+ <h5 className="text-black font-semibold my-2">Work Programs</h5>
173+ <div className="flex flex-wrap items-center pb-2">
172174 <button
173175 onClick={() => {
174176 setTab(0);
175177 setTypes(types);
176178 }}
177− className={`badge-lg mr-2 ${
179+ className={`badge-lg my-2 mr-2 ${
178180 tab === 0 ? "text-white bg-black" : "text-gray bg-wall"
179181 }`}
180182 >
181183 All
182184 </button>
183185 {types.map((type, index) => {
186+ const className = classnames({
187+ "bg-blue text-white": tab === index + 1 && type === "Proposal",
188+ "bg-green text-white":
189+ tab === index + 1 && type === "Apprenticeship",
190+ "bg-yellow": tab === index + 1 && type === "Bounty",
191+ "bg-wall text-gray": tab !== index + 1,
192+ });
184193 return (
185194 <button
186195 onClick={() => {
@@ -188,82 +197,49 @@ export default function Grants({
188197 setTab(index + 1);
189198 setTypes([type]);
190199 }}
191− className={`badge-lg mr-2 ${
192− tab === index + 1
193− ? "text-white bg-black"
194− : "text-gray bg-wall"
195− }`}
200+ className={`badge-lg mr-2 ${className}`}
196201 >
197202 {type}
198203 </button>
199204 );
200205 })}
201206 </div>
202−
207+ <h5 className="text-black font-semibold my-2">Work Categories</h5>
203208 <div className="flex flex-wrap mb-12">
204209 {categories.map((category) => {
205210 const isActive = activeTags.includes(category);
206211 const activeClasses = classnames({
207212 "bg-green text-white": isActive,
208− "bg-wall text-black": !isActive,
213+ "bg-wall text-gray": !isActive,
209214 });
210215 return (
211216 <button
212217 onClick={() => setTags(toggleTag(activeTags, category))}
213− className={`${activeClasses} badge-sm m-1`}
218+ className={`${activeClasses} badge-sm mr-1 my-1`}
214219 >
215220 {category}
216221 </button>
217222 );
218223 })}
219224 </div>
220−
221− <div className="pb-8 flex">
222− <h4>
223− Showing {filteredPosts.length} grant
224− {filteredPosts.length === 1 ? "" : "s"}
225− </h4>
226− <button
227− className="ml-4"
228− onClick={() => setIncludeCompleted(!includeCompleted)}
229− >
230− {includeCompleted ? "Exclude Completed" : "Include Completed"}
231− </button>
232− </div>
233−
225+ {
226+ <div className="pb-8 flex">
227+ <h4>
228+ Showing {filteredPosts.length} grant
229+ {filteredPosts.length === 1 ? "" : "s"}
230+ </h4>
231+ {
232+ // <button
233+ // className="ml-4"
234+ // onClick={() => setIncludeCompleted(!includeCompleted)}
235+ // >
236+ // {includeCompleted ? "Exclude Completed" : "Include Completed"}
237+ // </button>
238+ }
239+ </div>
240+ }
234241 {filteredPosts.map((post) => {
235− return (
236− <div
237− key={post.slug}
238− className="mb-4 cursor-pointer bg-wall rounded-lg"
239− >
240− <Link href={`/grants/${post.slug}`}>
241− <div className="p-8">
242− <h3 className="type-ui mb-4">{post.title}</h3>
243− <p className="mb-4">{post.extra.description}</p>
244− <div className="flex w-full items-center justify-between">
245− <p className="text-gray">
246− <strong>Reward: </strong>
247− {post.extra.reward} star
248− {post.extra.reward === 1 ? "" : "s"}
249− </p>
250− <div className="flex items-center">
251− {post.taxonomies.grant_type.map((category) => (
252− <div className="bg-black text-wall badge-sm m-1">
253− {category}
254− </div>
255− ))}
256− {post.taxonomies.grant_category.map((category) => (
257− <div className="bg-gray text-wall badge-sm m-1">
258− {category}
259− </div>
260− ))}
261− </div>
262− </div>
263− </div>
264− </Link>
265− </div>
266− );
242+ return <GrantPreview grant={post} />;
267243 })}
268244 </section>
269245 </SingleColumn>
pages/grants/[slug].js+44−52
@@ -2,12 +2,13 @@ import { useRouter } from "next/router";
22import {
33 getPostBySlug,
44 getAllPosts,
5− getNextPost,
6− getPreviousPost,
75 formatDate,
6+ getSimilarGrants,
87} from "../../lib/lib";
98import Head from "next/head";
109import Link from "next/link";
10+import { decode } from "html-entities";
11+import classnames from "classnames";
1112import ErrorPage from "../404";
1213import Container from "../../components/Container";
1314import Markdown from "../../components/Markdown";
@@ -16,18 +17,12 @@ import Footer from "../../components/Footer";
1617import BackgroundImage from "../../components/BackgroundImage";
1718import SingleColumn from "../../components/SingleColumn";
1819import NewsletterSignup from "../../components/NewletterSignup";
19−import PostPreview from "../../components/PostPreview";
20+import GrantPreview from "../../components/GrantPreview";
21+import Section from "../../components/Section";
2022import { name, contact } from "../../lib/constants";
2123import markdownStyles from "../../styles/markdown.module.css";
22−import { decode } from "html-entities";
2324
24−export default function Grant({
25− post,
26− nextPost,
27− markdown,
28− previousPost,
29− search,
30−}) {
25+export default function Grant({ post, markdown, search, similarGrants }) {
3126 const router = useRouter();
3227 if (!router.isFallback && !post?.slug) {
3328 return <ErrorPage />;
@@ -37,7 +32,7 @@ export default function Grant({
3732 <Container>
3833 <SingleColumn>
3934 <Header search={search} />
40− <section className="flex flex-col layout-narrow">
35+ <Section narrow short>
4136 <h1>{post.title}</h1>
4237 {post.extra.author ? (
4338 <div className="type-ui text-gray mt-4">{post.extra.author}</div>
@@ -45,36 +40,41 @@ export default function Grant({
4540 {post.extra.ship ? (
4641 <div className="type-ui text-gray font-mono">{post.extra.ship}</div>
4742 ) : null}
48− <div className="type-ui text-gray mt-8 md:mt-12 lg:mt-16">
43+ <div className="type-ui text-gray mt-4 md:mt-8 lg:mt-10">
4944 {formatDate(new Date(post.date))}
5045 </div>
51− </section>
52− <div className={"layout-narrow " + markdownStyles["markdown"]}>
46+ <div className="flex items-center flex-wrap mt-4 md:mt-8 lg:mt-10">
47+ {post.taxonomies.grant_type.map((category) => {
48+ const className = classnames({
49+ "bg-blue text-white": category === "Proposal",
50+ "bg-green text-white": category === "Apprenticeship",
51+ "bg-yellow": category === "Bounty",
52+ });
53+ return (
54+ <div className={`${className} badge-sm mr-1 my-1`}>
55+ {category}
56+ </div>
57+ );
58+ })}
59+ {post.taxonomies.grant_category.map((category) => (
60+ <div className="bg-gray text-wall badge-sm mr-1 my-1">
61+ {category}
62+ </div>
63+ ))}
64+ </div>
65+ </Section>
66+ <Section className={markdownStyles["markdown"]}>
5367 <article
5468 dangerouslySetInnerHTML={{ __html: decode(markdown) }}
5569 ></article>
56− </div>
70+ </Section>
5771
58− <section className="layout-wide flex">
59− {previousPost === null ? (
60− <div className={"w-1/2 mr-4"} />
61− ) : (
62− <PostPreview
63− title="Previous Post"
64− post={previousPost}
65− className="mr-4 w-1/2"
66− />
67− )}
68− {nextPost === null ? (
69− <div className={"w-1/2 ml-4"} />
70− ) : (
71− <PostPreview
72− title="Next Post"
73− post={nextPost}
74− className="ml-4 w-1/2"
75− />
76− )}
77− </section>
72+ <Section narrow className="flex flex-col">
73+ <h3 className="pb-8">Similar Grants</h3>
74+ {similarGrants.map((grant) => {
75+ return <GrantPreview post={grant} />;
76+ })}
77+ </Section>
7878 </SingleColumn>
7979 <Footer />
8080 </Container>
@@ -83,30 +83,22 @@ export default function Grant({
8383
8484//
8585export async function getStaticProps({ params }) {
86− const nextPost =
87− getNextPost(
88− params.slug,
89− ["title", "slug", "date", "description", "extra"],
90− "grants"
91− ) || null;
92−
93− const previousPost =
94− getPreviousPost(
95− params.slug,
96− ["title", "slug", "date", "description", "extra"],
97− "grants"
98− ) || null;
99−
10086 const post = getPostBySlug(
10187 params.slug,
102− ["title", "slug", "date", "description", "content", "extra"],
88+ ["title", "slug", "date", "description", "content", "extra", "taxonomies"],
10389 "grants"
10490 );
10591
92+ const similarGrants = getSimilarGrants(
93+ post.taxonomies.grant_type,
94+ post.taxonomies.grant_category,
95+ 4
96+ );
97+
10698 const markdown = await Markdown({ post });
10799
108100 return {
109− props: { post, markdown, nextPost, previousPost },
101+ props: { post, markdown, similarGrants },
110102 };
111103}
112104
pages/index.js+18−15
@@ -2,6 +2,7 @@ import Head from "next/head";
22import Link from "next/link";
33import React, { useState, useEffect } from "react";
44import Container from "../components/Container";
5+import Section from "../components/Section";
56import SingleColumn from "../components/SingleColumn";
67import Header from "../components/Header";
78import Footer from "../components/Footer";
@@ -53,16 +54,18 @@ export default function Home({ posts, events, openGrantsCount, search }) {
5354 {
5455 // Hero Statement
5556 }
56− <section className="layout-narrow">
57− <h1>A general-purpose,</h1>
58− <h1>peer-to-peer,</h1>
59− <h1>personal computing system.</h1>
60− </section>
57+ <Section narrow>
58+ <div>
59+ <h1>A general-purpose,</h1>
60+ <h1>peer-to-peer,</h1>
61+ <h1>personal computing system.</h1>
62+ </div>
63+ </Section>
6164
6265 {
6366 // Introducing Port
6467 }
65− <section className="layout-wide hidden md:flex">
68+ <Section className="hidden md:flex">
6669 <div className="bg-wall w-11/12 hero-card-height rounded-3xl flex">
6770 <div className="pt-20 pl-12 w-7/12">
6871 <div className="pb-8">
@@ -84,12 +87,12 @@ export default function Home({ posts, events, openGrantsCount, search }) {
8487 </div>
8588 <div className="w-full hero-image-height hero-image mt-8" />
8689 </div>
87− </section>
90+ </Section>
8891
8992 {
9093 // Grants
9194 }
92− <section className="layout-narrow">
95+ <Section narrow>
9396 <div className="flex flex-col md:flex-row md:items-center items-start measure pb-12">
9497 <h2 className="m-0 p-0 mr-4 md:mb-0 mb-4">Urbit Grants</h2>
9598 <Link href="/grants">
@@ -129,12 +132,12 @@ export default function Home({ posts, events, openGrantsCount, search }) {
129132 </Link>
130133 </div>
131134 </div>
132− </section>
135+ </Section>
133136
134137 {
135138 // Build on Urbit Developer CTA
136139 }
137− <section className="layout-narrow">
140+ <Section narrow>
138141 <div className="measure">
139142 <h2 className="pb-12">Build on Urbit</h2>
140143 <h4 className="pb-12">
@@ -170,12 +173,12 @@ export default function Home({ posts, events, openGrantsCount, search }) {
170173 Read the Developer Docs
171174 </button>
172175 </div>
173− </section>
176+ </Section>
174177
175178 {
176179 // Blog and Events Combo Section
177180 }
178− <section className="layout-narrow">
181+ <Section narrow>
179182 <div className="flex items-center measure pb-12">
180183 <button
181184 onClick={() => setTab(0)}
@@ -255,12 +258,12 @@ export default function Home({ posts, events, openGrantsCount, search }) {
255258 </div>
256259 </div>
257260 </TabCarousel>
258− </section>
261+ </Section>
259262
260263 {
261264 // Newsletter and social media
262265 }
263− <section className="layout-narrow">
266+ <Section narrow>
264267 <div className="measure">
265268 <h2 className="m-0 p-0 mr-4 pb-12">Stay In Touch</h2>
266269 <p className="pb-6">
@@ -293,7 +296,7 @@ export default function Home({ posts, events, openGrantsCount, search }) {
293296 {contact.urbitCommunity}
294297 </code>
295298 </div>
296− </section>
299+ </Section>
297300 </SingleColumn>
298301
299302 <Footer />
styles/globals.css+12−4
@@ -17,14 +17,22 @@ p a {
1717 @apply text-green;
1818}
1919
20−.layout-narrow {
21− @apply w-full md:w-8/12 px-4 md:px-8 pb-20 md:pb-32 lg:pb-48;
20+/* .layout-narrow {
21+ @apply w-full md:w-8/12 px-4 md:px-8 py-10 md:py-12 lg:py-24;
2222}
2323
2424.layout-wide {
25− @apply w-full md:w-10/12 px-4 md:px-8 pb-20 md:pb-32 lg:pb-48;
25+ @apply w-full md:w-10/12 px-4 md:px-8 py-10 md:py-12 lg:py-24;
2626}
2727
28+.layout-narrow-heading {
29+ @apply w-full md:w-8/12 px-4 md:px-8 py-8 md:py-10 lg:py-12;
30+}
31+
32+.layout-wide-short {
33+ @apply w-full md:w-10/12 px-4 md:px-8 py-8 md:py-10 lg:py-12;
34+} */
35+
2836h1,
2937.type-h1 {
3038 @apply text-4xl md:text-5xl lg:text-6xl font-bold leading-tight;
@@ -80,7 +88,7 @@ button {
8088}
8189
8290.badge-sm {
83− @apply flex type-ui-small px-2 lg:px-3 items-center justify-center h-8 md:h-10 rounded-full;
91+ @apply flex type-ui-small px-3 lg:px-4 items-center justify-center h-8 md:h-10 rounded-full;
8492}
8593
8694.badge-lg {
styles/markdown.module.css+4
@@ -12,6 +12,10 @@
1212 @apply pt-0 mt-0;
1313}
1414
15+.markdown *:first-child figure {
16+ @apply pt-0 mt-0;
17+}
18+
1519.markdown p,
1620.markdown ul,
1721.markdown ol,