Add /news/archive and /news/[year]/[term] pages #146

Merged
a3thakra merged 4 commits from adi-news-archive into adi-news-content 2021-08-17 15:09:20 -04:00
9 changed files with 170 additions and 8 deletions

View File

@ -5,6 +5,12 @@
border-radius: calc(20rem / 16); border-radius: calc(20rem / 16);
} }
.fit.card {
max-width: unset;
padding: unset;
border-radius: unset;
}
.date { .date {
font-size: calc(18rem / 16); font-size: calc(18rem / 16);
margin: 0; margin: 0;

View File

@ -6,15 +6,19 @@ interface NewsCardProps {
date: Date; date: Date;
author: string; author: string;
children: ReactNode; children: ReactNode;
fit?: boolean;
} }
export const NewsCard: React.FC<NewsCardProps> = ({ export const NewsCard: React.FC<NewsCardProps> = ({
date, date,
author, author,
children, children,
fit = false,
}) => { }) => {
const classes = fit ? [styles.card, styles.fit] : [styles.card];
return ( return (
<article className={styles.card}> <article className={classes.join(" ")}>
<h1 className={styles.date}> <h1 className={styles.date}>
<time dateTime={date.toISOString()}> <time dateTime={date.toISOString()}>
{date.toLocaleDateString("en-US", { {date.toLocaleDateString("en-US", {

View File

@ -3,6 +3,6 @@ author: "ja2morri"
date: "2003-07-09" date: "2003-07-09"
--- ---
Jim Elliott gave a great talk for the CSC yesterday and has put his slides online. <br> Jim Elliott gave a great talk for the CSC yesterday and has put his slides online.
[ http://www.vm.ibm.com/devpages/jelliott/events](<http://www.vm.ibm.com/devpages/jelliott/events>) [ http://www.vm.ibm.com/devpages/jelliott/events](<http://www.vm.ibm.com/devpages/jelliott/events>)

View File

@ -3,10 +3,10 @@ author: "dtbartle"
date: "2008-05-04" date: "2008-05-04"
--- ---
Spring 2008 elections will be held on Tuesday May 13th at 4:30pm in the Comfy Lounge.<br> Spring 2008 elections will be held on Tuesday May 13th at 4:30pm in the Comfy Lounge.
Get your nominations in as soon as possible on the CSC whiteboard!<br> Get your nominations in as soon as possible on the CSC whiteboard!
Nominations close 24 hours before the polls open.<br> Nominations close 24 hours before the polls open.
You can email your nominations to cro@csclub.uwaterloo.ca You can email your nominations to cro@csclub.uwaterloo.ca

View File

@ -5,12 +5,12 @@ date: "2018-09-01"
Power has now been restored to the machine room and most CSC systems and services are now available, with the exception of: Power has now been restored to the machine room and most CSC systems and services are now available, with the exception of:
- **sucrose and taurine**<br> - **sucrose and taurine**
We are currently unable to access to servers remotely. To restore these servers, we need a visit to the machine room to identify and resolve boot issues. <br> We are currently unable to access to servers remotely. To restore these servers, we need a visit to the machine room to identify and resolve boot issues.
*As of Sept. 5, taurine is available again with reduced RAM.* *As of Sept. 5, taurine is available again with reduced RAM.*
- **[test-ipv6](<http://test-ipv6.csclub.uwaterloo.ca>) (restored as of Sept. 2)**<br> - **[test-ipv6](<http://test-ipv6.csclub.uwaterloo.ca>) (restored as of Sept. 2)**
Currently available from within the UW network only. Investigation is still ongoing and may require assistance from IST's security team. Currently available from within the UW network only. Investigation is still ongoing and may require assistance from IST's security team.

View File

@ -0,0 +1,7 @@
.page {
padding-bottom: calc(30rem / 16);
}
.term {
color: var(--primary-accent);
}

View File

@ -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);
}

View File

@ -0,0 +1,12 @@
.page {
margin-bottom: calc(40rem / 16);
}
.list {
list-style: none;
padding: 0;
}
.list > li {
line-height: 3;
}

49
pages/news/archive.tsx Normal file
View File

@ -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);
}