259 lines
6.6 KiB
TypeScript
259 lines
6.6 KiB
TypeScript
import { GetStaticProps } from "next";
|
|
import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote";
|
|
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 { TeamMemberCard } from "@/components/TeamMemberCard";
|
|
import { Title } from "@/components/Title";
|
|
import {
|
|
getExec,
|
|
getExecNamePosPairs,
|
|
Metadata,
|
|
getMemberImagePath,
|
|
} from "@/lib/team";
|
|
|
|
import designData from "../../content/team/design-team.json";
|
|
import discordData from "../../content/team/discord-team.json";
|
|
import eventsData from "../../content/team/events-team.json";
|
|
import externalData from "../../content/team/external-affairs-team.json";
|
|
import marketingData from "../../content/team/marketing-team.json";
|
|
import photographyData from "../../content/team/photography-team.json";
|
|
import repsData from "../../content/team/representative-team.json";
|
|
import systemsData from "../../content/team/systems-committee.json";
|
|
import terminalData from "../../content/team/terminal-committee.json";
|
|
import webData from "../../content/team/web-committee.json";
|
|
|
|
import styles from "./team.module.css";
|
|
|
|
interface SerializedExec {
|
|
content: MDXRemoteSerializeResult;
|
|
metadata: Metadata;
|
|
}
|
|
|
|
interface Props {
|
|
execs: SerializedExec[];
|
|
design: Metadata[];
|
|
discord: Metadata[];
|
|
events: Metadata[];
|
|
external: Metadata[];
|
|
marketing: Metadata[];
|
|
photography: Metadata[];
|
|
reps: Metadata[];
|
|
website: Metadata[];
|
|
systems: Metadata[];
|
|
terminal: Metadata[];
|
|
}
|
|
|
|
export default function Team({
|
|
execs,
|
|
design,
|
|
discord,
|
|
events,
|
|
external,
|
|
marketing,
|
|
photography,
|
|
reps,
|
|
website,
|
|
systems,
|
|
terminal,
|
|
}: Props) {
|
|
const teams = [
|
|
{
|
|
id: "design",
|
|
name: "Design Team",
|
|
members: design,
|
|
},
|
|
{
|
|
id: "discord",
|
|
name: "Discord Team",
|
|
members: discord,
|
|
},
|
|
{
|
|
id: "events",
|
|
name: "Events Team",
|
|
members: events,
|
|
},
|
|
{
|
|
id: "external",
|
|
name: "External Affairs Team",
|
|
members: external,
|
|
},
|
|
{
|
|
id: "marketing",
|
|
name: "Marketing Team",
|
|
members: marketing,
|
|
},
|
|
{
|
|
id: "photography",
|
|
name: "Photography Team",
|
|
members: photography,
|
|
},
|
|
{
|
|
id: "reps",
|
|
name: "Class Representatives",
|
|
members: reps,
|
|
},
|
|
{
|
|
id: "website",
|
|
name: "Website Committee",
|
|
members: website,
|
|
},
|
|
{
|
|
id: "system",
|
|
name: "Systems Committee",
|
|
members: systems,
|
|
},
|
|
{
|
|
id: "terminal",
|
|
name: "Terminal Committee",
|
|
members: terminal,
|
|
},
|
|
];
|
|
return (
|
|
<>
|
|
<Title>Team</Title>
|
|
<DefaultLayout>
|
|
<div className={styles.headerContainer}>
|
|
<div className={styles.headerTextContainer}>
|
|
<h1 className={styles.header}>Meet the Team!</h1>
|
|
<div className={styles.nav}>
|
|
<Link href="#execs">The Executives</Link>
|
|
<Link href="#design">Design</Link>
|
|
<Link href="#discord">Discord</Link>
|
|
<Link href="#events">Events</Link>
|
|
<Link href="#external">External Affairs</Link>
|
|
<Link href="#marketing">Marketing</Link>
|
|
<Link href="#photography">Photography</Link>
|
|
<Link href="#reps">Class Representatives</Link>
|
|
<Link href="#website">Website Committee</Link>
|
|
<Link href="#system">Systems Committee</Link>
|
|
<Link href="#terminal">Terminal Committee</Link>
|
|
</div>
|
|
<h2
|
|
className={styles.subheading}
|
|
style={{ borderBottom: "none", margin: 0, padding: 0 }}
|
|
>
|
|
The Executives
|
|
</h2>
|
|
</div>
|
|
<Image src="images/team/team-codey.svg" className={styles.codey} />
|
|
</div>
|
|
<div className={styles.execs} id="execs">
|
|
{execs.map((exec) => {
|
|
return (
|
|
<div key={exec.metadata.name}>
|
|
<TeamMemberCard {...exec.metadata}>
|
|
<MDXRemote {...exec.content} />
|
|
</TeamMemberCard>
|
|
</div>
|
|
);
|
|
})}
|
|
</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.elections}>
|
|
<Bubble>
|
|
<h2 className={styles.electionSubheading}>Elections</h2>
|
|
To find out when and where the next elections will be held, keep an
|
|
eye on on the <Link href="/#news">News</Link>. <br />
|
|
For details on the elections, read our
|
|
<Link href="/about/constitution"> Constitution</Link>.
|
|
</Bubble>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
Team.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));
|
|
return {
|
|
...member,
|
|
image,
|
|
};
|
|
})
|
|
);
|
|
}
|
|
|
|
export const getStaticProps: GetStaticProps<Props> = async () => {
|
|
const execNamePosPairs = await getExecNamePosPairs();
|
|
|
|
const execs = (await Promise.all(
|
|
execNamePosPairs.map((namePosPair) =>
|
|
getExec(namePosPair[0], namePosPair[1])
|
|
)
|
|
)) as SerializedExec[];
|
|
|
|
const [
|
|
design,
|
|
discord,
|
|
events,
|
|
external,
|
|
marketing,
|
|
photography,
|
|
reps,
|
|
website,
|
|
systems,
|
|
terminal,
|
|
] = await Promise.all([
|
|
getTeamWithImages(designData),
|
|
getTeamWithImages(discordData),
|
|
getTeamWithImages(eventsData),
|
|
getTeamWithImages(externalData),
|
|
getTeamWithImages(marketingData),
|
|
getTeamWithImages(photographyData),
|
|
getTeamWithImages(repsData),
|
|
getTeamWithImages(webData),
|
|
getTeamWithImages(systemsData),
|
|
getTeamWithImages(terminalData),
|
|
]);
|
|
|
|
return {
|
|
props: {
|
|
execs,
|
|
design,
|
|
discord,
|
|
events,
|
|
external,
|
|
marketing,
|
|
photography,
|
|
reps,
|
|
website,
|
|
systems,
|
|
terminal,
|
|
},
|
|
};
|
|
};
|