diff --git a/gatsby-node.js b/gatsby-node.js index e8fdcea9..568b68d6 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -13,8 +13,8 @@ const html = require('remark-html') const { paginate } = require('gatsby-awesome-pagination') const { postsPerPage } = require('./src/constants/blog.ts') -const MemberTemplate = path.resolve(`./src/templates/Member.tsx`) -const AlumnusTemplate = path.resolve(`./src/templates/Alumnus.tsx`) +const MemberTemplate = path.resolve(`./src/templates/members/Member.tsx`) +const AlumnusTemplate = path.resolve(`./src/templates/members/Alumnus.tsx`) const ProductTemplate = path.resolve(`src/templates/Product.tsx`) const TagTemplate = path.resolve(`./src/templates/Tag.tsx`) const BlogPostTemplate = path.resolve(`./src/templates/BlogPost.tsx`) @@ -109,7 +109,8 @@ exports.createPages = async ({ graphql, actions, reporter }) => { // Retrieve ID's of all team members const { data: { - allMembersJson: { edges }, + allMembersJson: { edges: memberEdges }, + allAlumniJson: { edges: alumniEdges }, }, } = await graphql(` query { @@ -118,44 +119,26 @@ exports.createPages = async ({ graphql, actions, reporter }) => { node { id pennkey + alumnus } } } - } - `) - await edges.map(({ node: { id, pennkey } }) => - createPage({ - path: `/team/${pennkey}`, - component: MemberTemplate, - context: { - // Data passed to context is available in page queries as GraphQL vars - id, - pennkey, - }, - }), - ) - - // Retrieve ID's of all alumni - const { - data: { - allAlumniJson: { edges: alumniEdges }, - }, - } = await graphql(` - query { allAlumniJson { edges { node { id pennkey + alumnus } } } } `) - await alumniEdges.map(({ node: { id, pennkey } }) => + edges = memberEdges.concat(alumniEdges) + await edges.map(({ node: { id, pennkey, alumnus } }) => createPage({ - path: `/alumni/${pennkey}`, - component: AlumnusTemplate, + path: alumnus ? `/alumni/${pennkey}` : `/team/${pennkey}`, + component: alumnus ? AlumnusTemplate : MemberTemplate, context: { // Data passed to context is available in page queries as GraphQL vars id, @@ -164,7 +147,6 @@ exports.createPages = async ({ graphql, actions, reporter }) => { }), ) - /** * Create pages for products */ diff --git a/src/templates/Member.tsx b/src/templates/Member.tsx deleted file mode 100644 index 3d236c91..00000000 --- a/src/templates/Member.tsx +++ /dev/null @@ -1,318 +0,0 @@ -import { graphql } from 'gatsby' -import BackgroundImage from 'gatsby-background-image' -import React from 'react' -import { useState } from 'react' -import styled from 'styled-components' -import remark from 'remark' -import html from 'remark-html' - -import Posts from '../components/Blog/Posts' -import Layout from '../components/Layout' -import SEO from '../components/SEO' -import { DARK_GRAY } from '../constants/colors' -import { - BORDER_RADIUS, - DESKTOP, - M1, - M2, - M3, - M4, - maxWidth, - minWidth, - PHONE, -} from '../constants/measurements' -import { - BookOpenIcon, - CalendarIcon, - Card, - Col, - Fade, - GitHubIcon, - H1, - H3, - HomeIcon, - HR, - LinkedInIcon, - LinkIcon, - LogOutIcon, - MediumContainer, - P, - Row, - Tags, -} from '../shared' -import { IGhostPost, IMember, Subset } from '../types' -import { semesterToString } from '../helpers' - -const markdownProcessor = remark().use(html) - -type ILinks = Subset< - IMember, - { - github?: string - linkedin?: string - website?: string - } -> - -const LinksTag = styled.div<{}>` - a { - color: ${DARK_GRAY} !important; - opacity: 0.5; - margin-right: ${M2}; - transform: scale(0.8); - - svg { - stroke-width: 1.8px; - } - - :hover, - :focus, - :active { - opacity: 0.75; - } - } -` - -const StyledCard = styled(Card) <{}>` - padding: ${M4}; - margin-top: ${M2}; - - ${minWidth(DESKTOP)} { - margin-top: 7.5vh; - } - - ${maxWidth(PHONE)} { - padding: ${M2}; - } -` - -const Links = ({ github, linkedin, website }: ILinks) => ( - - {github && ( - - - - )} - {linkedin && ( - - - - )} - {website && ( - - - - )} - -) - -const ProfilePictureWrapper = styled.div` - border-radius: ${BORDER_RADIUS}; - overflow: hidden; - margin-right: ${M2}; - margin-bottom: 0; - - ${maxWidth(DESKTOP)} { - margin-bottom: ${M3}; - } - - ${maxWidth(PHONE)} { - margin-right: 0; - } - - ${minWidth(DESKTOP)} { - margin-right: ${M4}; - } -` - -const ProfilePicture = styled(BackgroundImage)` - height: 10.4rem; - width: 10.4rem; - background-position: center; - background-repeat: no-repeat; - background-size: cover; - margin-bottom: 0; - - ${maxWidth(PHONE)} { - width: 100%; - height: auto; - padding-top: 100%; - } -` - -interface IMemberTemplateProps { - data: { - membersJson: IMember, - } -} - -const Detail = ({ text, Icon }) => { - if (!text) return null - return ( - - -

- {text} -

- - ) -} - -const Studies = ({ major, school }: { major?: string; school?: string }) => { - const getStudiesText = (): string | null => { - if (!major && !school) return null - if (!major) return `Studies in ${school}` - if (!school) return `Studies ${major}` - return `Studies ${major} in ${school}` - } - - return -} - -const MemberTemplate = ({ data }: IMemberTemplateProps) => { - const { - membersJson: { - bio, - github, - graduation_year: gradYear, - linkedin, - hometown: location, - photo, - localImage, - roles, - name, - major, - school, - team, - website, - semester_joined: semesterJoined, - alumnus, - posts, - } - } = data - - // Bios may contain markdown. Make sure to parse these into HTML! - const [bioAsHtml, updateBioAsHtml] = useState(bio) - markdownProcessor - .process(bio || '') - .then(({ contents: b }) => updateBioAsHtml(b as any)) - - return ( - - - - - - - {localImage?.childImageSharp.fluid && ( - - - - )} - -
-

{name}

-
- -
-

Part of {team}

- -
- -
-
-
- - {bio && ( - -
- - )} - - -
-
- - - - - {location && } - {semesterJoined && ( - - )} - {gradYear && ( - - )} - - - {posts && posts.length > 0 ? ( - <> - -
-
- -

Posts

-
- - !p.frontmatter.draft)} /> - - - ) : null} - - - ) -} - -export const pageQuery = graphql` - query($pennkey: String!) { - membersJson(pennkey: { eq: $pennkey }) { - bio - github - graduation_year - linkedin - hometown - photo - roles - name - major - school - team - website - semester_joined - alumnus - posts { - excerpt - frontmatter { - title - slug - customExcerpt - draft - coverPhoto { - childImageSharp { - fluid(maxWidth: 484) { - ...GatsbyImageSharpFluid - } - } - } - } - } - } - } -` - -export default MemberTemplate diff --git a/src/templates/members/Alumnus.tsx b/src/templates/members/Alumnus.tsx new file mode 100644 index 00000000..0878655c --- /dev/null +++ b/src/templates/members/Alumnus.tsx @@ -0,0 +1,29 @@ +import { graphql } from 'gatsby' +import { GenericMemberTemplate, IAlumniTemplateProps } from './utils' + +const AlumniTemplate = ({ data }: IAlumniTemplateProps) => { + return GenericMemberTemplate({ data }) +} + +export const pageQuery = graphql` + query($pennkey: String!) { + alumniJson(pennkey: { eq: $pennkey }) { + bio + github + graduation_year + linkedin + hometown + photo + roles + name + major + school + team + website + semester_joined + alumnus + } + } +` + +export default AlumniTemplate diff --git a/src/templates/members/Member.tsx b/src/templates/members/Member.tsx new file mode 100644 index 00000000..0ae2a072 --- /dev/null +++ b/src/templates/members/Member.tsx @@ -0,0 +1,45 @@ +import { graphql } from 'gatsby' +import { GenericMemberTemplate, IMemberTemplateProps } from './utils' + +const MemberTemplate = ({ data }: IMemberTemplateProps) => { + return GenericMemberTemplate({ data }) +} + +export const pageQuery = graphql` + query($pennkey: String!) { + membersJson(pennkey: { eq: $pennkey }) { + bio + github + graduation_year + linkedin + hometown + photo + roles + name + major + school + team + website + semester_joined + alumnus + posts { + excerpt + frontmatter { + title + slug + customExcerpt + draft + coverPhoto { + childImageSharp { + fluid(maxWidth: 484) { + ...GatsbyImageSharpFluid + } + } + } + } + } + } + } +` + +export default MemberTemplate diff --git a/src/templates/Alumnus.tsx b/src/templates/members/utils.tsx similarity index 82% rename from src/templates/Alumnus.tsx rename to src/templates/members/utils.tsx index 3396ec4a..3cd343f3 100644 --- a/src/templates/Alumnus.tsx +++ b/src/templates/members/utils.tsx @@ -6,10 +6,10 @@ import styled from 'styled-components' import remark from 'remark' import html from 'remark-html' -import Posts from '../components/Blog/Posts' -import Layout from '../components/Layout' -import SEO from '../components/SEO' -import { DARK_GRAY } from '../constants/colors' +import Posts from '../../components/Blog/Posts' +import Layout from '../../components/Layout' +import SEO from '../../components/SEO' +import { DARK_GRAY } from '../../constants/colors' import { BORDER_RADIUS, DESKTOP, @@ -20,7 +20,7 @@ import { maxWidth, minWidth, PHONE, -} from '../constants/measurements' +} from '../../constants/measurements' import { BookOpenIcon, CalendarIcon, @@ -39,9 +39,9 @@ import { P, Row, Tags, -} from '../shared' -import { IGhostPost, IMember, Subset } from '../types' -import { semesterToString } from '../helpers' +} from '../../shared' +import { IGhostPost, IMember, Subset } from '../../types' +import { semesterToString } from '../../helpers' const markdownProcessor = remark().use(html) @@ -140,12 +140,6 @@ const ProfilePicture = styled(BackgroundImage)` } ` -interface IMemberTemplateProps { - data: { - alumniJson: IMember, - } -} - const Detail = ({ text, Icon }) => { if (!text) return null return ( @@ -177,9 +171,27 @@ const Studies = ({ major, school }: { major?: string; school?: string }) => { return } -const MemberTemplate = ({ data }: IMemberTemplateProps) => { - const { - alumniJson: { + +export interface IMemberTemplateProps { + data: { + membersJson: IMember, + } +} + +export interface IAlumniTemplateProps { + data: { + alumniJson: IMember, + } +} + +export type IGenericMemberTemplateProps = IMemberTemplateProps | IAlumniTemplateProps + +export const GenericMemberTemplate = ({ data }: IGenericMemberTemplateProps) => { + // if data is alumniJson, then we are rendering an alumni page + const isAlumni = 'alumniJson' in data + + const + { bio, github, graduation_year: gradYear, @@ -196,8 +208,7 @@ const MemberTemplate = ({ data }: IMemberTemplateProps) => { semester_joined: semesterJoined, alumnus, posts, - } - } = data + } = isAlumni ? data.alumniJson : data.membersJson // Bios may contain markdown. Make sure to parse these into HTML! const [bioAsHtml, updateBioAsHtml] = useState(bio) @@ -237,7 +248,7 @@ const MemberTemplate = ({ data }: IMemberTemplateProps) => { {bio && ( -
+
)} @@ -256,7 +267,13 @@ const MemberTemplate = ({ data }: IMemberTemplateProps) => { /> )} {gradYear && ( - + )} @@ -269,7 +286,7 @@ const MemberTemplate = ({ data }: IMemberTemplateProps) => {

Posts

- !p.frontmatter.draft)} /> + !p.frontmatter.draft)} /> ) : null} @@ -277,26 +294,3 @@ const MemberTemplate = ({ data }: IMemberTemplateProps) => { ) } - -export const pageQuery = graphql` - query($pennkey: String!) { - alumniJson(pennkey: { eq: $pennkey }) { - bio - github - graduation_year - linkedin - hometown - photo - roles - name - major - school - team - website - semester_joined - alumnus - } - } -` - -export default MemberTemplate