diff --git a/content/team/execs/06-codey.md b/content/team/execs/codey.md similarity index 100% rename from content/team/execs/06-codey.md rename to content/team/execs/codey.md diff --git a/content/team/execs/03-dina-orucevic.md b/content/team/execs/dina-orucevic.md similarity index 100% rename from content/team/execs/03-dina-orucevic.md rename to content/team/execs/dina-orucevic.md diff --git a/content/team/execs/04-eden-chan.md b/content/team/execs/eden-chan.md similarity index 100% rename from content/team/execs/04-eden-chan.md rename to content/team/execs/eden-chan.md diff --git a/content/team/execs/02-eric-huang.md b/content/team/execs/eric-huang.md similarity index 100% rename from content/team/execs/02-eric-huang.md rename to content/team/execs/eric-huang.md diff --git a/content/team/execs/01-juthika-hoque.md b/content/team/execs/juthika-hoque.md similarity index 100% rename from content/team/execs/01-juthika-hoque.md rename to content/team/execs/juthika-hoque.md diff --git a/content/team/execs/05-raymond-li.md b/content/team/execs/raymond-li.md similarity index 100% rename from content/team/execs/05-raymond-li.md rename to content/team/execs/raymond-li.md diff --git a/lib/team.ts b/lib/team.ts index 0afe94f7..43cb7100 100644 --- a/lib/team.ts +++ b/lib/team.ts @@ -1,11 +1,32 @@ -import { readFile, readdir, access } from "fs/promises"; +import { readFile, 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"; +import { capitalize } from "@/utils"; + const EXECS_PATH = path.join("content", "team", "execs"); -const fileType = ".md"; +const FILETYPE = ".md"; +const { year, term } = getCurrentTerm(); + +const execPositions: { [position: string]: string } = { + president: "President", + "vice-president": "Vice President", + secretary: "Assistant Vice President", + treasurer: "Treasurer", + sysadmin: "System Administrator", +}; + +const orderedExecPositions: string[] = [ + "president", + "vice-president", + "secretary", + "treasurer", + "sysadmin", +]; export interface Metadata { name: string; @@ -13,23 +34,93 @@ export interface Metadata { image: string; } -export async function getExecNames() { - return (await readdir(EXECS_PATH)) - .filter((name) => name.endsWith(fileType)) - .map((name) => name.slice(0, -1 * fileType.length)); +export async function getExecNamePosPairs() { + if (process.env.USE_LDAP?.toLowerCase() !== "true") { + return [["codey", "mascot"]]; + } + + const url = "ldap://ldap1.csclub.uwaterloo.ca"; + const searchDN = "ou=People,dc=csclub,dc=uwaterloo,dc=ca"; + const client = new Client({ url }); + + // position: name + const execMembers: { [position: string]: string } = {}; + let formattedExec: [string, string][] = []; + + try { + await client.bind("", ""); + const { searchEntries } = await client.search(searchDN, { + scope: "sub", + filter: `(&(objectClass=member)(term=${(term as string).slice( + 0, + 1 + )}${year}))`, + }); + + // item.position might be an array if the member has more than one position + searchEntries.forEach((item) => { + if (typeof item.position === "string" && item.position in execPositions) { + execMembers[item.position] = item.cn as string; + } else if (item.position instanceof Array) { + item.position.forEach((p) => { + if ((p as string) in execPositions) { + execMembers[p as string] = item.cn as string; + } + }); + } + }); + + formattedExec = orderedExecPositions.map((position) => { + return [ + `${execMembers[position].split(" ")[0].toLowerCase()}-${execMembers[ + position + ] + .split(" ")[1] + .toLowerCase()}`, + position, + ]; + }); + + formattedExec = [...formattedExec, ["codey", "mascot"]]; + } 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)); +export async function getExec(name: string, pos: string, convert = true) { + let content, metadata; - return { - content: convert ? await serialize(content) : content, - metadata: { ...metadata, image } as Metadata, - }; + try { + const raw = await readFile(path.join(EXECS_PATH, `${name}${FILETYPE}`)); + ({ content, data: metadata } = matter(raw)); + + const image = await getMemberImagePath(metadata.name); + + return { + content: convert ? await serialize(content) : content, + metadata: { ...metadata, image } as Metadata, + }; + } catch (err) { + // Capitalize the first letter of the first name and last name + const firstName = capitalize(name.split("-")[0]); + const lastName = capitalize(name.split("-")[1]); + + const posName = execPositions[pos]; + content = "Coming Soon!"; + metadata = { + name: `${firstName} ${lastName}`, + role: `${posName}`, + }; + + const image = await getMemberImagePath(metadata.name); + + return { + content: convert ? await serialize(content) : content, + metadata: { ...metadata, image } as Metadata, + }; + } } async function getImage(imgPath: string) { diff --git a/pages/about/team.tsx b/pages/about/team.tsx index d5d0974b..5c2bf065 100644 --- a/pages/about/team.tsx +++ b/pages/about/team.tsx @@ -11,7 +11,7 @@ import { TeamMemberCard } from "@/components/TeamMemberCard"; import { Title } from "@/components/Title"; import { getExec, - getExecNames, + getExecNamePosPairs, Metadata, getMemberImagePath, } from "@/lib/team"; @@ -208,10 +208,12 @@ async function getTeamWithImages(team: TeamMember[]) { } export const getStaticProps: GetStaticProps = async () => { - const execNames = await getExecNames(); + const execNamePosPairs = await getExecNamePosPairs(); const execs = (await Promise.all( - execNames.map((name) => getExec(name)) + execNamePosPairs.map((namePosPair) => + getExec(namePosPair[0], namePosPair[1]) + ) )) as SerializedExec[]; const [