on master help sign in
pages: add queries for blog, events pages for tags
2c85488Matilde Park
lib/constants.js+1
@@ -24,6 +24,7 @@ export const eventKeys = [
24 "dark",
24 "dark",
25 "timezone",
25 "timezone",
26 "darken_image",
26 "darken_image",
27+ "tags"
27];
28];
28
29
29export const postKeys = [
30export const postKeys = [
pages/blog.js+26−13
@@ -14,8 +14,14 @@ import Footer from "../components/Footer";
14import Header from "../components/Header";
14import Header from "../components/Header";
15import BackgroundImage from "../components/BackgroundImage";
15import BackgroundImage from "../components/BackgroundImage";
16import { contact } from "../lib/constants";
16import { contact } from "../lib/constants";
17+import { useRouter } from "next/router";
17
18
18export default function Blog({ posts, search }) {
19export default function Blog({ posts, search }) {
20+ const router = useRouter();
21+ const { tag } = router.query;
22+
23+ const filteredPosts = tag ? posts.filter((e) => e?.tags?.includes(tag)) : posts;
24+
19 const post = {
25 const post = {
20 title: "Blog",
26 title: "Blog",
21 description:
27 description:
@@ -31,20 +37,27 @@ export default function Blog({ posts, search }) {
31 <SingleColumn>
37 <SingleColumn>
32 <Header search={search} />
38 <Header search={search} />
33 <Section>
39 <Section>
40+ {tag ?
41+ <><h1 className="pb-16">{filteredPosts.length} posts tagged "{tag}"</h1>
42+ <p>
43+ For more posts, return to the <Link href="/blog">blog index</Link>.
44+ </p>
45+ </>
34− <h1 className="pb-16">Blog</h1>
46+ : <><h1 className="pb-16">Blog</h1>
35− <div className="md:columns-2 gap-x-8">
47+ <div className="md:columns-2 gap-x-8">
36− <p className="pb-6 md:pb-0">
48+ <p className="pb-6 md:pb-0">
37− Stories from the broader Urbit community, the Urbit Foundation,
49+ Stories from the broader Urbit community, the Urbit Foundation,
38− and the many people contributing to Urbit.
50+ and the many people contributing to Urbit.
39− </p>
51+ </p>
40− <p>
52+ <p>
41− <a href={contact.newsletter}>Subscribe</a> to the Urbit Newsletter
53+ <a href={contact.newsletter}>Subscribe</a> to the Urbit Newsletter
42− for regular updates, including new blog posts and events.
54+ for regular updates, including new blog posts and events.
43− </p>
55+ </p>
44− </div>
56+ </div>
57+ </>}
45 </Section>
58 </Section>
46 <Section>
59 <Section>
47− {posts.map((post) => {
60+ {filteredPosts.map((post) => {
48 const date = generateDisplayDate(post.date);
61 const date = generateDisplayDate(post.date);
49 return (
62 return (
50 <div key={post.slug} className="mb-20 cursor-pointer">
63 <div key={post.slug} className="mb-20 cursor-pointer">
@@ -107,7 +120,7 @@ export default function Blog({ posts, search }) {
107
120
108export async function getStaticProps() {
121export async function getStaticProps() {
109 const posts = getAllPosts(
122 const posts = getAllPosts(
110− ["title", "slug", "date", "description", "extra"],
123+ ["title", "slug", "date", "description", "tags", "extra"],
111 "blog",
124 "blog",
112 "date"
125 "date"
113 );
126 );
pages/events.js+17−3
@@ -15,11 +15,15 @@ import Footer from "../components/Footer";
15import Header from "../components/Header";
15import Header from "../components/Header";
16import EventPreview from "../components/EventPreview";
16import EventPreview from "../components/EventPreview";
17import { getAllEvents, pair } from "../lib/lib";
17import { getAllEvents, pair } from "../lib/lib";
18+import { useRouter } from "next/router";
18
19
19import { eventKeys } from "../lib/constants";
20import { eventKeys } from "../lib/constants";
20
21
21export default function Events({ events, search }) {
22export default function Events({ events, search }) {
22 const [selected, setSelected] = useState("All");
23 const [selected, setSelected] = useState("All");
24+ const router = useRouter();
25+ const { tag } = router.query;
26+
23 const post = {
27 const post = {
24 title: "Events",
28 title: "Events",
25 description: "In-person, remote, and recorded events about Urbit.",
29 description: "In-person, remote, and recorded events about Urbit.",
@@ -27,6 +31,13 @@ export default function Events({ events, search }) {
27
31
28 const now = DateTime.now();
32 const now = DateTime.now();
29
33
34+ const tagFilter = (event) => {
35+ if (tag) {
36+ return event?.tags?.includes(tag)
37+ } else {
38+ return true;
39+ }
40+ }
30 const selectionFilter = (event) => {
41 const selectionFilter = (event) => {
31 if (selected === "All") {
42 if (selected === "All") {
32 return true;
43 return true;
@@ -38,7 +49,7 @@ export default function Events({ events, search }) {
38 };
49 };
39
50
40 const pastEvents = pair(
51 const pastEvents = pair(
41− events.filter(selectionFilter).filter((event) => {
52+ events.filter(selectionFilter).filter(tagFilter).filter((event) => {
42 const ends = generateRealtimeDate(event.ends);
53 const ends = generateRealtimeDate(event.ends);
43 return ends < now;
54 return ends < now;
44 })
55 })
@@ -47,6 +58,7 @@ export default function Events({ events, search }) {
47 const futureEvents = pair(
58 const futureEvents = pair(
48 events
59 events
49 .filter(selectionFilter)
60 .filter(selectionFilter)
61+ .filter(tagFilter)
50 .filter((event) => {
62 .filter((event) => {
51 const starts = generateRealtimeDate(event.starts);
63 const starts = generateRealtimeDate(event.starts);
52 return starts > now;
64 return starts > now;
@@ -64,7 +76,7 @@ export default function Events({ events, search }) {
64 );
76 );
65
77
66 const happeningNow = pair(
78 const happeningNow = pair(
67− events.filter(selectionFilter).filter((event) => {
79+ events.filter(selectionFilter).filter(tagFilter).filter((event) => {
68 const starts = generateRealtimeDate(event.starts);
80 const starts = generateRealtimeDate(event.starts);
69 const ends = generateRealtimeDate(event.ends);
81 const ends = generateRealtimeDate(event.ends);
70 return starts < DateTime.now() && ends > now;
82 return starts < DateTime.now() && ends > now;
@@ -96,7 +108,9 @@ export default function Events({ events, search }) {
96 <Header search={search} />
108 <Header search={search} />
97 <Section>
109 <Section>
98 <div className="measure">
110 <div className="measure">
111+ {tag
112+ ? <h1 className="pb-16">{events.filter(tagFilter).length} events tagged "{tag}"</h1>
99− <h1 className="pb-16">Events</h1>
113+ : <h1 className="pb-16">Events</h1>}
100 <div className="flex space-x-2">
114 <div className="flex space-x-2">
101 <SelectedButton selection="All" text="All Events" />
115 <SelectedButton selection="All" text="All Events" />
102 <SelectedButton selection="In-person" text="In-person" />
116 <SelectedButton selection="In-person" text="In-person" />