diff --git a/src/components/Governance.tsx b/src/components/Governance.tsx
new file mode 100644
index 0000000..843f476
--- /dev/null
+++ b/src/components/Governance.tsx
@@ -0,0 +1,90 @@
+import Header from '@/components/Header';
+import Footer from '@/components/Footer';
+import PeriodLinks from '@/components/PeriodLinks';
+import Image, { StaticImageData } from 'next/image';
+
+interface LeadershipCardProps {
+ image: string | StaticImageData;
+ name: string;
+ title: string;
+ links: {
+ link: string;
+ image: string | StaticImageData;
+ }[];
+}
+[];
+
+const LeadershipCard = (props: LeadershipCardProps) => {
+ return (
+
+ {props.image == '' ? (
+
+ ) : (
+
+ )}
+
{props.name}
+
{props.title}
+
+ {props.links.map((link, index) => (
+
+
+
+ ))}
+
+
+ );
+};
+
+interface LeadershipGroupProps {
+ name: string;
+ description: string;
+ people: LeadershipCardProps[];
+}
+[];
+
+const LeadershipGroup = (props: LeadershipGroupProps) => {
+ return (
+
+
{props.name}
+
{props.description}
+
+ {props.people.map((person) => (
+
+ ))}
+
+
+ );
+};
+
+interface GovernanceProps {
+ data: LeadershipGroupProps[];
+ past?: string;
+ periodLinks: {
+ path: string;
+ periods: string[];
+ current: string;
+ };
+}
+
+const Governance = (props: GovernanceProps) => (
+
+
+ {props.data.map((group) => (
+
+ ))}
+
+
+
+);
+
+export default Governance;
diff --git a/src/components/PeriodLinks.tsx b/src/components/PeriodLinks.tsx
new file mode 100644
index 0000000..a651b26
--- /dev/null
+++ b/src/components/PeriodLinks.tsx
@@ -0,0 +1,52 @@
+import Link from 'next/link';
+
+interface GovernanceProps {
+ name: string;
+ past?: string | null;
+ path: string;
+ periods: string[];
+ current: string;
+}
+
+const PeriodLinks = (props: GovernanceProps) => {
+ const periods = props.periods;
+ periods[periods.indexOf(props.current)] = 'Current';
+
+ const urls = periods.map((period) => {
+ if (period === 'Current') {
+ return props.path;
+ }
+ return props.path + period;
+ });
+
+ return (
+
+
{props.name}
+
+ {periods.map((period, index) => {
+ if (
+ period === props.past ||
+ (period === 'Current' && typeof props.past === 'undefined')
+ ) {
+ return (
+
+ {period}
+
+ );
+ }
+ return (
+
+ {period}
+
+ );
+ })}
+
+
+ );
+};
+
+export default PeriodLinks;
diff --git a/src/data/governance.tsx b/src/data/governance.tsx
new file mode 100644
index 0000000..0980201
--- /dev/null
+++ b/src/data/governance.tsx
@@ -0,0 +1,259 @@
+import { StaticImageData } from 'next/image';
+
+import LinkedIn from '@/../public/linkedin-royal.svg';
+import Website from '@/../public/website.svg';
+import Email from '@/../public/email.svg';
+
+import Amrit from '@/../public/governance/amrit.png';
+
+export const current = '2023-2024';
+
+function vacant(title: string) {
+ return {
+ image: '',
+ name: 'Vacant',
+ title: title,
+ links: [],
+ };
+}
+
+const clubSponsor = {
+ name: 'Our Club Sponsor',
+ description:
+ 'With more than a decade of teaching and mentoring experience within the community here at The University of Texas at Dallas, John Cole consistently leaves a positive impact on the people around him. Here at Nebula Labs we eagerly look forward to utilizing his invaluable support and knowledge as we grow as an organization.',
+ people: [
+ {
+ image: '',
+ name: 'John Cole',
+ title: 'Professor and Club Sponsor',
+ links: [
+ {
+ link: '/',
+ image: Website,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ ],
+};
+
+interface StringKeys {
+ [key: string]: {
+ name: string;
+ description: string;
+ people: {
+ image: string | StaticImageData;
+ name: string;
+ title: string;
+ links: {
+ link: string;
+ image: string | StaticImageData;
+ }[];
+ }[];
+ }[];
+}
+
+const data: StringKeys = {
+ '2023-2024': [
+ {
+ name: 'Officers',
+ description:
+ 'As a group of leaders, our officer team works together to guide our organization towards its goals while upholding the principles upon which Nebula Labs was founded. Although each role has distinct responsibilities, they all contribute to ensuring the success and growth of our organization.',
+ people: [
+ {
+ image: '',
+ name: 'Caleb Lim',
+ title: 'President',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: '',
+ name: 'David Launikitis',
+ title: 'Vice President',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: '',
+ name: 'Jake Spann',
+ title: 'Executive Director',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: '',
+ name: 'Shaurya Dwivedi',
+ title: 'Secretary',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: Amrit,
+ name: 'Amrit Rathie',
+ title: 'Treasurer',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'Division Heads',
+ description:
+ 'By overseeing and managing specific areas within Nebula Labs, division heads leverage their expertise to drive the achievement of organization-wide goals. They play a crucial role in orchestrating collaborative efforts, establishing and upholding standards, and cultivating a culture of innovation and development within their respective domains.',
+ people: [
+ {
+ image: '',
+ name: 'Hilary Nguyen',
+ title: 'Head of Design',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: '',
+ name: 'Jason Antwi-Appah',
+ title: 'Head of Engineering',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ vacant('Head of Product'),
+ vacant('Head of Marketing'),
+ ],
+ },
+ {
+ name: 'Project Leads',
+ description:
+ 'Playing a crucial role in shaping every project we work on, project leads orchestrate the transformation of ideas into tangible and functional products. Their coordination skills ensure the successful development of each project, delivering valuable outcomes that positively impact our community.',
+ people: [
+ {
+ image: '',
+ name: 'Stephanie Li',
+ title: 'Planner Lead',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: '',
+ name: 'Ruben Olano',
+ title: 'Jupiter Lead',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: '',
+ name: 'William Skaggs',
+ title: 'Trends and Skedge Lead',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ {
+ image: '',
+ name: 'Josh Pahman',
+ title: 'API and Platform Lead',
+ links: [
+ {
+ link: '/',
+ image: LinkedIn,
+ },
+ {
+ link: '/',
+ image: Email,
+ },
+ ],
+ },
+ ],
+ },
+ clubSponsor,
+ ],
+ '2022-2023': [],
+ '2021-2022': [],
+ '2020-2021': [],
+ '2019-2020': [],
+ '2018-2019': [],
+ '2017-2018': [],
+};
+
+export default data;
diff --git a/src/pages/about/governance.tsx b/src/pages/about/governance.tsx
deleted file mode 100644
index cd4118c..0000000
--- a/src/pages/about/governance.tsx
+++ /dev/null
@@ -1,322 +0,0 @@
-import Header from '@/components/Header';
-import Footer from '@/components/Footer';
-import Image, { StaticImageData } from 'next/image';
-import Link from 'next/image';
-
-import LinkedIn from '@/../public/linkedin-royal.svg';
-import Website from '@/../public/website.svg';
-import Email from '@/../public/email.svg';
-
-import Amrit from '@/../public/governance/amrit.png';
-
-const governance = [
- {
- name: 'Officers',
- description:
- 'As a group of leaders, our officer team works together to guide our organization towards its goals while upholding the principles upon which Nebula Labs was founded. Although each role has distinct responsibilities, they all contribute to ensuring the success and growth of our organization.',
- people: [
- {
- image: '',
- name: 'Caleb Lim',
- title: 'President',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'David Launikitis',
- title: 'Vice President',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'Jake Spann',
- title: 'Executive Director',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'Shaurya Dwivedi',
- title: 'Secretary',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: Amrit,
- name: 'Amrit Rathie',
- title: 'Treasurer',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- ],
- },
- {
- name: 'Division Heads',
- description:
- 'By overseeing and managing specific areas within Nebula Labs, division heads leverage their expertise to drive the achievement of organization-wide goals. They play a crucial role in orchestrating collaborative efforts, establishing and upholding standards, and cultivating a culture of innovation and development within their respective domains.',
- people: [
- {
- image: '',
- name: 'Hilary Nguyen',
- title: 'Head of Design',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'Jason Antwi-Appah',
- title: 'Head of Engineering',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'Vacant',
- title: 'Head of Product',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'Vacant',
- title: 'Head of Marketing',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- ],
- },
- {
- name: 'Project Leads',
- description:
- 'Playing a crucial role in shaping every project we work on, project leads orchestrate the transformation of ideas into tangible and functional products. Their coordination skills ensure the successful development of each project, delivering valuable outcomes that positively impact our community.',
- people: [
- {
- image: '',
- name: 'Stephanie Li',
- title: 'Planner Lead',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'Ruben Olano',
- title: 'Jupiter Lead',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'William Skaggs',
- title: 'Trends and Skedge Lead',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- {
- image: '',
- name: 'Josh Pahman',
- title: 'API and Platform Lead',
- links: [
- {
- link: '/',
- image: LinkedIn,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- ],
- },
- {
- name: 'Our Club Sponsor',
- description:
- 'With more than a decade of teaching and mentoring experience within the community here at The University of Texas at Dallas, John Cole consistently leaves a positive impact on the people around him. Here at Nebula Labs we eagerly look forward to utilizing his invaluable support and knowledge as we grow as an organization.',
- people: [
- {
- image: '',
- name: 'John Cole',
- title: 'Professor and Club Sponsor',
- links: [
- {
- link: '/',
- image: Website,
- },
- {
- link: '/',
- image: Email,
- },
- ],
- },
- ],
- },
-];
-
-interface LeadershipCardProps {
- image: string | StaticImageData;
- name: string;
- title: string;
- links: {
- link: string;
- image: string | StaticImageData;
- }[];
-}
-[];
-
-const LeadershipCard = (props: LeadershipCardProps) => {
- return (
-
- {props.image == '' ? (
-
- ) : (
-
- )}
-
{props.name}
-
{props.title}
-
- {props.links.map((link) => (
-
-
-
- ))}
-
-
- );
-};
-
-interface LeadershipGroupProps {
- name: string;
- description: string;
- people: LeadershipCardProps[];
-}
-[];
-
-const LeadershipGroup = (props: LeadershipGroupProps) => {
- return (
-
-
{props.name}
-
{props.description}
-
- {props.people.map((person) => (
-
- ))}
-
-
- );
-};
-
-const Governance = () => (
-
-
- {governance.map((group) => (
-
- ))}
-
-
-);
-
-export default Governance;
diff --git a/src/pages/about/governance/[period].tsx b/src/pages/about/governance/[period].tsx
new file mode 100644
index 0000000..9ebb928
--- /dev/null
+++ b/src/pages/about/governance/[period].tsx
@@ -0,0 +1,42 @@
+import Header from '@/components/Header';
+import Footer from '@/components/Footer';
+import PeriodLinks from '@/components/PeriodLinks';
+import Image, { StaticImageData } from 'next/image';
+import { useRouter } from 'next/router';
+
+import Governance from '@/components/Governance';
+import data, { current } from '@/data/governance';
+
+const Page = () => {
+ const router = useRouter();
+
+ const periodLinks = {
+ path: router.pathname.replace(/\[.*\]/, ''),
+ periods: Object.keys(data),
+ current: current,
+ };
+
+ if (
+ typeof router.query.period === 'undefined' ||
+ Array.isArray(router.query.period) ||
+ !(router.query.period in data)
+ ) {
+ return (
+
+ );
+ }
+
+ return (
+
+ );
+};
+
+export default Page;
diff --git a/src/pages/about/governance/index.tsx b/src/pages/about/governance/index.tsx
new file mode 100644
index 0000000..1ab6691
--- /dev/null
+++ b/src/pages/about/governance/index.tsx
@@ -0,0 +1,16 @@
+import Governance from '@/components/Governance';
+import data, { current } from '@/data/governance';
+import { useRouter } from 'next/router';
+
+const Page = () => {
+ const router = useRouter();
+
+ return (
+
+ );
+};
+
+export default Page;