@@ -1,29 +1,58 @@
11import Head from "next/head";
22import Link from "next/link";
33import React, { useState, useEffect } from "react";
4+
45import Container from "../components/Container";
56import Section from "../components/Section";
67import SingleColumn from "../components/SingleColumn";
78import Header from "../components/Header";
89import Footer from "../components/Footer";
910import BackgroundImage from "../components/BackgroundImage";
10−import TabCarousel from "../components/TabCarousel";
1111import Contact from "../components/Contact";
1212import PostPreview from "../components/PostPreview";
1313import EventPreview from "../components/EventPreview";
14+import Cross from "../components/icons/Cross";
15+import TwoUp from "../components/TwoUp";
1416import {
1517 getAllPosts,
1618 getAllEvents,
1719 formatDate,
1820 getOpenGrantsCount,
1921} from "../lib/lib";
20−import { contact } from "../lib/constants";
22+import { contact, eventKeys } from "../lib/constants";
23+import { useLocalStorage } from "../lib/hooks";
24+
25+const Banner = ({ children, isOpen, href, dismiss }) => {
26+ return (
27+ <div className="w-full flex justify-center bg-green-100">
28+ <SingleColumn>
29+ <div className="w-full layout">
30+ <div className="w-full flex justify-between items-center px-4 md:px-8 py-4">
31+ <a href={href} target="_blank">
32+ {children}
33+ </a>
34+ <button
35+ className="type-ui w-6 h-6 bg-green-400 flex items-center justify-center rounded-full text-white hover:opacity-70"
36+ onClick={(e) => {
37+ e.stopPropagation();
38+ dismiss();
39+ }}
40+ >
41+ <Cross width="10" height="10" fill="#E5F7F1" />
42+ </button>
43+ </div>
44+ </div>
45+ </SingleColumn>
46+ </div>
47+ );
48+};
2149
2250export default function Home({ posts, events, openGrantsCount, search }) {
23− const [tab, setTab] = useState(0);
2451 const [heroButton, setHeroButton] = useState(<div />);
52+ const [bannerElement, setBannerElement] = useState(null);
53+ const [isBannerOpen, setBanner] = useLocalStorage("isBannerOpen", true);
2554
26− const detectOS = () => {
55+ const selectDownloadButton = () => {
2756 const agent = window.navigator.appVersion;
2857 if (agent.includes("Win")) {
2958 return (
@@ -49,17 +78,37 @@ export default function Home({ posts, events, openGrantsCount, search }) {
4978 };
5079
5180 useEffect(() => {
52− setHeroButton(detectOS());
81+ setHeroButton(selectDownloadButton());
5382 }, []);
5483
84+ // Use this pattern when depending on client-side state or conditions like localStorage, user OS or geolocation.
85+ const selectBanner = (isBannerOpen) => {
86+ if (isBannerOpen) {
87+ return (
88+ <Banner
89+ href="http://assembly.urbit.org/"
90+ dismiss={() => setBanner(false)}
91+ >
92+ <p className="text-green-400 font-semibold hover:opacity-70">{`-> Join us October 15-17 for Assembly`}</p>
93+ </Banner>
94+ );
95+ } else {
96+ return null;
97+ }
98+ };
99+
100+ useEffect(() => {
101+ setBannerElement(selectBanner(isBannerOpen));
102+ }, [isBannerOpen]);
103+
55104 return (
56105 <Container>
57106 <Head>
58107 <title>urbit.org</title>
59108 </Head>
109+ {bannerElement}
60110 <SingleColumn>
61111 <Header search={search} />
62−
63112 {
64113 // Hero Statement
65114 }
@@ -197,14 +246,11 @@ export default function Home({ posts, events, openGrantsCount, search }) {
197246 <h2>Blog</h2>
198247 </div>
199248
200− <div className="flex flex-wrap">
201− <div className="w-full md:w-1/2 pr-0 pb-8 md:pr-4">
202− <PostPreview post={posts[0]} key={posts[0].slug} />
203− </div>
204− <div className="w-full md:w-1/2 pl-0 pb-8 md:pl-4">
205− <PostPreview post={posts[1]} key={posts[1].slug} />
206− </div>
207− </div>
249+ <TwoUp>
250+ <PostPreview post={posts[0]} key={posts[0].slug} />
251+ <PostPreview post={posts[1]} key={posts[1].slug} />
252+ </TwoUp>
253+
208254 <Link href="/blog">
209255 <button className="button-lg type-ui text-white bg-green-400">
210256 See More
@@ -220,14 +266,11 @@ export default function Home({ posts, events, openGrantsCount, search }) {
220266 <h2>Events</h2>
221267 </div>
222268
223− <div className="flex flex-wrap">
224− <div className="w-full md:w-1/2 pr-0 pb-8 md:pr-4">
225− <EventPreview event={events[0]} key={events[0].slug} />
226− </div>
227− <div className="w-full md:w-1/2 pl-0 pb-8 md:pl-4">
228− <EventPreview event={events[1]} key={events[1].slug} />
229− </div>
230− </div>
269+ <TwoUp>
270+ <EventPreview event={events[0]} key={events[0].slug} />
271+ <EventPreview event={events[1]} key={events[1].slug} />
272+ </TwoUp>
273+
231274 <Link href="/events">
232275 <button className="button-lg type-ui text-white bg-wall-600">
233276 More Events
@@ -256,21 +299,7 @@ export async function getStaticProps() {
256299 "blog"
257300 );
258301
259− const events = getAllEvents(
260− [
261− "title",
262− "slug",
263− "starts",
264− "guests",
265− "hosts",
266− "registration_url",
267− "ends",
268− "timezone",
269− "youtube",
270− "image",
271− ],
272− "events"
273− );
302+ const events = getAllEvents(eventKeys, "events");
274303
275304 return {
276305 props: { posts, events, openGrantsCount },