on master help sign in
mobile 2
e03e0f6Gavin Atkinson
components/Header.js+39−4
@@ -3,6 +3,7 @@ import { useRouter } from "next/router";
3import { useState } from "react";
3import { useState } from "react";
4import classnames from "classnames";
4import classnames from "classnames";
5import path from "path";
5import path from "path";
6+import { useLockBodyScroll } from "../lib/hooks";
6
7
7function ActiveLink({ children, href, className }) {
8function ActiveLink({ children, href, className }) {
8 const router = useRouter();
9 const router = useRouter();
@@ -21,12 +22,28 @@ function ActiveLink({ children, href, className }) {
21 );
22 );
22}
23}
23
24
24−function MenuTray({ props }) {
25+function MenuTray(props) {
26+ // Locks document scrolling when menu is open
27+ if (typeof document !== "undefined") {
28+ if (props.isOpen) {
29+ document.body.style.overflow = "hidden";
30+ } else {
31+ document.body.style.overflow = "visible";
32+ }
33+ }
34+
25 const activeClasses = classnames({
35 const activeClasses = classnames({
26− "": props.isOpen,
36+ "tray-menu-open": props.isOpen,
37+ "tray-menu-closed": !props.isOpen,
27 });
38 });
28
39
29− return <nav></nav>;
40+ return (
41+ <nav
42+ className={`w-screen h-screen bg-wall flex top-0 left-0 flex-col p-8 fixed ${activeClasses}`}
43+ >
44+ {props.children}
45+ </nav>
46+ );
30}
47}
31
48
32// This is the header for the index page
49// This is the header for the index page
@@ -58,8 +75,26 @@ export default function Header() {
58 {
75 {
59 // Small screen header
76 // Small screen header
60 }
77 }
78+
61 <div className="block md:hidden">
79 <div className="block md:hidden">
80+ <MenuTray isOpen={isOpen}>
81+ <ActiveLink className="mr-5 type-h3" href="/docs">
82+ Docs
83+ </ActiveLink>
84+ <ActiveLink className="mr-5 type-h3" href="/blog">
85+ Blog
86+ </ActiveLink>
87+ <ActiveLink className="mr-5 type-h3" href="/events">
88+ Events
89+ </ActiveLink>
90+ <button className="button-sm bg-wall text-gray">
91+ Search Urbit.org<div className="ml-4 text-lightGray">⌘K</div>
92+ </button>
93+ </MenuTray>
94+ <button
62− <button onClick={() => toggleTray(!isOpen)}>
95+ onClick={() => toggleTray(!isOpen)}
96+ className="z-10 absolute right-8"
97+ >
63 {isOpen ? (
98 {isOpen ? (
64 <svg
99 <svg
65 width="16"
100 width="16"
lib/hooks.jsnew file+12
@@ -0,0 +1,12 @@
1+import { useState, useLayoutEffect } from "react";
2+
3+export function useLockBodyScroll() {
4+ useLayoutEffect(() => {
5+ // Get original body overflow
6+ const originalStyle = window.getComputedStyle(document.body).overflow;
7+ // Prevent scrolling on mount
8+ document.body.style.overflow = "hidden";
9+ // Re-enable scrolling when component unmounts
10+ return () => (document.body.style.overflow = originalStyle);
11+ }, []); // Empty array ensures effect is only run on mount and unmount
12+}
pages/index.js+78−29
@@ -20,12 +20,18 @@ export default function Home({ posts, events }) {
20 <SingleColumn>
20 <SingleColumn>
21 <Header />
21 <Header />
22
22
23+ {
24+ // Hero Statement
25+ }
23 <section className="layout-narrow">
26 <section className="layout-narrow">
24 <h1>A general-purpose,</h1>
27 <h1>A general-purpose,</h1>
25 <h1>peer-to-peer,</h1>
28 <h1>peer-to-peer,</h1>
26 <h1>personal computing system.</h1>
29 <h1>personal computing system.</h1>
27 </section>
30 </section>
28
31
32+ {
33+ // Introducing Port
34+ }
29 <section className="layout-wide hidden md:flex">
35 <section className="layout-wide hidden md:flex">
30 <div className="bg-wall w-11/12 hero-card-height rounded-3xl flex">
36 <div className="bg-wall w-11/12 hero-card-height rounded-3xl flex">
31 <div className="pt-20 pl-12 w-7/12">
37 <div className="pt-20 pl-12 w-7/12">
@@ -47,24 +53,29 @@ export default function Home({ posts, events }) {
47 </div>
53 </div>
48 </section>
54 </section>
49
55
56+ {
57+ // Grants
58+ }
50 <section className="layout-narrow">
59 <section className="layout-narrow">
51− <div className="flex items-center measure pb-12">
60+ <div className="flex flex-col md:flex-row md:items-center measure pb-12">
52− <h2 className="m-0 p-0 mr-4">Urbit Grants</h2>
61+ <h2 className="m-0 p-0 mr-4 md:mb-0 mb-4">Urbit Grants</h2>
62+ <div>
53− <button className="bg-green text-white badge-lg">32 Open</button>
63+ <button className="bg-green text-white badge-lg">32 Open</button>
64+ </div>
54 </div>
65 </div>
55− <div className="flex w-full items-center bg-washedGreen px-8 py-8 rounded-xl">
66+ <div className="flex flex-col md:flex-row w-full items-center bg-washedGreen px-8 py-8 rounded-xl">
56 <div className="flex items-center flex-col p-4 w-full">
67 <div className="flex items-center flex-col p-4 w-full">
57 <h2 className="text-green">200+</h2>
68 <h2 className="text-green">200+</h2>
58 <h3 className="text-green text-center pt-2">
69 <h3 className="text-green text-center pt-2">
59 Urbit stars awarded
70 Urbit stars awarded
60 </h3>
71 </h3>
61 </div>
72 </div>
62− <div className="h-24 w-4 bg-lightGreen" />
73+ <div className="h-0 w-0 md:h-24 md:w-4 bg-lightGreen" />
63 <div className="flex items-center flex-col p-4 w-full">
74 <div className="flex items-center flex-col p-4 w-full">
64 <h2 className="text-green">1M+</h2>
75 <h2 className="text-green">1M+</h2>
65 <h3 className="text-green text-center pt-2">USD Rewarded</h3>
76 <h3 className="text-green text-center pt-2">USD Rewarded</h3>
66 </div>
77 </div>
67− <div className="h-24 w-4 bg-lightGreen" />
78+ <div className="h-0 w-0 md:h-24 md:w-4 bg-lightGreen" />
68 <div className="flex items-center flex-col p-4 w-full">
79 <div className="flex items-center flex-col p-4 w-full">
69 <h2 className="text-green">90+</h2>
80 <h2 className="text-green">90+</h2>
70 <h3 className="text-green text-center pt-2">Grants completed</h3>
81 <h3 className="text-green text-center pt-2">Grants completed</h3>
@@ -81,6 +92,9 @@ export default function Home({ posts, events }) {
81 </div>
92 </div>
82 </section>
93 </section>
83
94
95+ {
96+ // Build on Urbit Developer CTA
97+ }
84 <section className="layout-narrow">
98 <section className="layout-narrow">
85 <div className="measure">
99 <div className="measure">
86 <h2 className="pb-12">Build on Urbit</h2>
100 <h2 className="pb-12">Build on Urbit</h2>
@@ -119,6 +133,9 @@ export default function Home({ posts, events }) {
119 </div>
133 </div>
120 </section>
134 </section>
121
135
136+ {
137+ // Blog and Events Combo Section
138+ }
122 <section className="layout-narrow">
139 <section className="layout-narrow">
123 <div className="flex items-center measure pb-12">
140 <div className="flex items-center measure pb-12">
124 <button
141 <button
@@ -140,16 +157,27 @@ export default function Home({ posts, events }) {
140 </div>
157 </div>
141
158
142 <TabCarousel index={tab}>
159 <TabCarousel index={tab}>
143− <div className="blog-grid">
160+ <div className="flex flex-wrap">
161+ <PostPreview
144− {posts.slice(0, 4).map((post, i) => {
162+ post={posts[0]}
145− return (
163+ className={`w-full md:w-1/2 pr-0 pb-8 md:pr-4`}
164+ key={posts[0].slug}
165+ />
166+ <PostPreview
167+ post={posts[1]}
168+ className={`w-full md:w-1/2 pl-0 pb-8 md:pl-4`}
169+ key={posts[1].slug}
170+ />
146− <PostPreview
171+ <PostPreview
147− post={post}
172+ post={posts[3]}
148− className={`blog-grid-${i}`}
173+ className={`w-full md:w-1/2 pr-0 pb-8 md:pr-4`}
149− key={post.slug}
174+ key={posts[3].slug}
150− />
175+ />
151− );
176+ <PostPreview
152− })}
177+ post={posts[4]}
178+ className={`w-full md:w-1/2 pl-0 pb-8 md:pl-4`}
179+ key={posts[4].slug}
180+ />
153 <div>
181 <div>
154 <Link href="/blog">
182 <Link href="/blog">
155 <button className="button-lg type-ui text-white bg-black">
183 <button className="button-lg type-ui text-white bg-black">
@@ -158,20 +186,41 @@ export default function Home({ posts, events }) {
158 </Link>
186 </Link>
159 </div>
187 </div>
160 </div>
188 </div>
161− <div className="blog-grid">
189+ <div className="flex flex-wrap">
162− {events.slice(0, 4).map((event, i) => {
190+ <PostPreview
163− return (
191+ post={events[0]}
192+ className={`w-full md:w-1/2 pr-0 pb-8 md:pr-4`}
193+ key={events[0].slug}
194+ />
195+ <PostPreview
196+ post={events[1]}
197+ className={`w-full md:w-1/2 pl-0 pb-8 md:pl-4`}
198+ key={events[1].slug}
199+ />
200+ <PostPreview
201+ post={events[3]}
202+ className={`w-full md:w-1/2 pr-0 pb-8 md:pr-4`}
203+ key={events[3].slug}
204+ />
164− <PostPreview
205+ <PostPreview
165− post={event}
206+ post={events[4]}
166− className={`blog-grid-${i}`}
207+ className={`w-full md:w-1/2 pl-0 pb-8 md:pl-4`}
167− key={event.slug}
208+ key={events[4].slug}
168− />
209+ />
169− );
210+ <div>
170− })}
211+ <Link href="/events">
212+ <button className="button-lg type-ui text-white bg-black">
213+ More Events
214+ </button>
215+ </Link>
216+ </div>
171 </div>
217 </div>
172 </TabCarousel>
218 </TabCarousel>
173 </section>
219 </section>
174
220
221+ {
222+ // Newsletter and social media
223+ }
175 <section className="layout-narrow">
224 <section className="layout-narrow">
176 <div className="measure">
225 <div className="measure">
177 <h2 className="m-0 p-0 mr-4 pb-12">Stay In Touch</h2>
226 <h2 className="m-0 p-0 mr-4 pb-12">Stay In Touch</h2>
@@ -199,12 +248,12 @@ export default function Home({ posts, events }) {
199 Discord
248 Discord
200 </a>
249 </a>
201 </h4>
250 </h4>
202− <h4 className="mt-6">
251+ <div className="mt-4 flex flex-wrap items-baseline">
203− Boot Urbit and join{" "}
252+ <h4 className="mr-2">Boot Urbit and join</h4>
204 <code className="bg-wall p-2 rounded-lg">
253 <code className="bg-wall p-2 rounded-lg">
205 {contact.urbitCommunity}
254 {contact.urbitCommunity}
206 </code>
255 </code>
207− </h4>
256+ </div>
208 </section>
257 </section>
209 </SingleColumn>
258 </SingleColumn>
210
259
styles/globals.css+10−24
@@ -122,32 +122,18 @@ a:hover {
122 justify-content: center;
122 justify-content: center;
123}
123}
124
124
125−.blog-grid {
125+.bg-img {
126− width: 100%;
126+ background-repeat: no-repeat;
127− display: grid;
127+ background-position: center center;
128− gap: 3rem;
128+ @apply bg-wall;
129− grid-template-columns: 1fr 1fr;
130− grid-template-rows: 1fr 1fr;
131− grid-template-areas:
132− "blog-grid-0 blog-grid-1"
133− "blog-grid-2 blog-grid-3";
134}
129}
135
130
136−.blog-grid-0 {
131+.tray-menu-open {
137− grid-area: blog-grid-0;
132+ transform: translateX(0);
138−}
133+ transition: transform 200ms;
139−.blog-grid-1 {
140− grid-area: blog-grid-1;
141−}
142−.blog-grid-2 {
143− grid-area: blog-grid-2;
144−}
145−.blog-grid-3 {
146− grid-area: blog-grid-3;
147}
134}
148
135
149−.bg-img {
136+.tray-menu-closed {
150− background: silver;
137+ transform: translateX(100vw);
151− background-repeat: no-repeat;
138+ transition: transform 200ms;
152− background-position: center center;
153}
139}