Add /news/archive and /news/[year]/[term] pages #146
Merged
a3thakra
merged 4 commits from adi-news-archive
into adi-news-content
2 years ago
@ -0,0 +1,7 @@ |
||||
.page { |
||||
padding-bottom: calc(30rem / 16); |
||||
} |
||||
|
||||
.term { |
||||
color: var(--primary-accent); |
||||
} |
@ -0,0 +1,84 @@ |
||||
import { ParsedUrlQuery } from "querystring"; |
||||
|
||||
import { GetStaticPaths, GetStaticProps } from "next"; |
||||
import { MDXRemote } from "next-mdx-remote"; |
||||
import React from "react"; |
||||
|
||||
import { NewsCard } from "@/components/NewsCard"; |
||||
import { |
||||
getNewsBySlug, |
||||
getNewsByTerm, |
||||
getNewsTermsByYear, |
||||
getNewsYears, |
||||
News, |
||||
} from "@/lib/news"; |
||||
|
||||
import styles from "./[term].module.css"; |
||||
|
||||
interface Props { |
||||
year: string; |
||||
term: string; |
||||
news: News[]; |
||||
} |
||||
|
||||
export default function TermNews({ year, term, news }: Props) { |
||||
return ( |
||||
<div className={styles.page}> |
||||
<h1> |
||||
News Archive:{" "} |
||||
<span className={styles.term}> |
||||
{capitalize(term)} {year} |
||||
</span> |
||||
</h1> |
||||
{news.map(({ content, metadata }, idx) => ( |
||||
<NewsCard |
||||
key={idx} |
||||
{...metadata} |
||||
date={new Date(metadata.date)} |
||||
fit={true} |
||||
> |
||||
<MDXRemote {...content} /> |
||||
</NewsCard> |
||||
))} |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export const getStaticProps: GetStaticProps<Props, Params> = async ( |
||||
context |
||||
) => { |
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const { year, term } = context.params!; |
||||
const slugs = await getNewsByTerm(year, term); |
||||
const news = await Promise.all( |
||||
slugs.map((slug) => getNewsBySlug(year, term, slug)) |
||||
); |
||||
|
||||
// Reverse so that we are displaying the most recent news
|
||||
// of term first
|
||||
return { props: { year, term, news: news.reverse() } }; |
||||
}; |
||||
|
||||
interface Params extends ParsedUrlQuery { |
||||
year: string; |
||||
term: string; |
||||
} |
||||
|
||||
export const getStaticPaths: GetStaticPaths<Params> = async () => { |
||||
const years = await getNewsYears(); |
||||
const terms = await Promise.all( |
||||
years.map(async (year) => { |
||||
const termsInYear = await getNewsTermsByYear(year); |
||||
return termsInYear.map((term) => ({ year, term })); |
||||
}) |
||||
); |
||||
|
||||
return { |
||||
paths: terms.flat().map((params) => ({ params })), |
||||
fallback: false, |
||||
}; |
||||
}; |
||||
|
||||
function capitalize(str: string) { |
||||
return str.slice(0, 1).toUpperCase() + str.slice(1); |
||||
} |
@ -0,0 +1,12 @@ |
||||
.page { |
||||
margin-bottom: calc(40rem / 16); |
||||
} |
||||
|
||||
.list { |
||||
list-style: none; |
||||
padding: 0; |
||||
} |
||||
|
||||
.list > li { |
||||
line-height: 3; |
||||
} |
@ -0,0 +1,49 @@ |
||||
import { getNewsTermsByYear, getNewsYears } from "lib/news"; |
||||
import { GetStaticProps } from "next"; |
||||
import React from "react"; |
||||
|
||||
import { Link } from "@/components/Link"; |
||||
|
||||
import styles from "./archive.module.css"; |
||||
|
||||
interface Props { |
||||
items: { |
||||
year: string; |
||||
terms: string[]; |
||||
}[]; |
||||
} |
||||
|
||||
export default function NewsArchive({ items }: Props) { |
||||
return ( |
||||
<div className={styles.page}> |
||||
<h1>News Archive</h1> |
||||
<ul className={styles.list}> |
||||
{items.map(({ year, terms }) => |
||||
terms.map((term) => ( |
||||
<li key={`${year}-${term}`}> |
||||
<Link href={`/news/${year}/${term}`}> |
||||
{capitalize(term)} {year} |
||||
</Link> |
||||
</li> |
||||
)) |
||||
)} |
||||
</ul> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export const getStaticProps: GetStaticProps<Props> = async () => { |
||||
const years = (await getNewsYears()).reverse(); |
||||
const yearsWithTerms = await Promise.all( |
||||
years.map(async (year) => ({ |
||||
year, |
||||
terms: (await getNewsTermsByYear(year)).reverse(), |
||||
})) |
||||
); |
||||
|
||||
return { props: { items: yearsWithTerms } }; |
||||
}; |
||||
|
||||
function capitalize(str: string) { |
||||
return str.slice(0, 1).toUpperCase() + str.slice(1); |
||||
} |
Loading…
Reference in new issue