Add past execs page (Close #370) #417

Open
b72zhou wants to merge 21 commits from b72zhou-past-exec into main
25 changed files with 367 additions and 12 deletions

View File

@ -13,7 +13,7 @@ import { Title } from "./Title";
import styles from "./ArchivePage.module.css";
export interface Props {
type: "news" | "events";
type: "news" | "events" | "executives";
items: {
year: string;
terms: Term[];
@ -28,13 +28,19 @@ export function ArchivePage({ items, type }: Props) {
<h1>{capitalize(type)} Archive</h1>
<ul className={styles.list}>
{items.map(({ year, terms }) =>
terms.map((term) => (
<li key={`/${type}/${year}/${term}`}>
<Link href={`/${type}/${year}/${term}`}>
{capitalize(term)} {year}
</Link>
</li>
))
terms.map((term) => {
const url =
type !== "executives"
? `/${type}/${year}/${term}`
: `/about/${type}/${year}/${term}`;
return (
<li key={url}>
<Link href={url}>
{capitalize(term)} {year}
</Link>
</li>
);
})
)}
</ul>
</div>

View File

@ -36,6 +36,10 @@ const menu: Menu = [
name: "Members",
route: "/about/members",
},
{
name: "Past Executives",
route: "/about/executives",
},
{
name: "Constitution",
route: "/about/constitution",

View File

@ -10,7 +10,7 @@ export interface TeamMemberCardProps {
name: string;
role: string;
image: string;
children: React.ReactNode;
children?: React.ReactNode;
}
export function TeamMemberCard({

View File

@ -0,0 +1,26 @@
[
{
"name": "Dora Su",
"role": "President"
},
{
"name": "Jason Sang",
"role": "Vice President"
},
{
"name": "Anjing Li",
"role": "Assistant Vice President"
},
{
"name": "Yanni Wang",
"role": "Treasurer"
},
{
"name": "Max Erenberg",
"role": "Systems Administrator"
},
{
"name": "Neil Parikh",
"role": "Advisor"
}
]

View File

@ -0,0 +1,22 @@
[
{
"name": "Kallen Tu",
"role": "President"
},
{
"name": "Gordon Le",
"role": "Vice President"
},
{
"name": "Ravindu Angammana",
"role": "Assistant Vice President"
},
{
"name": "Neil Parikh",
"role": "Treasurer"
},
{
"name": "Max Erenberg",
"role": "Systems Administrator"
}
]

View File

@ -0,0 +1,22 @@
[
{
"name": "Kallen Tu",
"role": "President"
},
{
"name": "Gordon Le",
"role": "Vice President"
},
{
"name": "Nakul Vijhani",
"role": "Assistant Vice President"
},
{
"name": "Neil Parikh",
"role": "Treasurer"
},
{
"name": "Max Erenberg",
"role": "Systems Administrator"
}
]

View File

@ -0,0 +1,30 @@
[
{
"name": "Juthika Hoque",
"role": "President"
},
{
"name": "Eric Huang",
"role": "Vice President"
},
{
"name": "Dina Orucevic",
"role": "Assistant Vice President"
},
{
"name": "Eden Chan",
"role": "Treasurer"
},
{
"name": "Raymond Li",
"role": "Systems Administrator"
},
{
"name": "Amy Wang",
"role": "Web Master"
},
{
"name": "Neil Parikh",
"role": "Office Manager"
}
]

BIN
images/execs/AnjingLi.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

BIN
images/execs/DoraSu.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
images/execs/EdenChan.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
images/execs/EricHuang.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
images/execs/GordonLe.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 KiB

BIN
images/execs/JasonSang.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

BIN
images/execs/KallenTu.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
images/execs/NeilParikh.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 KiB

BIN
images/execs/RaymondLi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB

BIN
images/execs/YanniWang.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@ -274,7 +274,10 @@ export function getCurrentTerm(): { year: string; term: Term } {
return { year, term };
}
function getPastTerm(year: string, term: Term): { year: string; term: Term } {
export function getPastTerm(
year: string,
term: Term
): { year: string; term: Term } {
const index = TERMS.indexOf(term);
if (index === -1) {
@ -292,7 +295,10 @@ function getPastTerm(year: string, term: Term): { year: string; term: Term } {
};
}
function getFutureTerm(year: string, term: Term): { year: string; term: Term } {
export function getFutureTerm(
year: string,
term: Term
): { year: string; term: Term } {
const index = TERMS.indexOf(term);
if (index === -1) {

View File

@ -0,0 +1,98 @@
.headerContainer {
display: flex;
flex-direction: row;
padding-bottom: calc(24rem / 16);
border-bottom: calc(1rem / 16) var(--primary-heading);
margin-bottom: calc(32rem / 16);
}
.nav {
display: none;
}
.headerTextContainer {
margin: auto 0 0 0;
}
.header {
color: var(--primary-heading);
font-size: calc(48rem / 16);
margin: 0 calc(53rem / 16) 0 0;
}
.subheading {
color: var(--primary-heading);
font-size: calc(36rem / 16);
font-weight: 600;
padding-bottom: calc(22rem / 16);
border-bottom: calc(1rem / 16) solid var(--primary-heading);
margin-bottom: calc(32rem / 16);
margin-top: calc(46rem / 16);
}
.codey {
width: calc(360rem / 16);
}
.members {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(calc(100rem / 16), 1fr));
row-gap: calc(43rem / 16);
column-gap: calc(53rem / 16);
justify-items: center;
}
.info {
margin: 6rem 0;
}
.infoSubheading {
color: var(--primary-accent);
font-size: calc(36rem / 16);
font-weight: 600;
margin-top: 0;
}
@media only screen and (max-width: calc(768rem / 16)) {
.headerContainer {
flex-direction: column-reverse;
padding-bottom: 1rem;
margin-top: calc(30rem / 16);
}
.nav {
margin-top: calc(24rem / 16);
margin-bottom: calc(46rem / 16);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.codey {
width: calc(140rem / 16);
align-self: center;
}
.header {
font-size: calc(24rem / 16);
margin: calc(10rem / 16) 0 0 0;
text-align: center;
}
.subheading {
font-size: calc(24rem / 16);
padding-bottom: calc(15rem / 16);
}
.members {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(calc(130rem / 16), 1fr));
justify-items: center;
column-gap: 0;
}
.infoSubheading {
font-size: calc(24rem / 16);
}
}

141
pages/about/executives.tsx Normal file
View File

@ -0,0 +1,141 @@
import { GetStaticProps } from "next";
import React from "react";
import { Bubble } from "@/components/Bubble";
import { DefaultLayout } from "@/components/DefaultLayout";
import { Image } from "@/components/Image";
import { Link } from "@/components/Link";
import { TeamMember } from "@/components/TeamMember";
import { Title } from "@/components/Title";
import { Metadata, getMemberImagePath } from "@/lib/team";
import F21ExecData from "../../content/past-execs/2021/fall.json";
import S21ExecData from "../../content/past-execs/2021/spring.json";
import W21ExecData from "../../content/past-execs/2021/winter.json";
import W22ExecData from "../../content/past-execs/2022/winter.json";
import styles from "./executives.module.css";
interface Props {
F21Exec: Metadata[];
S21Exec: Metadata[];
W21Exec: Metadata[];
W22Exec: Metadata[];
}
export default function Executives({
F21Exec,
S21Exec,
W21Exec,
W22Exec,
}: Props) {
const teams = [
{
id: "W22Exec",
name: "Winter 2022",
members: W22Exec,
},
{
id: "F21Exec",
name: "Fall 2021",
members: F21Exec,
},
{
id: "S21Exec",
name: "Spring 2021",
members: S21Exec,
},
{
id: "W21Exec",
name: "Winter 2021",
members: W21Exec,
},
];
return (
<>
<Title>Team</Title>
<DefaultLayout>
<div className={styles.headerContainer}>
<div className={styles.headerTextContainer}>
<h1 className={styles.header}>Meet the Past Executives!</h1>
<div className={styles.nav}>
<Link href="#F21Exec">Fall 2021</Link>
<Link href="#S21Exec">Spring 2021</Link>
<Link href="#W21Exec">Winter 2021</Link>
</div>
</div>
<Image src="images/team/team-codey.svg" className={styles.codey} />
</div>
{teams.map((team) => {
return (
<div id={team.id} key={team.id}>
<h2 className={styles.subheading}>{team.name}</h2>
<MembersList team={team.members} />
</div>
);
})}
</DefaultLayout>
<div className={styles.info}>
<Bubble>
<h2 className={styles.infoSubheading}>More information</h2>
To learn more about our past executives, see our{" "}
<Link href="https://wiki.csclub.uwaterloo.ca/Past_Executive">
Wikipedia
</Link>
.
</Bubble>
</div>
</>
);
}
Executives.Layout = function TeamLayout(props: { children: React.ReactNode }) {
return <div>{props.children}</div>;
};
interface MembersProps {
team: Metadata[];
}
function MembersList(props: MembersProps) {
return (
<div className={styles.members}>
{props.team.map((member) => (
<TeamMember {...member} key={member.name} />
))}
</div>
);
}
type TeamMember = Omit<Metadata, "image"> & { image?: string };
async function getTeamWithImages(team: TeamMember[]) {
return await Promise.all(
team.map(async (member) => {
const image =
member.image ?? (await getMemberImagePath(member.name, false));
return {
...member,
image,
};
})
);
}
export const getStaticProps: GetStaticProps<Props> = async () => {
const [F21Exec, S21Exec, W21Exec, W22Exec] = await Promise.all([
getTeamWithImages(F21ExecData),
getTeamWithImages(S21ExecData),
getTeamWithImages(W21ExecData),
getTeamWithImages(W22ExecData),
]);
return {
props: {
F21Exec,
S21Exec,
W21Exec,
W22Exec,
},
};
};

View File

@ -103,4 +103,4 @@
.electionSubheading {
font-size: calc(24rem / 16);
}
}
}