diff --git a/src/App.css b/src/App.css index fe6f59d..24c034a 100644 --- a/src/App.css +++ b/src/App.css @@ -16,6 +16,7 @@ --secondary-grey: #222222f2; --toggle-green: #4dd6a8; --toggle-blue: #61c3d4; + --toggle-earthGreen: #a4c639; --title-size: clamp(1.4rem, calc(15vw + 1rem), 8rem); --chonky-header-size: 4.75rem; --thicc-subheading-size: 2.5rem; diff --git a/src/components/PreviousExecTeam/PreviousExecTeam.styles.ts b/src/components/PreviousExecTeam/PreviousExecTeam.styles.ts new file mode 100644 index 0000000..815cde7 --- /dev/null +++ b/src/components/PreviousExecTeam/PreviousExecTeam.styles.ts @@ -0,0 +1,107 @@ +import styled from "styled-components"; + +export const PrevTeamSection = styled.div` + margin-left: auto; + margin-right: auto; + padding-bottom: 2rem; + text-align: center; + background-color: white; + +`; + +export const SectionHeader = styled.div` + padding: 2rem 0; + font-size: 2.5rem; + color: black; + font-weight: 900; + text-align: center; + font-family: Inter, Tahoma, sans-serif; + line-height: 1; +`; + +export const PaginationControl = styled.div` + display: flex; + /* border: 1px red solid; */ + margin-left: auto; + margin-right: auto; + justify-content: center; +`; + +export const ArrowButton = styled.button` + background-color: white; + border: none; + border-radius: 50%; + color: #333; + font-size: 1.5rem; + padding: 0.5rem 1rem; + cursor: pointer; + transition: background-color 0.3s; + + &:hover { + background-color: #e0e0e0; + } + + &:disabled { + cursor: not-allowed; + } +`; + +export const YearButton = styled.div` + background-color: transparent; + border: 1px lightgray solid; + border-radius: 10px; + color: #333; + font-size: 1.2rem; + padding: 0.5rem 2rem; + margin: 0 0.3rem; + transition: color 0.3s; +`; + +export const Carousel = styled.div` + width: 40%; + margin: 3rem auto; + @media(max-width: 768px) { + width: 80%; + } +`; + +export const TeamList = styled.div` + max-width: 85%; + margin: 0 auto; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 2rem; + + @media (max-width: 768px) { + grid-template-columns: 1fr 1fr; + } + @media (max-width: 600px) { + grid-template-columns: 1fr; + } +`; + +export const TeamMember = styled.div` + background-color: #f5f5f5; + border-radius: 0.5rem; + padding: 1rem 0rem; +`; + +export const TeamHeader = styled.a` + font-size: 20px; + font-weight: bold; + margin: 0 0 10px 0; + text-decoration: none; + color: inherit; + transition: color 0.3s, text-decoration 0.3; + &:hover { + color: #4dd6a8; + text-decoration: underline; + } +`; + +export const TeamRole = styled.p` + font-size: 16px; + margin: 0 0 5px 0; + +`; +export const YearPagination = styled.div``; diff --git a/src/components/PreviousExecTeam/PreviousExecTeam.tsx b/src/components/PreviousExecTeam/PreviousExecTeam.tsx new file mode 100644 index 0000000..6f658f5 --- /dev/null +++ b/src/components/PreviousExecTeam/PreviousExecTeam.tsx @@ -0,0 +1,195 @@ +import React, { useEffect, useState } from "react"; +import * as S from "./PreviousExecTeam.styles"; +import { prevExecTeamList, PrevExecTeam } from "./PreviousExecTeamsInfo"; +// https://react-slick.neostack.com/docs/example/ +import Divider from "components/Divider"; +import { + faChevronLeft, + faChevronRight, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +const PAGINATION_VISIBLE_YEARS = 1; + +// interface of the prop +interface PreviousExecTeamProps { + desktopView: boolean; +} +const PreviousExecTeam = ({ desktopView }: PreviousExecTeamProps) => { + const [selectedYear, setSelectedYear] = useState( + prevExecTeamList[prevExecTeamList.length - 1].year + ); + const [visibleYears, setVisibleYears] = useState([]); + + useEffect(() => { + updateVisibleYears(); + }, [desktopView]); // only run on inital render or when view changes + + // Function to set the visible years + function updateVisibleYears() { + const selectedYearIndex = getSelectedYearIndex(); + + // Calculate startIndex based on the selectedYearIndex + let startIndex = Math.max( + 0, + prevExecTeamList.length - PAGINATION_VISIBLE_YEARS + ); + // If the selected year is near the beginning, adjust startIndex to show available years + if (selectedYearIndex < startIndex) { + startIndex = Math.max( + 0, + selectedYearIndex - Math.floor(PAGINATION_VISIBLE_YEARS / 2) + ); + } + + // Calculate endIndex based on startIndex + const endIndex = Math.min( + prevExecTeamList.length, + startIndex + PAGINATION_VISIBLE_YEARS + ); + + setVisibleYears(prevExecTeamList.slice(startIndex, endIndex)); + } + + const getSelectedYearIndex = (): number => + prevExecTeamList.findIndex((data) => data.year === selectedYear); + + const handleLeftArrow = () => { + const selectedYearIndex = getSelectedYearIndex(); + if (selectedYearIndex > 0) { + setSelectedYear(prevExecTeamList[selectedYearIndex - 1].year); + + // Recalculate visible years only if necessary + const currentStartIndex = prevExecTeamList.findIndex( + (data) => data.year === visibleYears[0].year + ); + + // if the selectedyear index less that the start of the visible year array + if (selectedYearIndex - 1 < currentStartIndex) { + // Only shift the visible years by 1 year to the left so we don't introduce any unnecssary years + const newStartIndex = Math.max(0, currentStartIndex - 1); + const newEndIndex = Math.min( + prevExecTeamList.length, + newStartIndex + PAGINATION_VISIBLE_YEARS + ); + setVisibleYears(prevExecTeamList.slice(newStartIndex, newEndIndex)); + } + } + }; + const handleRightArrow = () => { + const selectedYearIndex = getSelectedYearIndex(); + if (selectedYearIndex < prevExecTeamList.length - 1) { + setSelectedYear(prevExecTeamList[selectedYearIndex + 1].year); + + // Recalculate visible years only if necessary + const currentStartIndex = prevExecTeamList.findIndex( + (data) => data.year === visibleYears[0].year + ); + + // If the selected year moves beyond the currently visible years + if ( + selectedYearIndex + 1 >= + currentStartIndex + PAGINATION_VISIBLE_YEARS + ) { + // Shift the visible years by one to the right + const newStartIndex = Math.min( + prevExecTeamList.length - PAGINATION_VISIBLE_YEARS, + currentStartIndex + 1 + ); + const newEndIndex = Math.min( + prevExecTeamList.length, + newStartIndex + PAGINATION_VISIBLE_YEARS + ); + setVisibleYears(prevExecTeamList.slice(newStartIndex, newEndIndex)); + } + } + }; + + return ( + + + Previous Executives + + + + + + {visibleYears.map((data) => ( + {data.year} + ))} + + + + + + + {prevExecTeamList + .filter((team) => team.year === selectedYear) + .map((team: PrevExecTeam) => { + return ( + <> + + {team.picture ? ( + + ) : ( +

No picture available

+ )} +
+ + {team.members.length > 0 && ( + <> + {team.members.map((member, index) => ( + +
+ + {member.name} + + {member.role} +
+
+ ))} + + )} +
+ + ); + })} +
+ ); +}; + +export default React.memo(PreviousExecTeam); diff --git a/src/components/PreviousExecTeam/PreviousExecTeamsInfo.ts b/src/components/PreviousExecTeam/PreviousExecTeamsInfo.ts new file mode 100644 index 0000000..baf4ea3 --- /dev/null +++ b/src/components/PreviousExecTeam/PreviousExecTeamsInfo.ts @@ -0,0 +1,273 @@ +import exec2023 from "../../images/previousTeam/exec_23.png"; +import exec2022 from "../../images/previousTeam/exec_22.png"; +import exec2021 from "../../images/previousTeam/exec_21.png"; + +export type PrevExecTeam = { + year : string; + picture: string; + members: {name: string, role: string, linkedin_url: string}[]; +}; + +export const prevExecTeamList : PrevExecTeam[] =[ + { + "year": "2021-2022", + "picture": exec2021, + "members": [ + { + "name": "Joel Happ", + "role": "Co-President", + "linkedin_url": "https://www.linkedin.com/in/joel-happ/" + }, + { + "name": "Naureen Othi", + "role": "Co-President", + "linkedin_url": "https://www.linkedin.com/mwlite/in/naureen-othi" + }, + + { + "name": "Fedor Prokopchuk", + "role": "VP Strategy", + "linkedin_url": "https://www.linkedin.com/in/fedor-prokopchuk-707668a6/" + }, + { + "name": "Luke Hollinda", + "role": "VP External", + "linkedin_url": "https://www.linkedin.com/in/luke-hollinda-89270a183/?originalSubdomain=ca" + }, + { + "name": "Amanda Nguyen", + "role": "VP Community", + "linkedin_url": "https://www.linkedin.com/in/amanda-nguyen-b9146620b/" + }, + { + "name": "Tyler Chan", + "role": "VP Communications", + "linkedin_url": "https://www.linkedin.com/in/chan-tyler/" + }, + { + "name": "Sareen Singh", + "role": "VP Events", + "linkedin_url": "https://www.linkedin.com/in/sareen-singh-309b55173/?originalSubdomain=ca" + }, + { + "name": "Nurgul Akhshatayeva", + "role": "VP Internal", + "linkedin_url": "https://www.linkedin.com/in/nurgul-akhshatayeva-6821b0205/" + }, + { + "name": "Godwin Saure", + "role": "VP Finance", + "linkedin_url": "https://www.linkedin.com/in/godwin-saure/" + }, + { + "name": "Terry Fu", + "role": "VP Development", + "linkedin_url": "https://www.linkedin.com/in/terryfu33/" + }, + { + "name": "Vidhi Soni", + "role": "Jr VP External", + "linkedin_url": "https://www.linkedin.com/in/vidhi-soni-5ba193196/" + } + ] + }, + { + "year": "2022-2023", + "picture": exec2022, + "members": [ + { + "name": "Niyousha Raeesinejad", + "role": "Co-President", + "linkedin_url": "https://www.linkedin.com/in/niyoushar/" + }, + { + "name": "Rajpreet Gill", + "role": "Co-President", + "linkedin_url": "https://www.linkedin.com/in/rajpreet-gill/" + }, + + { + "name": "Fedor Prokopchuk", + "role": "VP Strategy", + "linkedin_url": "https://www.linkedin.com/in/fedor-prokopchuk-707668a6/" + }, + + { + "name": "Noel Thomas", + "role": "VP Events", + "linkedin_url": "https://www.linkedin.com/in/noelfranthomas/" + }, + { + "name": "Ben Shi", + "role": "Jr VP Events", + "linkedin_url": "https://www.linkedin.com/in/ben-shi-228651189" + }, + + { + "name": "Carol Wang", + "role": "VP Internal", + "linkedin_url": "https://www.linkedin.com/in/carol-wang3116/" + }, + { + "name": "Tyler Chan", + "role": "VP Communications", + "linkedin_url": "https://www.linkedin.com/in/chan-tyler/" + }, + { + "name": "Sahiti Akella", + "role": "Jr VP Communications", + "linkedin_url": "https://www.linkedin.com/in/sahiti-akella/" + }, + + { + "name": "Estefy Caballero", + "role": "Media Commissioner", + "linkedin_url": "https://www.linkedin.com/in/estefy-caballero-864aab25a" + }, + { + "name": "Kevin Amado", + "role": "VP Development", + "linkedin_url": "https://www.linkedin.com/in/kamadorueda/" + }, + + { + "name": "Rachel Renegado", + "role": "Senior Software Advisor", + "linkedin_url": "https://www.linkedin.com/in/rachel-renegado-544409201" + }, + + { + "name": "Mya Gill", + "role": "VP Community", + "linkedin_url": "https://www.linkedin.com/in/mya-gill-71a8451b8/" + }, + { + "name": "Labib Afshar Ahmed", + "role": "VP Finance", + "linkedin_url": "https://www.linkedin.com/in/labib-afsar-ahmed/" + }, + { + "name": "Nathan Karbonik", + "role": "VP External", + "linkedin_url": "https://www.linkedin.com/in/nathan-karbonik/" + }, + { + "name": "Sareen Singh", + "role": "Advisor", + "linkedin_url": "https://www.linkedin.com/in/sareen-singh-309b55173/?originalSubdomain=ca" + } + ] + }, + { + "year": "2023-2024", + "picture": exec2023, + "members": [ + { + "name": "Niyousha Raeesinejad", + "role": "Co-President", + "linkedin_url": "https://www.linkedin.com/in/niyoushar/" + }, + { + "name": "Tyler Chan", + "role": "Co-President", + "linkedin_url": "https://www.linkedin.com/in/chan-tyler/" + }, + { + "name": "Labib Afshar Ahmed", + "role": "President Elect / VP Finance", + "linkedin_url": "https://www.linkedin.com/in/labib-afsar-ahmed/" + }, + { + "name": "Nathan Karbonik", + "role": "External Advisor", + "linkedin_url": "https://www.linkedin.com/in/nathan-karbonik/" + }, + { + "name": "Ana Laura Espinosa Garza", + "role": "VP External", + "linkedin_url": "https://www.linkedin.com/in/ana-laura-espinosa-garza-136a281b0/" + }, + { + "name": "Cindy Cheng", + "role": "Jr. VP External", + "linkedin_url": "https://www.linkedin.com/in/cindy-cheng-66328a2b8/" + }, + { + "name": "Carol Wang", + "role": "VP Community", + "linkedin_url": "https://www.linkedin.com/in/carol-wang3116/" + }, + { + "name": "Estefy Caballero", + "role": "Co-VP Communications", + "linkedin_url": "https://www.linkedin.com/in/estefy-caballero-864aab25a" + }, + { + "name": "Enioluwafe Balogun", + "role": "Co-VP Communications", + "linkedin_url": "https://www.linkedin.com/in/enioluwafe-balogun/" + }, + { + "name": "Leo Wei", + "role": "Co-VP Events", + "linkedin_url": "https://www.linkedin.com/in/leo-wei/" + }, + { + "name": "Maheen Raza", + "role": "Co-VP Events", + "linkedin_url": "https://www.linkedin.com/in/maheen-raza-40b780229/" + }, + { + "name": "Azlfa Anwar", + "role": "Jr. VP Events", + "linkedin_url": "https://www.linkedin.com/in/azlfa-anwar-20a040218/" + }, + { + "name": "Janita Mahum", + "role": "VP Design", + "linkedin_url": "https://www.linkedin.com/in/janita-mahum-a5484a1b9/" + }, + { + "name": "Ben Schmidt", + "role": "VP Development", + "linkedin_url": "https://www.linkedin.com/in/benschmidt2343/" + }, + { + "name": "Abod Abbas", + "role": "Senior Technical Advisor", + "linkedin_url": "https://www.linkedin.com/in/abod-a-427274198/" + }, + { + "name": "Wai Ka Wong", + "role": "Technical Advisor", + "linkedin_url": "https://www.linkedin.com/in/waika-wong/" + }, + + { + "name": "Sajwal Pageni", + "role": "VP Strategy", + "linkedin_url": "https://www.linkedin.com/in/sajwal/" + }, + { + "name": "Fedor Prokopchuk", + "role": "Business Strategy Advisor", + "linkedin_url": "https://www.linkedin.com/in/fedor-prokopchuk-707668a6/" + }, + { + "name": "Brian Nguyen", + "role": "Senior Web Developer", + "linkedin_url": "https://www.linkedin.com/in/nguyennbrian/" + }, + { + "name": "Sahiti Akella", + "role": "Web Developer", + "linkedin_url": "https://www.linkedin.com/in/sahiti-akella/" + }, + { + "name": "Isaiah Asaolu", + "role": "Web Developer", + "linkedin_url": "https://www.linkedin.com/in/isaiah-a-2001/" + } + ] + } +] diff --git a/src/components/TeamSection/Profile.tsx b/src/components/TeamSection/Profile.tsx index 36718c0..4cb045d 100644 --- a/src/components/TeamSection/Profile.tsx +++ b/src/components/TeamSection/Profile.tsx @@ -6,7 +6,6 @@ import SocialMedia from "components/SocialMedia/SocialMedia"; import { SocialMediaColor } from "../../utility/SharedStyles"; import { faLinkedinIn } from "@fortawesome/free-brands-svg-icons"; - // props for team profile type ProfileProps = { key: number; @@ -19,16 +18,16 @@ type ProfileProps = { const getBackgroundColor = (category: string): SocialMediaColor => { switch (category) { - case 'executives': + case "executives": return SocialMediaColor.ToggleGreen; - case 'projectManagers': + case "projectManagers": return SocialMediaColor.ToggleBlue; - case 'alumni': - return SocialMediaColor.ToggleYellow; + case "alumni": + return SocialMediaColor.ToggleEarthGreen; default: return SocialMediaColor.ToggleBlue; } -} +}; const Profile = (props: ProfileProps) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -58,7 +57,9 @@ const Profile = (props: ProfileProps) => { )} {props.member.linkedin && ( - + { case "projectManagers": return { backgroundColor: "var(--lightwash-green)", left: "calc(33.3% + 5px)" }; case "alumni": - return { backgroundColor: "var(--secondary-lime)", left: "calc(66.6% + 5px)" }; + return { backgroundColor: "var(--toggle-earthGreen)", left: "calc(66.6% + 5px)" }; default: return { backgroundColor: "var(--primary-green)", left: "5px" }; // Default to executives } @@ -42,16 +42,16 @@ export const ToggleButtonWrapper = styled.div` align-items: center; `; -export const SliderWrapper = styled.div<{ selectedCategory: TeamCategory}>` +export const SliderWrapper = styled.div<{ selectedCategory: TeamCategory }>` position: relative; display: flex; justify-content: space-between; width: 700px; - height: 60px; + height: 40px; background-color: ${({ selectedCategory }) => - selectedCategory === "executives" ? "var(--primary-green)" : - selectedCategory === "projectManagers" ? "var(--lightwash-green)" : - "var(--secondary-lime)"}; + selectedCategory === "executives" ? "var(--primary-green)" : + selectedCategory === "projectManagers" ? "var(--lightwash-green)" : + "var(--toggle-earthGreen)"}; border-radius: 50px; padding: 5px; `; @@ -65,12 +65,13 @@ export const SliderOption = styled.div` cursor: pointer; padding: 10px 5px; font-weight: 500; - font-size: 1.5em; + font-size: var(--regular-font); + font-family: "Inter", Tahoma, sans-serif; color: #fff; z-index: 2; @media (max-width: 700px) { - font-size: 1.2em; + font-size: var(--regular-font); } `; diff --git a/src/images/previousTeam/exec_21.png b/src/images/previousTeam/exec_21.png new file mode 100644 index 0000000..8aff81a Binary files /dev/null and b/src/images/previousTeam/exec_21.png differ diff --git a/src/images/previousTeam/exec_22.png b/src/images/previousTeam/exec_22.png new file mode 100644 index 0000000..b0c5908 Binary files /dev/null and b/src/images/previousTeam/exec_22.png differ diff --git a/src/images/previousTeam/exec_23.png b/src/images/previousTeam/exec_23.png new file mode 100644 index 0000000..56de7d0 Binary files /dev/null and b/src/images/previousTeam/exec_23.png differ diff --git a/src/pages/TeamPage.tsx b/src/pages/TeamPage.tsx index 52d90f1..a75f2e3 100644 --- a/src/pages/TeamPage.tsx +++ b/src/pages/TeamPage.tsx @@ -10,7 +10,7 @@ import Team from "components/TeamSection/Team"; import { boardMembers } from "components/TeamSection/TeamInformation"; import useViewport from "components/UseViewport"; import Divider from "components/Divider"; - +import PreviousExecTeam from "components/PreviousExecTeam/PreviousExecTeam"; const TeamPage = () => { // set defaultView flag according to screen width cutoff value @@ -70,10 +70,11 @@ const TeamPage = () => { + ); }; diff --git a/src/utility/SharedStyles.tsx b/src/utility/SharedStyles.tsx index 18d1b63..7bbcfc4 100644 --- a/src/utility/SharedStyles.tsx +++ b/src/utility/SharedStyles.tsx @@ -7,7 +7,7 @@ export enum SocialMediaColor { Black = "Black", ToggleGreen = "ToggleGreen", ToggleBlue = "ToggleBlue", - ToggleYellow = "ToggleYellow", + ToggleEarthGreen = "ToggleEarthGreen", White = "White", } @@ -27,8 +27,8 @@ export const handleColor = (color: SocialMediaColor) => { return "var(--toggle-green)"; case SocialMediaColor.ToggleBlue: return "var(--toggle-blue)"; - case SocialMediaColor.ToggleYellow: - return "var(--secondary-lime)" + case SocialMediaColor.ToggleEarthGreen: + return "var(--toggle-earthGreen)" case SocialMediaColor.White: return "white"; default: