on master help sign in
remove max width on md, add prev/next post getter
082f2fcGavin Atkinson
components/Header.js+6−3
@@ -1,10 +1,13 @@
1+import Link from 'next/link'
2+
1export default function Header() {
3export default function Header() {
2 return (
4 return (
3 <header className="layout-wide flex justify-between items-center pt-8">
5 <header className="layout-wide flex justify-between items-center pt-8">
4− <a href="/" className="type-ui">Urbit</a>
6+ <Link href="/"><a className="type-ui">Urbit</a></Link>
5 <nav className="flex items-center">
7 <nav className="flex items-center">
6− <a href="/docs" className="type-ui text-gray mr-6">Docs</a>
8+ <Link href="/docs"><a className="type-ui text-gray mr-6">Docs</a></Link>
7− <a href="/blog" className="type-ui text-gray mr-6">Blog</a>
9+ <Link href="/blog"><a className="type-ui text-gray mr-6">Blog</a></Link>
10+ <Link href="/events"><a className="type-ui text-gray mr-6">Events</a></Link>
8 <button className="button-sm">Download Port</button>
11 <button className="button-sm">Download Port</button>
9 </nav>
12 </nav>
10 </header>
13 </header>
components/Markdown.js+1−1
@@ -5,7 +5,7 @@ import remark2react from 'remark-react'
5
5
6function P({ children }) {
6function P({ children }) {
7 return (
7 return (
8− <p className='leading-snug max-w-prose'>
8+ <p className='leading-snug'>
9 {children}
9 {children}
10 </p>
10 </p>
11 )
11 )
components/SingleColumn.jsnew file+7
@@ -0,0 +1,7 @@
1+export default function SingleColumn({children}) {
2+ return (
3+ <div className='flex flex-col w-full items-center max-w-screen-xl'>
4+ {children}
5+ </div>
6+ )
7+ }
lib/lib.js+24
@@ -70,6 +70,30 @@ export function getAllPosts(fields = [], key) {
70 return posts
70 return posts
71}
71}
72
72
73+export function getNextPost(slug, fields = [], key) {
74+ let resultPost = null
75+
76+ getAllPosts(fields, key)
77+ .forEach((post, index, array) => {
78+ if (post.slug === slug) {
79+ resultPost = array[index + 1]
80+ }
81+ })
82+ return resultPost
83+}
84+
85+export function getPreviousPost(slug, fields = [], key) {
86+ let resultPost = null
87+
88+ getAllPosts(fields, key)
89+ .forEach((post, index, array) => {
90+ if (post.slug === slug) {
91+ resultPost = array[index - 1]
92+ }
93+ })
94+ return resultPost
95+}
96+
73// export function dateFormat(d) {
97// export function dateFormat(d) {
74// const wk = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
98// const wk = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
75// const mn =["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
99// const mn =["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
pages/blog.js+12−15
@@ -3,6 +3,8 @@ import Link from 'next/link'
3import { useState } from 'react';
3import { useState } from 'react';
4import Container from '../components/Container'
4import Container from '../components/Container'
5import Footer from '../components/Footer'
5import Footer from '../components/Footer'
6+import Header from '../components/Header'
7+import SingleColumn from '../components/SingleColumn'
6import { getAllPosts } from '../lib/lib'
8import { getAllPosts } from '../lib/lib'
7
9
8function BackgroundImage(props) {
10function BackgroundImage(props) {
@@ -11,25 +13,19 @@ function BackgroundImage(props) {
11 )
13 )
12}
14}
13
15
14−export default function Home({ posts }) {
16+export default function BlogPost({ posts }) {
15
17
16 return (
18 return (
17 <Container>
19 <Container>
18− <header className="layout-wide flex justify-between items-center pt-8">
20+ <SingleColumn>
19− <a href="/" className="type-ui">Urbit</a>
21+ <Header />
20− <nav className="flex items-center">
21− <a href="/docs" className="type-ui text-gray mr-6">Docs</a>
22− <a href="/blog" className="type-ui text-gray mr-6">Blog</a>
23− <button className="button-sm">Download Port</button>
24− </nav>
25− </header>
26− <section className="layout-narrow pt-48">
22+ <section className="layout-narrow pt-48">
27− {
23+ {
28− posts.map((post) => <div key={post.slug}>{post.title}</div>)
24+ posts.map((post) => <div key={post.slug}>{post.title}</div>)
29− }
25+ }
30− </section>
26+ </section>
27+ </SingleColumn>
31 <Footer/>
28 <Footer/>
32−
33 </Container>
29 </Container>
34 )
30 )
35}
31}
@@ -47,3 +43,4 @@ export async function getStaticProps() {
47 props: { posts },
43 props: { posts },
48 }
44 }
49}
45}
46+
pages/blog/[slug].js+51−21
@@ -1,17 +1,19 @@
1import { useRouter } from 'next/router'
1import { useRouter } from 'next/router'
2−import { getPostBySlug, getAllPosts, markdownToHtml } from '../../lib/lib'
2+import { getPostBySlug, getAllPosts, getNextPost, getPreviousPost } from '../../lib/lib'
3import Head from 'next/head'
3import Head from 'next/head'
4+import Link from 'next/link'
4import ErrorPage from '../404'
5import ErrorPage from '../404'
5import Container from '../../components/Container'
6import Container from '../../components/Container'
6import Markdown from '../../components/Markdown'
7import Markdown from '../../components/Markdown'
7import Header from '../../components/Header'
8import Header from '../../components/Header'
8−import Footer from '../components/Footer'
9+import Footer from '../../components/Footer'
10+import SingleColumn from '../../components/SingleColumn'
9
11
10import {
12import {
11 name,
13 name,
12} from '../../lib/constants'
14} from '../../lib/constants'
13
15
14−export default function Post({ post }) {
16+export default function Post({ post, nextPost, previousPost }) {
15 const router = useRouter()
17 const router = useRouter()
16 if (!router.isFallback && !post?.slug) {
18 if (!router.isFallback && !post?.slug) {
17 return <ErrorPage />
19 return <ErrorPage />
@@ -19,30 +21,58 @@ export default function Post({ post }) {
19
21
20 return (
22 return (
21 <Container>
23 <Container>
24+ <SingleColumn>
22− <Header />
25+ <Header />
23− <section className="layout-narrow pt-48">
26+ <section className="layout-narrow pt-48">
24− <article>
27+ <article>
25− <Markdown post={post} />
28+ <Markdown post={post} />
26− </article>
29+ </article>
27− </section>
30+ </section>
31+ <section className="layout-narrow pt-48">
32+
33+ <Link href={nextPost.slug}>{nextPost.title}</Link>
34+ <Link href={previousPost.slug}>{previousPost.title}</Link>
35+
36+ </section>
28− <Footer />
37+ <Footer />
38+ </SingleColumn>
29 </Container>
39 </Container>
30 )
40 )
31}
41}
42+
32//
43//
33export async function getStaticProps({ params }) {
44export async function getStaticProps({ params }) {
45+
46+ const nextPost = getNextPost(params.slug, [
47+ 'title',
48+ 'slug',
49+ 'date',
50+ 'description',
51+ 'extra',
52+ ], 'blog')
53+
54+ const previousPost = getPreviousPost(params.slug, [
55+ 'title',
56+ 'slug',
57+ 'date',
58+ 'description',
59+ 'extra',
60+ ], 'blog')
61+
62+ // console.log(previousPost, nextPost)
63+
34− const post = getPostBySlug(params.slug, [
64+ const post = getPostBySlug(params.slug, [
35− 'title',
65+ 'title',
36− 'slug',
66+ 'slug',
37− 'date',
67+ 'date',
38− 'description',
68+ 'description',
39− 'content',
69+ 'content',
40− 'extra',
70+ 'extra',
41− ], 'blog')
71+ ], 'blog')
42
72
43− return {
73+ return {
44− props: { post },
74+ props: { post, nextPost, previousPost },
45− }
75+ }
46}
76}
47
77
48export async function getStaticPaths() {
78export async function getStaticPaths() {
pages/index.js+122−119
@@ -2,6 +2,7 @@ import Head from 'next/head'
2import Link from 'next/link'
2import Link from 'next/link'
3import { useState } from 'react';
3import { useState } from 'react';
4import Container from '../components/Container'
4import Container from '../components/Container'
5+import SingleColumn from '../components/SingleColumn'
5import Header from '../components/Header'
6import Header from '../components/Header'
6import Footer from '../components/Footer'
7import Footer from '../components/Footer'
7import { getAllPosts } from '../lib/lib'
8import { getAllPosts } from '../lib/lib'
@@ -27,134 +28,136 @@ export default function Home({ posts, events }) {
27
28
28 return (
29 return (
29 <Container>
30 <Container>
31+ <SingleColumn>
30− <Header />
32+ <Header />
31−
33+
32− <section className="layout-narrow pt-48">
34+ <section className="layout-narrow pt-48">
33− <h1>A general-purpose, peer-to-peer, personal computing system.</h1>
35+ <h1>A general-purpose, peer-to-peer, personal computing system.</h1>
34− </section>
36+ </section>
35−
37+
36− <section className="layout-wide pt-48">
38+ <section className="layout-wide pt-48">
37− <div className="bg-yellow w-11/12 hero-card-height rounded-3xl flex">
39+ <div className="bg-yellow w-11/12 hero-card-height rounded-3xl flex">
38− <div className="pt-20 pl-12 w-7/12">
40+ <div className="pt-20 pl-12 w-7/12">
39− <div className="pb-7">
41+ <div className="pb-7">
40− <h2 className="text-gray p-0 m-0">Introducing</h2><h2 className="p-0 m-0">Port</h2>
42+ <h2 className="text-gray p-0 m-0">Introducing</h2><h2 className="p-0 m-0">Port</h2>
43+ </div>
44+ <h3 className="pb-5">The Urbit client, now in beta.</h3>
45+ <p className="pb-5">Port lets you... Sed iste iusto deserunt id dolores dignissimos est expedita. Earum ut et nemo et voluptatem sunt ea. Delectus sed unde fugit reiciendis. Voluptatum animi laborum fugit dolores. Dolore qui asperiores eum iusto debitis sit. Et vel dolores voluptas.</p>
46+ <button className="button-lg type-ui mb-5">Download For Mac</button>
47+ <a className="">View on GitHub</a>
41 </div>
48 </div>
42− <h3 className="pb-5">The Urbit client, now in beta.</h3>
43− <p className="pb-5">Port lets you... Sed iste iusto deserunt id dolores dignissimos est expedita. Earum ut et nemo et voluptatem sunt ea. Delectus sed unde fugit reiciendis. Voluptatum animi laborum fugit dolores. Dolore qui asperiores eum iusto debitis sit. Et vel dolores voluptas.</p>
44− <button className="button-lg type-ui mb-5">Download For Mac</button>
45− <a className="">View on GitHub</a>
46− </div>
47− <div className="bg-black w-full rounded-xl hero-image-height hero-image mt-8" />
49+ <div className="bg-black w-full rounded-xl hero-image-height hero-image mt-8" />
48− </div>
49− </section>
50−
51− <section className="layout-narrow pt-48">
52− <div className='measure'>
53− <h2 className="pb-12">Develop on Urbit</h2>
54− <h3 className="pb-12">
55− Urbit is a personal OS designed from scratch to run peer-to-peer applications.
56− </h3>
57− <p className="pb-12">
58− The entire OS is a <a>single pure function</a> that provides application developers with strong guarantees: automated persistence and memory management, repeatable builds, and support for hot code reloading.
59− </p>
60− <button className="button-lg type-ui">Contribute</button>
61− </div>
62− </section>
63−
64− <section className="layout-narrow pt-48">
65− <div className='flex items-center measure pb-12'>
66− <h2 className="m-0 p-0 mr-4">Urbit Grants</h2>
67− <button className="flex bg-green type-ui px-4 items-center justify-center h-12 rounded-full">32 Open</button>
68− </div>
69− <h3 className="pb-12 measure">
70− Contribute to Urbit and get rewarded with address space.
71− </h3>
72− <div className="flex w-full items-center bg-lightGreen px-8 py-10 rounded-xl">
73− <div className="flex items-center flex-col p-4 w-full">
74− <h2>200+</h2>
75− <h3 className="text-gray text-center pt-4">Urbit stars awarded</h3>
76 </div>
50 </div>
77− <div className="h-32 w-4 bg-green" />
51+ </section>
52+
53+ <section className="layout-narrow pt-48">
78− <div className="flex items-center flex-col p-4 w-full">
54+ <div className='measure'>
79− <h2>1M+</h2>
55+ <h2 className="pb-12">Develop on Urbit</h2>
80− <h3 className="text-gray text-center pt-4">USD Rewarded</h3>
56+ <h3 className="pb-12">
81− </div>
57+ Urbit is a personal OS designed from scratch to run peer-to-peer applications.
58+ </h3>
82− <div className="h-32 w-4 bg-green" />
59+ <p className="pb-12">
83− <div className="flex items-center flex-col p-4 w-full">
60+ The entire OS is a <a>single pure function</a> that provides application developers with strong guarantees: automated persistence and memory management, repeatable builds, and support for hot code reloading.
84− <h2>90+</h2>
61+ </p>
85− <h3 className="text-gray text-center pt-4">Grants completed</h3>
62+ <button className="button-lg type-ui">Contribute</button>
86 </div>
63 </div>
87− </div>
88− <div className='measure py-12'>
89− <p className="pb-12">We regularly give away address space to reward community contributions, including education, promotion, and development.</p>
90− <button className="button-lg">View Grants</button>
91− </div>
92− </section>
64+ </section>
93−
94− <section className="layout-narrow pt-48">
95− <div className='flex items-center measure pb-12'>
96− <button
97− onClick={() => setTab(0)}
98− className={`tab-button-lg mr-6 ${tab === 0 ? 'text-black' : 'text-gray'}`}>
99− Blog
100− </button>
101− <button
102− onClick={() => setTab(1)}
103− className={`tab-button-lg ${tab === 1 ? 'text-black' : 'text-gray'}`}>
104− Events
105− </button>
106− </div>
107
65
108− <TabCarousel index={tab}>
66+ <section className="layout-narrow pt-48">
109− <div className="blog-grid">
67+ <div className='flex items-center measure pb-12'>
110− {
68+ <h2 className="m-0 p-0 mr-4">Urbit Grants</h2>
111− posts.slice(0, 4).map((post, i) => {
69+ <button className="flex bg-green type-ui px-4 items-center justify-center h-12 rounded-full">32 Open</button>
112− return (
70+ </div>
113− <div className={`border-black cursor-pointer blog-grid-${i}`} key={post.slug}>
71+ <h3 className="pb-12 measure">
114− <Link href={'/blog/' + post.slug} key={`post-${post.slug}`}>
72+ Contribute to Urbit and get rewarded with address space.
115− <div>
73+ </h3>
116− <BackgroundImage src={post.extra.image || ''} />
74+ <div className="flex w-full items-center bg-lightGreen px-8 py-10 rounded-xl">
117− <p className='text-black mt-2'>{post.title}</p>
75+ <div className="flex items-center flex-col p-4 w-full">
118− <caption className='text-black mt-2'>{post.extra.author}</caption>
76+ <h2>200+</h2>
119− <caption className='text-gray'>{post.date}</caption>
77+ <h3 className="text-gray text-center pt-4">Urbit stars awarded</h3>
120− </div>
78+ </div>
121− </Link>
79+ <div className="h-32 w-4 bg-green" />
122− </div>
80+ <div className="flex items-center flex-col p-4 w-full">
123− )
81+ <h2>1M+</h2>
124− })
82+ <h3 className="text-gray text-center pt-4">USD Rewarded</h3>
125− }
83+ </div>
126− <div>
84+ <div className="h-32 w-4 bg-green" />
127− <Link href="/blog"><button className="button-lg type-ui">Read More</button></Link>
85+ <div className="flex items-center flex-col p-4 w-full">
86+ <h2>90+</h2>
87+ <h3 className="text-gray text-center pt-4">Grants completed</h3>
128 </div>
88 </div>
129 </div>
89 </div>
130− <div className="blog-grid">
90+ <div className='measure py-12'>
131− {
91+ <p className="pb-12">We regularly give away address space to reward community contributions, including education, promotion, and development.</p>
132− events.slice(0, 4).map((event, i) => {
92+ <button className="button-lg">View Grants</button>
133− return (
134− <div className={`border-black cursor-pointer blog-grid-${i}`} key={event.slug}>
135− <Link href={'/events/' + event.slug} key={`post-${event.slug}`}>
136− <div>
137− <BackgroundImage src={event.extra.image || ''} />
138− <p className='text-black mt-2'>{event.title || ''}</p>
139− <caption className='text-gray'>{event.date}</caption>
140− </div>
141− </Link>
142− </div>
143− )
144− })
145− }
146 </div>
93 </div>
147− </TabCarousel>
94+ </section>
148
95
96+ <section className="layout-narrow pt-48">
97+ <div className='flex items-center measure pb-12'>
98+ <button
99+ onClick={() => setTab(0)}
100+ className={`tab-button-lg mr-6 ${tab === 0 ? 'text-black' : 'text-gray'}`}>
101+ Blog
102+ </button>
103+ <button
104+ onClick={() => setTab(1)}
105+ className={`tab-button-lg ${tab === 1 ? 'text-black' : 'text-gray'}`}>
106+ Events
107+ </button>
108+ </div>
109+
110+ <TabCarousel index={tab}>
111+ <div className="blog-grid">
112+ {
113+ posts.slice(0, 4).map((post, i) => {
114+ return (
115+ <div className={`border-black cursor-pointer blog-grid-${i}`} key={post.slug}>
116+ <Link href={'/blog/' + post.slug} key={`post-${post.slug}`}>
117+ <div>
118+ <BackgroundImage src={post.extra.image || ''} />
119+ <p className='text-black mt-2'>{post.title}</p>
120+ <caption className='text-black mt-2'>{post.extra.author}</caption>
121+ <caption className='text-gray'>{post.date}</caption>
122+ </div>
123+ </Link>
124+ </div>
125+ )
126+ })
127+ }
128+ <div>
129+ <Link href="/blog"><button className="button-lg type-ui">Read More</button></Link>
130+ </div>
131+ </div>
132+ <div className="blog-grid">
133+ {
134+ events.slice(0, 4).map((event, i) => {
135+ return (
136+ <div className={`border-black cursor-pointer blog-grid-${i}`} key={event.slug}>
137+ <Link href={'/events/' + event.slug} key={`post-${event.slug}`}>
138+ <div>
139+ <BackgroundImage src={event.extra.image || ''} />
140+ <p className='text-black mt-2'>{event.title || ''}</p>
141+ <caption className='text-gray'>{event.date}</caption>
142+ </div>
143+ </Link>
144+ </div>
145+ )
146+ })
147+ }
148+ </div>
149+ </TabCarousel>
150+
151+
152+ </section>
149
153
150− </section>
151−
152− <section className="layout-narrow pt-48">
154+ <section className="layout-narrow pt-48">
153− <div className='measure pb-12'>
155+ <div className='measure pb-12'>
154− <h2 className="m-0 p-0 mr-4 pb-12">Inside the OS</h2>
156+ <h2 className="m-0 p-0 mr-4 pb-12">Inside the OS</h2>
155− <p>We send monthly emails on system improvements, upcoming events, and community spotlights.</p>
157+ <p>We send monthly emails on system improvements, upcoming events, and community spotlights.</p>
156− </div>
158+ </div>
157− </section>
159+ </section>
160+ </SingleColumn>
158
161
159 <Footer />
162 <Footer />
160
163
styles/globals.css+2−7
@@ -23,16 +23,11 @@ p a {
23}
23}
24
24
25.layout-narrow {
25.layout-narrow {
26− /* padding-left: 16.6667%;
26+ @apply w-8/12;
27− padding-right: 16.6667%;
28− */
29− width: 66.6667%;
30}
27}
31
28
32.layout-wide {
29.layout-wide {
33− /* padding-left: 8.3334%;
30+ @apply w-10/12;
34− padding-right: 8.3334%; */
35− width: 83.3334%;
36}
31}
37
32
38h1, .type-h1 {
33h1, .type-h1 {
styles/markdown.module.css+1−11
@@ -18,19 +18,9 @@
18 }
18 }
19
19
20 .markdown h3 {
20 .markdown h3 {
21− @apply font-semibold mt-8 mb-4;
21+ @apply font-semibold mt-8 mb-4;
22 }
22 }
23
23
24− .markdown p,
25− .markdown h1,
26− .markdown h2,
27− .markdown h3,
28− .markdown h4,
29− .markdown h5 {
30− @apply max-w-prose;
31− }
32−
33−
34 .markdown img {
24 .markdown img {
35 width: 100%;
25 width: 100%;
36 height: auto;
26 height: auto;