mobile team member card
continuous-integration/drone/push Build is passing Details

This commit is contained in:
b38peng 2021-07-24 15:33:02 -03:00
parent 801a200664
commit d296fe2d7b
12 changed files with 213 additions and 168 deletions

View File

@ -26,3 +26,14 @@
font-weight: 600;
color: var(--purple-2);
}
@media only screen and (max-width: calc(768rem / 16)) {
.img {
width: calc(85rem / 16);
}
.caption {
font-size: calc(10rem / 16);
margin-top: 1rem;
}
}

View File

@ -17,7 +17,7 @@ export const TeamMember: React.FC<TeamMemberProps> = ({
<div className={styles.container}>
<Image
className={styles.img}
src={image ?? "/images/team/team-member-placeholder.svg"}
src={image ?? "/images/team/team-member-placeholder.png"}
alt={`Picture of ${name}`}
/>
<div className={styles.caption}>

View File

@ -38,6 +38,7 @@
grid-area: role;
margin: 0;
color: var(--purple-2);
font-size: calc(24rem / 16);
line-height: calc(40 / 24);
font-weight: 600;
@ -51,38 +52,90 @@
margin-top: 0;
}
/* @media only screen and (max-width: calc(375rem / 16)) {
.card {
grid-template-columns: calc(70rem / 16) auto;
grid-template-rows: auto calc(calc(14rem / 16) * 1.5 + calc(12rem / 16)) auto;
grid-template-areas:
"picture name"
"picture role"
"description description";
column-gap: 1.4375rem;
align-items: end;
/* Popup */
max-width: calc(190rem / 16);
.popup_background {
position: fixed;
background-color: var(--navbar-gray);
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1;
}
.popup_container {
position: fixed;
display: flex;
flex-direction: column;
background-color: var(--off-white);
padding: calc(20rem / 16) calc(40rem / 16);
left: 0;
top: 50%;
transform: translate(0, -50%);
z-index: 2;
}
.close_btn {
align-self: flex-end;
/* reset default button styling */
width: min-content;
background: transparent;
border: 0px solid transparent;
padding: 0;
font-family: inherit;
line-height: inherit;
}
.popup_content {
display: flex;
flex-direction: column;
align-items: center;
}
.popup_image {
width: 100%;
}
.popup_name {
color: var(--blue-2);
margin: calc(24rem / 16) 0 0 0;
font-size: calc(18rem / 16);
font-weight: 600;
}
.popup_role {
color: var(--purple-2);
margin: 0 0 1rem 0;
font-size: calc(18rem / 16);
font-weight: 600;
}
.popup_description {
font-size: calc(14rem / 16);
}
@media only screen and (max-width: calc(768rem / 16)) {
.card {
display: flex;
flex-direction: column;
align-items: center;
max-width: calc(135rem / 16);
margin: 0;
}
.picture {
max-width: calc(70rem / 16);
max-height: calc(70rem / 16);
.name {
margin-top: calc(24rem / 16);
font-weight: 700;
}
.name,
.role,
.description {
line-height: 1.5;
}
.role {
margin-bottom: calc(12rem / 16);
text-align: center;
font-size: calc(14rem / 16);
}
.description {
justify-self: top;
margin-top: calc(12rem / 16);
margin-left: calc(12rem / 16);
display: none;
}
} */
}

View File

@ -1,27 +1,81 @@
import React from "react";
import React, { useState } from "react";
import { Image } from "./Image";
import useWindowDimensions from "../hooks/useWindowDimension";
import styles from "./TeamMemberCard.module.css";
interface TeamMemberCardProps {
export interface TeamMemberCardProps {
name: string;
role: string;
image?: string; // path to image of person, relative to public directory
children: React.ReactNode;
}
export function TeamMemberCard(props: TeamMemberCardProps) {
export function TeamMemberCard({
name,
image,
role,
children,
}: TeamMemberCardProps) {
const { width } = useWindowDimensions();
const [isOpen, setIsOpen] = useState(false);
const handleClick = () => {
if (width <= 768) {
setIsOpen(!isOpen);
}
};
return (
<article className={styles.card}>
<div className={styles.picture}>
<Image
className={styles.image}
src={props.image ?? "/images/team-member-placeholder.svg"}
alt={`Picture of ${props.name}`}
/>
</div>
<h1 className={styles.name}>{props.name}</h1>
<h2 className={styles.role}>{props.role}</h2>
<div className={styles.description}>{props.children}</div>
</article>
<>
<article className={styles.card} onClick={handleClick}>
<div className={styles.picture}>
<Image
className={styles.image}
src={image ?? "/images/team/team-member-placeholder.png"}
alt={`Picture of ${name}`}
/>
</div>
<h1 className={styles.name}>{name}</h1>
<h2 className={styles.role}>{role}</h2>
<div className={styles.description}>{children}</div>
</article>
{isOpen && (
<ExecPopup
name={name}
role={role}
image={image}
handleClick={handleClick}
>
{children}
</ExecPopup>
)}
</>
);
}
interface Propup extends TeamMemberCardProps {
handleClick: () => void;
}
function ExecPopup({ name, image, role, children, handleClick }: Propup) {
return (
<>
<div className={styles.popup_background} onClick={handleClick} />
<div className={styles.popup_container}>
<button className={styles.close_btn} onClick={handleClick}>
<Image src="images/team/popup-close.svg" />
</button>
<div className={styles.popup_content}>
<div className={styles.picture}>
<Image
className={styles.popup_image}
src={image ?? "/images/team/team-member-placeholder.png"}
alt={`Picture of ${name}`}
/>
</div>
<h1 className={styles.popup_name}>{name}</h1>
<h2 className={styles.popup_role}>{role}</h2>
<div className={styles.popup_description}>{children}</div>
</div>
</div>
</>
);
}

View File

@ -1,7 +1,7 @@
---
name: Nakul Vijhani
role: Assistant Vice President
image: /images/team/team-member-placeholder.svg
image:
---
words words words codey words words words words codey words words words words codey words words words words codey words words words words codey words words words words words codey words words words words codey words words words words codey words words words words codey words words words

View File

@ -11,8 +11,7 @@
},
{
"name": "Bill Xiang",
"role": "Member",
"image": "/images/team/team-member-placeholder.png"
"role": "Member"
},
{
"name": "Raymond Li",

View File

@ -11,8 +11,7 @@
},
{
"name": "Amy Wang",
"role": "Developer",
"image": "/images/team/team-member-placeholder.png"
"role": "Developer"
},
{
"name": "Bonnie Peng",

View File

@ -0,0 +1,39 @@
import { useEffect, useState } from "react";
interface WindowDimension {
width: number;
height: number;
}
function getWindowDimension() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
}
function useWindowDimension(): WindowDimension {
const [windowSize, setWindowDimension] = useState<WindowDimension>({
width: 0,
height: 0,
});
useEffect(() => {
const handleResize = () => {
setWindowDimension(getWindowDimension());
};
// Set size at the first client-side load
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return windowSize;
}
export default useWindowDimension;

View File

@ -1,4 +1,4 @@
.headerContainer {
.header_container {
display: flex;
flex-direction: row;
padding-bottom: calc(24rem / 16);
@ -10,7 +10,7 @@
display: none;
}
.headerTextContainer {
.header_text_container {
margin: auto 0 0 0;
}
@ -33,60 +33,7 @@
width: calc(360rem / 16);
}
.execsMobile {
display: none;
}
.reset_button {
/* reset default button styling */
background: transparent;
border: 0px solid transparent;
font-family: inherit;
line-height: inherit;
}
.execButton {
display: flex;
justify-content: center;
}
.popup_background {
position: fixed;
background-color: var(--navbar-gray);
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.popup_container {
position: fixed;
background-color: var(--off-white);
padding: calc(20rem / 16) calc(40rem / 16);
top: 0;
left: 0;
}
.popup_content {
display: flex;
flex-direction: column;
}
.close {
float: right;
}
.exec {
display: flex;
flex-direction: column;
align-items: center;
}
.exec > p {
font-size: calc(14rem / 16);
}
.execsDesktop {
.execs {
display: flex;
flex-direction: column;
gap: calc(26rem / 16);
@ -109,7 +56,7 @@
margin-top: 6rem;
}
.electionSubheading {
.election_subheading {
color: var(--blue-2);
font-size: calc(36rem / 16);
font-weight: 600;
@ -121,7 +68,7 @@
}
@media only screen and (max-width: calc(768rem / 16)) {
.headerContainer {
.header_container {
flex-direction: column-reverse;
padding-bottom: 1rem;
}
@ -151,15 +98,10 @@
padding-bottom: calc(15rem / 16);
}
.execsMobile {
.execs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(calc(130rem / 16), 1fr));
row-gap: calc(24rem / 16);
column-gap: calc(24rem / 16);
}
.execsDesktop {
display: none;
grid-template-columns: repeat(auto-fill, minmax(calc(132rem / 16), 1fr));
justify-items: center;
}
.members {
@ -171,7 +113,7 @@
padding: 2rem;
}
.electionSubheading {
.election_subheading {
font-size: calc(24rem / 16);
}
}

View File

@ -29,8 +29,8 @@ export default function MeetTheTeam({ execs }: Props) {
return (
<MDXProvider components={{}}>
<>
<div className={styles.headerContainer}>
<div className={styles.headerTextContainer}>
<div className={styles.header_container}>
<div className={styles.header_text_container}>
<h1 className={styles.header}>Meet the Team!</h1>
<div className={styles.nav}>
<Link href="#execs">The Executives</Link>
@ -47,7 +47,7 @@ export default function MeetTheTeam({ execs }: Props) {
</div>
<Image src="images/team/team-codey.svg" className={styles.codey} />
</div>
<div className={styles.execsDesktop} id="execs">
<div className={styles.execs} id="execs">
{execs.map((exec) => {
return (
<div key={exec.metadata.name}>
@ -72,7 +72,7 @@ export default function MeetTheTeam({ execs }: Props) {
</div>
<Bubble>
<div className={styles.elections}>
<h2 className={styles.electionSubheading}>Elections</h2>
<h2 className={styles.election_subheading}>Elections</h2>
<ElectionContent />
</div>
</Bubble>
@ -95,58 +95,6 @@ function MembersList(props: MembersProps) {
);
}
// interface MobileExecProps {
// metadata: Metadata;
// content: ComponentType;
// }
// interface Propup extends MobileExecProps {
// handleClose: () => void;
// }
// function MobileExec(props: MobileExecProps) {
// const [isOpen, setIsOpen] = useState(false);
// const togglePopup = () => {
// setIsOpen(!isOpen);
// };
// return (
// <>
// <button
// className={styles.reset_button + " " + styles.execButton}
// onClick={togglePopup}
// >
// <TeamMember {...props.metadata} size="medium" />
// </button>
// {isOpen && (
// <>
// <div className={styles.popup_background} onClick={togglePopup}></div>
// <ExecPopup
// metadata={props.metadata}
// content={props.content}
// handleClose={togglePopup}
// />
// </>
// )}
// </>
// );
// }
// function ExecPopup(props: Propup) {
// return (
// <div className={styles.popup_container}>
// <div className={styles.popup_content}>
// <button className={styles.reset_button} onClick={props.handleClose}>
// <Image src="images/team/popup-close.svg" className={styles.close} />
// </button>
// <div className={styles.exec}>
// <TeamMember {...props.metadata} size="medium" />
// <props.content />
// </div>
// </div>
// </div>
// );
// }
export const getStaticProps: GetStaticProps<Props> = async () => {
const execNames = await getExecNames();
const execs = (await Promise.all(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 173 KiB