Separate Teams on meet the team page (Close #364) #403
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
{
|
||||
"name": "Jenny Zhang",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Vivian Guo",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Rachel Ma",
|
||||
"role": "Design"
|
||||
},
|
||||
{
|
||||
"name": "Aaryan Shroff",
|
||||
"role": "Design"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,39 @@
|
|||
[
|
||||
{
|
||||
"name": "Andy Wang",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Alex Zhang",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Allen Qin Lu",
|
||||
"role": "Developer",
|
||||
"image": "/images/team/AllenLu.png"
|
||||
},
|
||||
{
|
||||
"name": "Chris Xie",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Edwin Yang",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Laura Nguyen",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Marcus Chan",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Mark Chen",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Victor Zheng",
|
||||
"role": "Developer"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,75 @@
|
|||
[
|
||||
{
|
||||
"name": "Eden Chan",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Eric Huang",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Adele Chen",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Amya Singhal",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Anna Wang",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Catherine Wan",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Diana Brebeanu",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Elaine Han",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Cui",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Kenson Hui",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Mabel Kwok",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Mashrur Chowdhury",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Matthew Wang",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Naman Chhawchharia",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Riddhi Bajaj",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "Santiago Montemayor Gomez",
|
||||
"role": "Events",
|
||||
"image": "/images/team/SantiagoMontemayor.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Tommy Jiang",
|
||||
"role": "Events"
|
||||
},
|
||||
{
|
||||
"name": "William Tran",
|
||||
"role": "Events"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
{
|
||||
"name": "David Chen",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Daniel Kim",
|
||||
"role": "External Affairs"
|
||||
},
|
||||
{
|
||||
"name": "Eric Liu",
|
||||
"role": "External Affairs"
|
||||
},
|
||||
{
|
||||
"name": "Victor Wu",
|
||||
"role": "External Affairs"
|
||||
},
|
||||
{
|
||||
"name": "Wanda Song",
|
||||
"role": "External Affairs"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,31 @@
|
|||
[
|
||||
{
|
||||
"name": "Dina Orucevic",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Arjun Amit Athalye",
|
||||
"role": "Marketing",
|
||||
"image": "/images/team/ArjunAthalye.jpeg"
|
||||
},
|
||||
{
|
||||
"name": "Catherine Tao",
|
||||
"role": "Marketing"
|
||||
},
|
||||
{
|
||||
"name": "Ethan Hong",
|
||||
"role": "Marketing"
|
||||
},
|
||||
{
|
||||
"name": "Gurnika Kaur",
|
||||
"role": "Marketing"
|
||||
},
|
||||
{
|
||||
"name": "Haley Song",
|
||||
"role": "Marketing"
|
||||
},
|
||||
{
|
||||
"name": "Kshama Patel",
|
||||
"role": "Marketing"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
{
|
||||
"name": "Bonnie Peng",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Annie Zhang",
|
||||
"role": "Photographer"
|
||||
},
|
||||
{
|
||||
"name": "Calvin Zhong",
|
||||
"role": "Photographer"
|
||||
},
|
||||
{
|
||||
"name": "Jesse Liu",
|
||||
"role": "Photographer"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,42 @@
|
|||
[
|
||||
{
|
||||
"name": "Amy Luo",
|
||||
"role": "Team Lead"
|
||||
},
|
||||
{
|
||||
"name": "Govind Varma",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Guneet Bola",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Ivy Lei",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Jasmine Bal",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Mayank Mehra",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Olivia Liu",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Sat Arora",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Star Xie",
|
||||
"role": "Representative"
|
||||
},
|
||||
{
|
||||
"name": "Tracy Dong",
|
||||
"role": "Representative"
|
||||
}
|
||||
]
|
127
lib/team.ts
127
lib/team.ts
|
@ -2,10 +2,35 @@ import { readFile, readdir, access } from "fs/promises";
|
|||
import path from "path";
|
||||
|
||||
import matter from "gray-matter";
|
||||
import { Client } from "ldapts";
|
||||
import { serialize } from "next-mdx-remote/serialize";
|
||||
|
||||
import { getCurrentTerm } from "@/lib/events";
|
||||
|
||||
const EXECS_PATH = path.join("content", "team", "execs");
|
||||
const fileType = ".md";
|
||||
const { year, term } = getCurrentTerm();
|
||||
|
||||
const execPositions: { [name: string]: number } = {
|
||||
president: 1,
|
||||
"vice-president": 2,
|
||||
secretary: 3,
|
||||
treasurer: 4,
|
||||
sysadmin: 5,
|
||||
};
|
||||
|
||||
const positionNames: string[] = [
|
||||
"President",
|
||||
"Vice President",
|
||||
"Assistant Vice President",
|
||||
"Treasurer",
|
||||
"System Administrator",
|
||||
];
|
||||
|
||||
export interface ExecMembers {
|
||||
name: string;
|
||||
position: string;
|
||||
}
|
||||
|
||||
export interface Metadata {
|
||||
name: string;
|
||||
|
@ -14,22 +39,100 @@ export interface Metadata {
|
|||
}
|
||||
|
||||
export async function getExecNames() {
|
||||
return (await readdir(EXECS_PATH))
|
||||
.filter((name) => name.endsWith(fileType))
|
||||
.map((name) => name.slice(0, -1 * fileType.length));
|
||||
if (process.env.USE_LDAP?.toLowerCase() !== "true") {
|
||||
return (await readdir(EXECS_PATH))
|
||||
.filter((name) => name.endsWith(fileType))
|
||||
.map((name) => name.slice(0, -1 * fileType.length));
|
||||
}
|
||||
|
||||
const url = "ldap://ldap1.csclub.uwaterloo.ca";
|
||||
const searchDN = "ou=People,dc=csclub,dc=uwaterloo,dc=ca";
|
||||
const client = new Client({ url });
|
||||
|
||||
let execMembers: ExecMembers[] = [];
|
||||
let formattedExec: string[];
|
||||
|
||||
try {
|
||||
await client.bind("", "");
|
||||
const { searchEntries } = await client.search(searchDN, {
|
||||
scope: "sub",
|
||||
filter: `(&(objectClass=member)(term=${(term as string).slice(
|
||||
0,
|
||||
1
|
||||
)}${year}))`,
|
||||
});
|
||||
|
||||
execMembers = searchEntries
|
||||
.map((item) => {
|
||||
return {
|
||||
name: item.cn as string,
|
||||
position:
|
||||
item.position === undefined
|
||||
? ""
|
||||
: typeof item.position === "string"
|
||||
? item.position
|
||||
: (item.position[0] as string),
|
||||
};
|
||||
})
|
||||
.filter((item: ExecMembers) => item.position !== "");
|
||||
|
||||
execMembers = execMembers.sort((item1: ExecMembers, item2: ExecMembers) => {
|
||||
return execPositions[item1.position] - execPositions[item2.position];
|
||||
});
|
||||
|
||||
formattedExec = execMembers.map(
|
||||
(member) =>
|
||||
`0${execPositions[member.position]}-${member.name
|
||||
.split(" ")[0]
|
||||
.toLowerCase()}-${member.name.split(" ")[1].toLowerCase()}`
|
||||
);
|
||||
|
||||
formattedExec = [...formattedExec, "06-codey"];
|
||||
} finally {
|
||||
await client.unbind();
|
||||
}
|
||||
|
||||
return formattedExec;
|
||||
}
|
||||
|
||||
export async function getExec(fileName: string, convert = true) {
|
||||
const raw = await readFile(path.join(EXECS_PATH, `${fileName}${fileType}`));
|
||||
const { content, data: metadata } = matter(raw);
|
||||
const image =
|
||||
(metadata.image as string | undefined) ??
|
||||
(await getMemberImagePath(metadata.name));
|
||||
let content, metadata;
|
||||
|
||||
return {
|
||||
content: convert ? await serialize(content) : content,
|
||||
metadata: { ...metadata, image } as Metadata,
|
||||
};
|
||||
try {
|
||||
const raw = await readFile(path.join(EXECS_PATH, `${fileName}${fileType}`));
|
||||
({ content, data: metadata } = matter(raw));
|
||||
|
||||
const image =
|
||||
(metadata.image as string | undefined) ??
|
||||
(await getMemberImagePath(metadata.name));
|
||||
|
||||
return {
|
||||
content: convert ? await serialize(content) : content,
|
||||
metadata: { ...metadata, image } as Metadata,
|
||||
};
|
||||
} catch (err) {
|
||||
const firstName =
|
||||
fileName.split("-")[1][0].toUpperCase() + fileName.split("-")[1].slice(1);
|
||||
const lastName =
|
||||
fileName.split("-")[2][0].toUpperCase() + fileName.split("-")[2].slice(1);
|
||||
|
||||
const posOrder = fileName.split("-")[0][1];
|
||||
const posName = positionNames[Number(posOrder) - 1];
|
||||
({ content, metadata } = {
|
||||
content: "Coming soon!",
|
||||
metadata: {
|
||||
name: `${firstName} ${lastName}`,
|
||||
role: `${posName} ${Number(posOrder) - 1}`,
|
||||
},
|
||||
});
|
||||
|
||||
const image = await getMemberImagePath(metadata.name);
|
||||
|
||||
return {
|
||||
content: convert ? await serialize(content) : content,
|
||||
metadata: { ...metadata, image } as Metadata,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function getImage(imgPath: string) {
|
||||
|
|
|
@ -16,7 +16,13 @@ import {
|
|||
getMemberImagePath,
|
||||
} from "@/lib/team";
|
||||
|
||||
import programmeData from "../../content/team/programme-committee.json";
|
||||
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";
|
||||
|
@ -30,7 +36,13 @@ interface SerializedExec {
|
|||
|
||||
interface Props {
|
||||
execs: SerializedExec[];
|
||||
programme: Metadata[];
|
||||
design: Metadata[];
|
||||
discord: Metadata[];
|
||||
events: Metadata[];
|
||||
external: Metadata[];
|
||||
marketing: Metadata[];
|
||||
photography: Metadata[];
|
||||
reps: Metadata[];
|
||||
website: Metadata[];
|
||||
systems: Metadata[];
|
||||
terminal: Metadata[];
|
||||
|
@ -38,7 +50,13 @@ interface Props {
|
|||
|
||||
export default function Team({
|
||||
execs,
|
||||
programme,
|
||||
design,
|
||||
discord,
|
||||
events,
|
||||
external,
|
||||
marketing,
|
||||
photography,
|
||||
reps,
|
||||
website,
|
||||
systems,
|
||||
terminal,
|
||||
|
@ -52,7 +70,13 @@ export default function Team({
|
|||
<h1 className={styles.header}>Meet the Team!</h1>
|
||||
<div className={styles.nav}>
|
||||
<Link href="#execs">The Executives</Link>
|
||||
<Link href="#programme">Programme Committee</Link>
|
||||
<Link href="#design">Design Team</Link>
|
||||
<Link href="#discord">Discord Team</Link>
|
||||
<Link href="#events">Events Team</Link>
|
||||
<Link href="#external">External Affairs Team</Link>
|
||||
<Link href="#marketing">Marketing Team</Link>
|
||||
<Link href="#photography">Photography Team</Link>
|
||||
<Link href="#reps">Representatives Team</Link>
|
||||
<Link href="#website">Website Committee</Link>
|
||||
<Link href="#system">Systems Committee</Link>
|
||||
<Link href="#terminal">Terminal Committee</Link>
|
||||
|
@ -77,9 +101,33 @@ export default function Team({
|
|||
);
|
||||
})}
|
||||
</div>
|
||||
<div id="programme">
|
||||
<h2 className={styles.subheading}>Programme Committee</h2>
|
||||
<MembersList team={programme} />
|
||||
<div id="design">
|
||||
<h2 className={styles.subheading}>Design Team</h2>
|
||||
<MembersList team={design} />
|
||||
</div>
|
||||
<div id="discord">
|
||||
<h2 className={styles.subheading}>Discord Team</h2>
|
||||
<MembersList team={discord} />
|
||||
</div>
|
||||
<div id="events">
|
||||
<h2 className={styles.subheading}>Events Team</h2>
|
||||
<MembersList team={events} />
|
||||
</div>
|
||||
<div id="external">
|
||||
<h2 className={styles.subheading}>External Affairs Team</h2>
|
||||
<MembersList team={external} />
|
||||
</div>
|
||||
<div id="marketing">
|
||||
<h2 className={styles.subheading}>Marketing Team</h2>
|
||||
<MembersList team={marketing} />
|
||||
</div>
|
||||
<div id="photography">
|
||||
<h2 className={styles.subheading}>Photography Team</h2>
|
||||
<MembersList team={photography} />
|
||||
</div>
|
||||
<div id="reps">
|
||||
<h2 className={styles.subheading}>Representatives Team</h2>
|
||||
<MembersList team={reps} />
|
||||
</div>
|
||||
<div id="website">
|
||||
<h2 className={styles.subheading}>Website Committee</h2>
|
||||
|
@ -141,17 +189,48 @@ async function getTeamWithImages(team: TeamMember[]) {
|
|||
|
||||
export const getStaticProps: GetStaticProps<Props> = async () => {
|
||||
const execNames = await getExecNames();
|
||||
|
||||
const execs = (await Promise.all(
|
||||
execNames.map((name) => getExec(name))
|
||||
)) as SerializedExec[];
|
||||
const [programme, website, systems, terminal] = await Promise.all([
|
||||
getTeamWithImages(programmeData),
|
||||
|
||||
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, programme, website, systems, terminal },
|
||||
props: {
|
||||
execs,
|
||||
design,
|
||||
discord,
|
||||
events,
|
||||
external,
|
||||
marketing,
|
||||
photography,
|
||||
reps,
|
||||
website,
|
||||
systems,
|
||||
terminal,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue