Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic goverance #45

Merged
merged 18 commits into from
Apr 27, 2024
Binary file added public/governance/amb150230.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/governance/amrit.png
Binary file not shown.
Binary file added public/governance/axr200071.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/axs200279.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/blank.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/cbm200003.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/cnl210000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/dml190001.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/ecb180001.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/flh220002.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/hxk180000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/jjp210000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/jrs190008.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/jxa220013.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/jxc064000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/npn190002.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/nxw180000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/rdo190000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/rsj180004.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/rxr180000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/rxt220032.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/sxd200087.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/sxl220024.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/sxn180076.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/sxs180000.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/governance/wec190000.jpg
Binary file added public/governance/wgs190000.jpg
94 changes: 46 additions & 48 deletions src/components/Governance.tsx
Original file line number Diff line number Diff line change
@@ -1,90 +1,88 @@
import { useState } from 'react';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
import PeriodLinks from '@/components/PeriodLinks';
import Image, { StaticImageData } from 'next/image';
import { PopulatedGoveranceGroup } from '@/lib/period-populator';
import { Person } from '@/data/person-dictionary';

interface LeadershipCardProps {
image: string | StaticImageData;
name: string;
title: string;
links: {
link: string;
image: string | StaticImageData;
}[];
}
[];
import LinkedIn from '@/../public/linkedin-royal.svg';
import Email from '@/../public/email.svg';

const fallbackSrc = '/governance/blank.jpg';

const LeadershipCard = (props: LeadershipCardProps) => {
const LeadershipCard = (props: Person) => {
const [src, setSrc] = useState(`/governance/${props.netId}.jpg`);
return (
<div className="p-2 flex flex-col items-center grow-0 w-72 gap-4">
{props.image == '' ? (
<div className="bg-cornflower-50 w-full aspect-square rounded-3xl"></div>
) : (
<Image
src={props.image}
alt="Headshot"
height={280}
width={280}
className="w-full aspect-square rounded-3xl"
/>
)}
<Image
src={src}
alt="Headshot"
height={280}
width={280}
className="w-full aspect-square rounded-3xl"
key={props.netId}
onLoadingComplete={(result) => {
if (result.naturalWidth === 0) {
// Broken image
setSrc(fallbackSrc);
}
}}
onError={() => {
setSrc(fallbackSrc);
}}
/>
<h3 className="text-3xl font-bold text-center">{props.name}</h3>
<p className="text-2xl text-center">{props.title}</p>
<p className="text-2xl text-center">{props.role}</p>
<div className="flex gap-4">
{props.links.map((link, index) => (
<a href={link.link} key={index} className="w-8 h-8 relative">
<Image src={link.image} alt="Social link" fill />
</a>
))}
<a href={`mailto:${props.netId}@utdallas.edu`} key={'email'} className="w-8 h-8 relative">
<Image src={Email} alt="Social link" fill />
</a>
<a
href={`https://www.linkedin.com/in/${props.linkedIn}/`}
key={'linkedIn'}
className="w-8 h-8 relative"
>
<Image src={LinkedIn} alt="Social link" fill />
</a>
</div>
</div>
);
};

interface LeadershipGroupProps {
name: string;
description: string;
people: LeadershipCardProps[];
}
[];

const LeadershipGroup = (props: LeadershipGroupProps) => {
const LeadershipGroup = (props: PopulatedGoveranceGroup) => {
return (
<div className="px-8 lg:px-16 xl:px-32 py-24 flex flex-wrap justify-center gap-8">
<h2 className="text-5xl font-bold pb-4 text-center">{props.name}</h2>
<p className="text-3xl pb-4">{props.description}</p>
<div className="flex flex-wrap justify-center gap-16">
{props.people.map((person) => (
<LeadershipCard {...person} key={person.title} />
<LeadershipCard {...person} key={person.role} />
))}
</div>
</div>
);
};

interface GovernanceProps {
data: LeadershipGroupProps[];
past?: string;
period: string;
data: PopulatedGoveranceGroup[];
isCurrent: boolean;
periodLinks: {
path: string;
periods: string[];
current: string;
};
}

const Governance = (props: GovernanceProps) => (
<div className="bg-white">
<Header
text={
'Our Leadership Team' + (typeof props.past === 'undefined' ? '' : ' (' + props.past + ')')
}
/>
<>
<Header text={'Our ' + (props.isCurrent ? '' : props.period + ' ') + 'Leadership Team'} />
{props.data.map((group) => (
<LeadershipGroup {...group} key={group.name} />
))}
<PeriodLinks name="Historical governance periods" past={props.past} {...props.periodLinks} />
<PeriodLinks name="Historical governance periods" {...props.periodLinks} />
<Footer royalBg={false} />
</div>
</>
);

export default Governance;
75 changes: 45 additions & 30 deletions src/components/PeriodLinks.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import Link from 'next/link';
import { Listbox, Transition } from '@headlessui/react';

interface GovernanceProps {
interface PeriodLinkProps {
name: string;
past?: string | null;
path: string;
periods: string[];
current: string;
}

const PeriodLinks = (props: GovernanceProps) => {
const PeriodLinks = (props: PeriodLinkProps) => {
const periods = props.periods;
periods[periods.indexOf(props.current)] = 'Current';

const urls = periods.map((period) => {
if (period === 'Current') {
return props.path;
Expand All @@ -20,30 +17,48 @@ const PeriodLinks = (props: GovernanceProps) => {
});

return (
<div className="px-8 lg:px-16 xl:px-32 py-24 flex flex-wrap justify-center gap-8">
<h2 className="text-5xl font-bold pb-4 text-center">{props.name}</h2>
<div className="flex flex-wrap justify-center gap-x-8">
{periods.map((period, index) => {
if (
period === props.past ||
(period === 'Current' && typeof props.past === 'undefined')
) {
return (
<h3 className="text-xl font-extrabold mb-4" key={period}>
{period}
</h3>
);
}
return (
<Link
href={urls[index]}
className="underline decoration-transparent hover:decoration-inherit transition"
key={period}
>
<h3 className="text-xl font-semibold mb-4">{period}</h3>
</Link>
);
})}
<div className="px-8 lg:px-16 xl:px-32 pt-12 pb-24 flex flex-col items-center">
<div className="w-fit">
<Listbox>
{({ open }) => (
<>
<Listbox.Button
className={
'transition-all duration-300 ease-in-out px-2 py-1 cursor-pointer border-x-2 border-t-2 hover:bg-royal hover:text-white border-royal rounded-t-lg' +
(open ? '' : ' rounded-b-lg border-2')
}
>
{props.name}
</Listbox.Button>
<Transition
className="transition-all duration-500 overflow-hidden"
enterFrom="transform max-h-0"
enterTo="transform opacity-100 max-h-48"
leaveFrom="transform opacity-100 max-h-48"
leaveTo="transform max-h-0"
>
<Listbox.Options className="rounded-b-lg border-2 border-royal max-h-48 overflow-auto">
{periods.map((period, index) => (
<Listbox.Option
key={period}
value={period}
className={
'p-2' + (index === periods.length - 1 ? '' : ' border-b-2 border-royal')
}
>
<Link
className="underline decoration-transparent hover:decoration-inherit transition"
href={urls[index]}
>
<h3 className="text-xl font-semibold">{period}</h3>
</Link>
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</>
)}
</Listbox>
</div>
</div>
);
Expand Down
Loading
Loading